# Path: paco/assertions.py
# def isiter(x):
#     """
#     Returns `True` if the given value implements an valid iterable
#     interface.
# 
#     Arguments:
#         x (mixed): value to check if it is an iterable.
# 
#     Returns:
#         bool
#     """
#     return hasattr(x, '__iter__') and not isinstance(x, (str, bytes))
# 
# Path: paco/reduce.py
# @overload
# @asyncio.coroutine
# def reduce(coro, iterable, initializer=None, limit=1, right=False, loop=None):
#     """
#     Apply function of two arguments cumulatively to the items of sequence,
#     from left to right, so as to reduce the sequence to a single value.
# 
#     Reduction will be executed sequentially without concurrency,
#     so passed values would be in order.
# 
#     This function is the asynchronous coroutine equivalent to Python standard
#     `functools.reduce()` function.
# 
#     This function is a coroutine.
# 
#     This function can be composed in a pipeline chain with ``|`` operator.
# 
#     Arguments:
#         coro (coroutine function): reducer coroutine binary function.
#         iterable (iterable|asynchronousiterable): an iterable collection
#             yielding coroutines functions.
#         initializer (mixed): initial accumulator value used in
#             the first reduction call.
#         limit (int): max iteration concurrency limit. Use ``0`` for no limit.
#         right (bool): reduce iterable from right to left.
#         loop (asyncio.BaseEventLoop): optional event loop to use.
# 
#     Raises:
#         TypeError: if input arguments are not valid.
# 
#     Returns:
#         mixed: accumulated final reduced value.
# 
#     Usage::
# 
#         async def reducer(acc, num):
#            return acc + num
# 
#         await paco.reduce(reducer, [1, 2, 3, 4, 5], initializer=0)
#         # => 15
# 
#     """
#     assert_corofunction(coro=coro)
#     assert_iter(iterable=iterable)
# 
#     # Reduced accumulator value
#     acc = initializer
# 
#     # If interable is empty, just return the initializer value
#     if len(iterable) == 0:
#         return initializer
# 
#     # Create concurrent executor
#     pool = ConcurrentExecutor(limit=limit, loop=loop)
# 
#     # Reducer partial function for deferred coroutine execution
#     def reducer(element):
#         @asyncio.coroutine
#         def wrapper():
#             nonlocal acc
#             acc = yield from coro(acc, element)
#         return wrapper
# 
#     # Support right reduction
#     if right:
#         iterable.reverse()
# 
#     # Iterate and attach coroutine for defer scheduling
#     for element in iterable:
#         pool.add(reducer(element))
# 
#     # Wait until all coroutines finish
#     yield from pool.run(ignore_empty=True)
# 
#     # Returns final reduced value
#     return acc
# 
# Path: paco/decorator.py
# def generator_consumer(coro):  # pragma: no cover
#     def wrapper(*args, **kw):
# def decorate(fn):
#     def decorator(*args, **kw):
#         def wrapper(coro, *_args, **_kw):
# 
# Path: paco/assertions.py
# def assert_corofunction(**kw):
#     """
#     Asserts if a given values are a coroutine function.
# 
#     Arguments:
#         **kw (mixed): value to check if it is an iterable.
# 
#     Raises:
#         TypeError: if assertion fails.
#     """
#     for name, value in kw.items():
#         if not asyncio.iscoroutinefunction(value):
#             raise TypeError(
#                 'paco: {} must be a coroutine function'.format(name))
# 
# def assert_iter(**kw):
#     """
#     Asserts if a given values implements a valid iterable interface.
# 
#     Arguments:
#         **kw (mixed): value to check if it is an iterable.
# 
#     Raises:
#         TypeError: if assertion fails.
#     """
#     for name, value in kw.items():
#         if not isiter(value):
#             raise TypeError(
#                 'paco: {} must be an iterable object'.format(name))


import asyncio
from .assertions import isiter
from .reduce import reduce
from .decorator import overload
from .assertions import assert_corofunction, assert_iter
        *args (mixed): optional variadic arguments to pass to the
            coroutine iterable function.

    Returns:
        results (list): ordered list of values yielded by coroutines

    Raises:
        TypeError: in case of invalid input arguments.

    Usage::

        async def mul_2(num):
            return num * 2

        await paco.flat_map(mul_2, [1, [2], [3, [4]], [(5,)]])
        # => [2, 4, 6, 8, 10]

        # Pipeline style
        await [1, [2], [3, [4]], [(5,)]] | paco.flat_map(mul_2)
        # => [2, 4, 6, 8, 10]

    """
    assert_corofunction(coro=coro)
    assert_iter(iterable=iterable)

    # By default do not collect yielded values from coroutines
    results = initializer if isiter(initializer) else []

    @asyncio.coroutine
    def reducer(buf, value):

# Path: paco/assertions.py
# def isiter(x):
#     """
#     Returns `True` if the given value implements an valid iterable
#     interface.
# 
#     Arguments:
#         x (mixed): value to check if it is an iterable.
# 
#     Returns:
#         bool
#     """
#     return hasattr(x, '__iter__') and not isinstance(x, (str, bytes))
# 
# Path: paco/reduce.py
# @overload
# @asyncio.coroutine
# def reduce(coro, iterable, initializer=None, limit=1, right=False, loop=None):
#     """
#     Apply function of two arguments cumulatively to the items of sequence,
#     from left to right, so as to reduce the sequence to a single value.
# 
#     Reduction will be executed sequentially without concurrency,
#     so passed values would be in order.
# 
#     This function is the asynchronous coroutine equivalent to Python standard
#     `functools.reduce()` function.
# 
#     This function is a coroutine.
# 
#     This function can be composed in a pipeline chain with ``|`` operator.
# 
#     Arguments:
#         coro (coroutine function): reducer coroutine binary function.
#         iterable (iterable|asynchronousiterable): an iterable collection
#             yielding coroutines functions.
#         initializer (mixed): initial accumulator value used in
#             the first reduction call.
#         limit (int): max iteration concurrency limit. Use ``0`` for no limit.
#         right (bool): reduce iterable from right to left.
#         loop (asyncio.BaseEventLoop): optional event loop to use.
# 
#     Raises:
#         TypeError: if input arguments are not valid.
# 
#     Returns:
#         mixed: accumulated final reduced value.
# 
#     Usage::
# 
#         async def reducer(acc, num):
#            return acc + num
# 
#         await paco.reduce(reducer, [1, 2, 3, 4, 5], initializer=0)
#         # => 15
# 
#     """
#     assert_corofunction(coro=coro)
#     assert_iter(iterable=iterable)
# 
#     # Reduced accumulator value
#     acc = initializer
# 
#     # If interable is empty, just return the initializer value
#     if len(iterable) == 0:
#         return initializer
# 
#     # Create concurrent executor
#     pool = ConcurrentExecutor(limit=limit, loop=loop)
# 
#     # Reducer partial function for deferred coroutine execution
#     def reducer(element):
#         @asyncio.coroutine
#         def wrapper():
#             nonlocal acc
#             acc = yield from coro(acc, element)
#         return wrapper
# 
#     # Support right reduction
#     if right:
#         iterable.reverse()
# 
#     # Iterate and attach coroutine for defer scheduling
#     for element in iterable:
#         pool.add(reducer(element))
# 
#     # Wait until all coroutines finish
#     yield from pool.run(ignore_empty=True)
# 
#     # Returns final reduced value
#     return acc
# 
# Path: paco/decorator.py
# def generator_consumer(coro):  # pragma: no cover
#     def wrapper(*args, **kw):
# def decorate(fn):
#     def decorator(*args, **kw):
#         def wrapper(coro, *_args, **_kw):
# 
# Path: paco/assertions.py
# def assert_corofunction(**kw):
#     """
#     Asserts if a given values are a coroutine function.
# 
#     Arguments:
#         **kw (mixed): value to check if it is an iterable.
# 
#     Raises:
#         TypeError: if assertion fails.
#     """
#     for name, value in kw.items():
#         if not asyncio.iscoroutinefunction(value):
#             raise TypeError(
#                 'paco: {} must be a coroutine function'.format(name))
# 
# def assert_iter(**kw):
#     """
#     Asserts if a given values implements a valid iterable interface.
# 
#     Arguments:
#         **kw (mixed): value to check if it is an iterable.
# 
#     Raises:
#         TypeError: if assertion fails.
#     """
#     for name, value in kw.items():
#         if not isiter(value):
#             raise TypeError(
#                 'paco: {} must be an iterable object'.format(name))


# Path: paco/flat_map.py
import asyncio
from .assertions import isiter
from .reduce import reduce
from .decorator import overload
from .assertions import assert_corofunction, assert_iter

        *args (mixed): optional variadic arguments to pass to the
            coroutine iterable function.

    Returns:
        results (list): ordered list of values yielded by coroutines

    Raises:
        TypeError: in case of invalid input arguments.

    Usage::

        async def mul_2(num):
            return num * 2

        await paco.flat_map(mul_2, [1, [2], [3, [4]], [(5,)]])
        # => [2, 4, 6, 8, 10]

        # Pipeline style
        await [1, [2], [3, [4]], [(5,)]] | paco.flat_map(mul_2)
        # => [2, 4, 6, 8, 10]

    """
    assert_corofunction(coro=coro)
    assert_iter(iterable=iterable)

    # By default do not collect yielded values from coroutines
    results = initializer if isiter(initializer) else []

    @asyncio.coroutine
    def reducer(buf, value):

        if isiter(value):