
    Dfo                        d Z ddlZddlZddlmZ ddlmZ ddlmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZ ddlmZ g d	Z e            Z	  e d
            ee d
          Z!n# e"$ r e Z!Y nw xY w e#edd           Z$d Z%dHdZ&d Z'dIdZ(dIdZ)dIdZ*e+fdZ,d Z-e-Z.d Z/d Z0d Z1dIdZ2d Z3	 ddl
m4Z5 d Z4e3j         e4_         n# e6$ r e3Z4Y nw xY w G d de7          Z8d Z9d  Z:dJd"Z;d# Z<d$ Z=d% Z>dId&Z?dId'Z@dKd)ZAdId*ZBdLd+ZCd,d-d.ZDdId/ZEd0 ZFd1 ZGd2 ZHd3 ZId4 ZJd5 ZKd6 ZLd7 ZMd8 ZNd9 ZOdMd:ZPd; ZQd(dd<ZRed=k    rdd>l
mSZT d(dd?ZSneRZSeRj         eS_         d@ ZUdA ZVdB ZWdC ZXdD ZYdE ZZdF Z[dG Z\dS )Na  Imported from the recipes section of the itertools documentation.

All functions taken from the recipes section of the itertools library docs
[1]_.
Some backward-compatible usability improvements have been made.

.. [1] http://docs.python.org/library/itertools.html#recipes

    N)deque)Sized)partialreduce)chaincombinationscompresscountcyclegroupbyisliceproductrepeatstarmapteezip_longest)	randrangesamplechoice)
hexversion).	all_equalbatchedbefore_and_afterconsumeconvolve
dotproduct
first_truefactorflattengrouperiter_except
iter_indexmatmulncyclesnthnth_combinationpadnonepad_nonepairwise	partitionpolynomial_evalpolynomial_from_rootspolynomial_derivativepowersetprependquantifyreshape#random_combination_with_replacementrandom_combinationrandom_permutationrandom_product
repeatfunc
roundrobinsievesliding_window	subslicessum_of_squarestabulatetailtaketotient	transpose
triplewiseuniqueunique_everseenunique_justseenTstrictsumprodc                 "    t          | |          S N)r   )xys     E/var/www/media/lib/python3.11/site-packages/more_itertools/recipes.py<lambda>rM   _   s    Aq1A1A     c                 <    t          t          ||                     S )zReturn first *n* items of the iterable as a list.

        >>> take(3, range(10))
        [0, 1, 2]

    If there are fewer than *n* items in the iterable, all of them are
    returned.

        >>> take(10, range(3))
        [0, 1, 2]

    )listr   niterables     rL   r>   r>   b   s     x##$$$rN   c                 <    t          | t          |                    S )a  Return an iterator over the results of ``func(start)``,
    ``func(start + 1)``, ``func(start + 2)``...

    *func* should be a function that accepts one integer argument.

    If *start* is not specified it defaults to 0. It will be incremented each
    time the iterator is advanced.

        >>> square = lambda x: x ** 2
        >>> iterator = tabulate(square, -3)
        >>> take(4, iterator)
        [9, 4, 1, 0]

    )mapr
   )functionstarts     rL   r<   r<   r   s     xu&&&rN   c           	   #      K   t          |t                    r7t          |t          dt	          |          | z
            d          E d{V  dS t          t          ||                     E d{V  dS )zReturn an iterator over the last *n* items of *iterable*.

    >>> t = tail(3, 'ABCDEFG')
    >>> list(t)
    ['E', 'F', 'G']

    r   Nmaxlen)
isinstancer   r   maxleniterr   rQ   s     rL   r=   r=      s       (E"" 3(C3x==1+<$=$=tDDDDDDDDDDDhq11122222222222rN   c                 n    |t          | d           dS t          t          | ||          d           dS )aX  Advance *iterable* by *n* steps. If *n* is ``None``, consume it
    entirely.

    Efficiently exhausts an iterator without returning values. Defaults to
    consuming the whole iterator, but an optional second argument may be
    provided to limit consumption.

        >>> i = (x for x in range(10))
        >>> next(i)
        0
        >>> consume(i, 3)
        >>> next(i)
        4
        >>> consume(i)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    If the iterator has fewer items remaining than the provided limit, the
    whole iterator will be consumed.

        >>> i = (x for x in range(3))
        >>> consume(i, 5)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    Nr   rY   )r   nextr   )iteratorrR   s     rL   r   r      sG    @ 	yhq!!!!!! 	VHa##T*****rN   c                 @    t          t          | |d          |          S )zReturns the nth item or a default value.

    >>> l = range(10)
    >>> nth(l, 3)
    3
    >>> nth(l, 20, "zebra")
    'zebra'

    N)r`   r   )rS   rR   defaults      rL   r%   r%      s      xD))7333rN   c           
      z    t          t          t          t          | |          d                              dk    S )a  
    Returns ``True`` if all the elements are equal to each other.

        >>> all_equal('aaaa')
        True
        >>> all_equal('aaab')
        False

    A function that accepts a single argument and returns a transformed version
    of each input item can be specified with *key*:

        >>> all_equal('AaaA', key=str.casefold)
        True
        >>> all_equal([1, 2, 3], key=lambda x: x < 10)
        True

          )r]   rP   r   r   rS   keys     rL   r   r      s3    $ tF78S1115566771<<rN   c                 <    t          t          ||                     S )zcReturn the how many times the predicate is true.

    >>> quantify([True, False, True])
    2

    )sumrU   )rS   preds     rL   r0   r0      s     s4""###rN   c                 <    t          | t          d                    S )a   Returns the sequence of elements and then returns ``None`` indefinitely.

        >>> take(5, pad_none(range(3)))
        [0, 1, 2, None, None]

    Useful for emulating the behavior of the built-in :func:`map` function.

    See also :func:`padded`.

    N)r   r   rS   s    rL   r(   r(      s     6$<<(((rN   c                 `    t          j        t          t          |           |                    S )zvReturns the sequence elements *n* times

    >>> list(ncycles(["a", "b"], 3))
    ['a', 'b', 'a', 'b', 'a', 'b']

    )r   from_iterabler   tuple)rS   rR   s     rL   r$   r$      s%     veHooq99:::rN   c                 R    t          t          t          j        | |                    S )zcReturns the dot product of the two iterables.

    >>> dotproduct([10, 10], [20, 20])
    400

    )rj   rU   operatormul)vec1vec2s     rL   r   r     s      s8<t,,---rN   c                 *    t          j        |           S )zReturn an iterator flattening one level of nesting in a list of lists.

        >>> list(flatten([[0, 1], [2, 3]]))
        [0, 1, 2, 3]

    See also :func:`collapse`, which can flatten multiple levels of nesting.

    )r   ro   )listOfListss    rL   r   r     s     {+++rN   c                 |    |t          | t          |                    S t          | t          ||                    S )aG  Call *func* with *args* repeatedly, returning an iterable over the
    results.

    If *times* is specified, the iterable will terminate after that many
    repetitions:

        >>> from operator import add
        >>> times = 4
        >>> args = 3, 5
        >>> list(repeatfunc(add, times, *args))
        [8, 8, 8, 8]

    If *times* is ``None`` the iterable will not terminate:

        >>> from random import randrange
        >>> times = None
        >>> args = 1, 11
        >>> take(6, repeatfunc(randrange, times, *args))  # doctest:+SKIP
        [2, 4, 8, 1, 8, 4]

    )r   r   )functimesargss      rL   r6   r6     s9    , }tVD\\***4e,,---rN   c                 f    t          |           \  }}t          |d           t          ||          S )zReturns an iterator of paired items, overlapping, from the original

    >>> take(4, pairwise(count()))
    [(0, 1), (1, 2), (2, 3), (3, 4)]

    On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`.

    N)r   r`   zip)rS   abs      rL   	_pairwiser   6  s.     x==DAqDMMMq!99rN   r)   c                      t          |           S rI   )itertools_pairwiserm   s    rL   r)   r)   J  s    !(+++rN   c                         e Zd Zd fd	Z xZS )UnequalIterablesErrorNc                 l    d}|| dj         | z  }t                                          |           d S )Nz Iterables have different lengthsz/: index 0 has length {}; index {} has length {})formatsuper__init__)selfdetailsmsg	__class__s      rL   r   zUnequalIterablesError.__init__Q  sI    0MEM C 	rN   rI   )__name__
__module____qualname__r   __classcell__)r   s   @rL   r   r   P  s=                 rN   r   c              #   r   K   t          | dt          iD ]"}|D ]}|t          u rt                      |V  #d S )N	fillvalue)r   _markerr   )	iterablescombovals      rL   _zip_equal_generatorr   [  s`      i;7;;   	. 	.Cg~~+--- 	 rN   c                  
   	 t          | d                   }t          | dd          d          D ]-\  }}t          |          }||k    rt          |||f          .t          |  S # t          $ r t          |           cY S w xY w)Nr   rf   )r   )r]   	enumerater   r}   	TypeErrorr   )r   
first_sizeiitsizes        rL   
_zip_equalr   c  s    /1&&
y}a00 	K 	KEArr77Dz!!+ZD4IJJJJ " I  / / /#I...../s   A#A& &BBfillc                     t          |           g|z  }|dk    rt          |d|iS |dk    r	t          | S |dk    r	t          | S t	          d          )a  Group elements from *iterable* into fixed-length groups of length *n*.

    >>> list(grouper('ABCDEF', 3))
    [('A', 'B', 'C'), ('D', 'E', 'F')]

    The keyword arguments *incomplete* and *fillvalue* control what happens for
    iterables whose length is not a multiple of *n*.

    When *incomplete* is `'fill'`, the last group will contain instances of
    *fillvalue*.

    >>> list(grouper('ABCDEFG', 3, incomplete='fill', fillvalue='x'))
    [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]

    When *incomplete* is `'ignore'`, the last group will not be emitted.

    >>> list(grouper('ABCDEFG', 3, incomplete='ignore', fillvalue='x'))
    [('A', 'B', 'C'), ('D', 'E', 'F')]

    When *incomplete* is `'strict'`, a subclass of `ValueError` will be raised.

    >>> it = grouper('ABCDEFG', 3, incomplete='strict')
    >>> list(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    UnequalIterablesError

    r   r   rF   ignorez Expected fill, strict, or ignore)r^   r   r   r}   
ValueError)rS   rR   
incompleter   r{   s        rL   r    r    s  so    : NNaDVD6I666X4  XDz;<<<rN   c               '      K   t          t          |           }t          t          |           dd          D ]:}t	          t          ||                    }t          t          |          E d{V  ;dS )aJ  Yields an item from each iterable, alternating between them.

        >>> list(roundrobin('ABC', 'D', 'EF'))
        ['A', 'D', 'E', 'B', 'F', 'C']

    This function produces the same output as :func:`interleave_longest`, but
    may perform better for some inputs (in particular when the number of
    iterables is small).

    r   N)rU   r^   ranger]   r   r   r`   )r   	iterators
num_actives      rL   r7   r7     s~       D)$$IC	NNAr22 ( (
&J7788	tY''''''''''( (rN   c                     | t           } t          |d          \  }}}t          t          | |                    \  }}t          |t          t          j        |                    t          ||          fS )a  
    Returns a 2-tuple of iterables derived from the input iterable.
    The first yields the items that have ``pred(item) == False``.
    The second yields the items that have ``pred(item) == True``.

        >>> is_odd = lambda x: x % 2 != 0
        >>> iterable = range(10)
        >>> even_items, odd_items = partition(is_odd, iterable)
        >>> list(even_items), list(odd_items)
        ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])

    If *pred* is None, :func:`bool` is used.

        >>> iterable = [0, 1, False, True, '', ' ']
        >>> false_items, true_items = partition(None, iterable)
        >>> list(false_items), list(true_items)
        ([0, False, ''], [1, True, ' '])

    N   )boolr   rU   r	   rr   not_)rk   rS   t1t2pp1p2s          rL   r*   r*     sg    ( |Ha  IBAT1FBRX]B//00(2r2B2BCCrN   c                     t          |           t          j        fdt          t	                    dz             D                       S )a1  Yields all possible subsets of the iterable.

        >>> list(powerset([1, 2, 3]))
        [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

    :func:`powerset` will operate on iterables that aren't :class:`set`
    instances, so repeated elements in the input will produce repeated elements
    in the output.

        >>> seq = [1, 1, 0]
        >>> list(powerset(seq))
        [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)]

    For a variant that efficiently yields actual :class:`set` instances, see
    :func:`powerset_of_sets`.
    c              3   8   K   | ]}t          |          V  d S rI   )r   ).0rss     rL   	<genexpr>zpowerset.<locals>.<genexpr>  s-      MMa|Aq11MMMMMMrN   rf   )rP   r   ro   r   r]   )rS   r   s    @rL   r.   r.     sH    " 	XAMMMM5Q!;L;LMMMMMMrN   c              #      K   t                      }|j        }g }|j        }|du}| D ]H}|r ||          n|}	 ||vr ||           |V  &# t          $ r ||vr ||           |V  Y Ew xY wdS )a  
    Yield unique elements, preserving order.

        >>> list(unique_everseen('AAAABBBCCDAABBB'))
        ['A', 'B', 'C', 'D']
        >>> list(unique_everseen('ABBCcAD', str.lower))
        ['A', 'B', 'C', 'D']

    Sequences with a mix of hashable and unhashable items can be used.
    The function will be slower (i.e., `O(n^2)`) for unhashable items.

    Remember that ``list`` objects are unhashable - you can use the *key*
    parameter to transform the list to a tuple (which is hashable) to
    avoid a slowdown.

        >>> iterable = ([1, 2], [2, 3], [1, 2])
        >>> list(unique_everseen(iterable))  # Slow
        [[1, 2], [2, 3]]
        >>> list(unique_everseen(iterable, key=tuple))  # Faster
        [[1, 2], [2, 3]]

    Similarly, you may want to convert unhashable ``set`` objects with
    ``key=frozenset``. For ``dict`` objects,
    ``key=lambda x: frozenset(x.items())`` can be used.

    N)setaddappendr   )	rS   rh   seensetseenset_addseenlistseenlist_adduse_keyelementks	            rL   rC   rC     s      6 eeG+KH?LoG 	 	#0CCLLL	A 	 	 	  Q		 	s   AA-,A-c           
          |/t          t          j        d          t          |                     S t          t          t          t          j        d          t          | |                              S )zYields elements in order, ignoring serial duplicates

    >>> list(unique_justseen('AAAABBBCCDAABBB'))
    ['A', 'B', 'C', 'D', 'A', 'B']
    >>> list(unique_justseen('ABBCcAD', str.lower))
    ['A', 'B', 'C', 'A', 'D']

    Nr   rf   )rU   rr   
itemgetterr   r`   rg   s     rL   rD   rD     s[     {8&q))78+<+<===tS,Q//31G1GHHIIIrN   Fc                 D    t          t          | ||          |          S )a  Yields unique elements in sorted order.

    >>> list(unique([[1, 2], [3, 4], [1, 2]]))
    [[1, 2], [3, 4]]

    *key* and *reverse* are passed to :func:`sorted`.

    >>> list(unique('ABBcCAD', str.casefold))
    ['A', 'B', 'c', 'D']
    >>> list(unique('ABBcCAD', str.casefold, reverse=True))
    ['D', 'c', 'B', 'A']

    The elements in *iterable* need not be hashable, but they must be
    comparable for sorting to work.
    )rh   reverse)rh   )rD   sorted)rS   rh   r   s      rL   rB   rB     s&      6(WEEE3OOOOrN   c              #   X   K   	 | |            V  	  |             V  # |$ r Y dS w xY w)a  Yields results from a function repeatedly until an exception is raised.

    Converts a call-until-exception interface to an iterator interface.
    Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel
    to end the loop.

        >>> l = [0, 1, 2]
        >>> list(iter_except(l.pop, IndexError))
        [2, 1, 0]

    Multiple exceptions can be specified as a stopping condition:

        >>> l = [1, 2, 3, '...', 4, 5, 6]
        >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError)))
        [7, 6, 5]
        >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError)))
        [4, 3, 2]
        >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError)))
        []

    N )ry   	exceptionfirsts      rL   r!   r!   -  s[      ,%''MMM	$&&LLL	   s     ))c                 >    t          t          ||           |          S )a  
    Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item for which
    ``pred(item) == True`` .

        >>> first_true(range(10))
        1
        >>> first_true(range(10), pred=lambda x: x > 5)
        6
        >>> first_true(range(10), default='missing', pred=lambda x: x > 9)
        'missing'

    )r`   filter)rS   rc   rk   s      rL   r   r   L  s    " tX&&000rN   rf   )r   c                 R    d |D             | z  }t          d |D                       S )a  Draw an item at random from each of the input iterables.

        >>> random_product('abc', range(4), 'XYZ')  # doctest:+SKIP
        ('c', 3, 'Z')

    If *repeat* is provided as a keyword argument, that many items will be
    drawn from each iterable.

        >>> random_product('abcd', range(4), repeat=2)  # doctest:+SKIP
        ('a', 2, 'd', 3)

    This equivalent to taking a random selection from
    ``itertools.product(*args, **kwarg)``.

    c                 ,    g | ]}t          |          S r   rp   r   pools     rL   
<listcomp>z"random_product.<locals>.<listcomp>p  s    ***TU4[[***rN   c              3   4   K   | ]}t          |          V  d S rI   )r   r   s     rL   r   z!random_product.<locals>.<genexpr>q  s(      00$000000rN   r   )r   r{   poolss      rL   r5   r5   `  s9      +*T***V3E00%000000rN   c                     t          |           }|t          |          n|}t          t          ||                    S )ab  Return a random *r* length permutation of the elements in *iterable*.

    If *r* is not specified or is ``None``, then *r* defaults to the length of
    *iterable*.

        >>> random_permutation(range(5))  # doctest:+SKIP
        (3, 4, 0, 1, 2)

    This equivalent to taking a random selection from
    ``itertools.permutations(iterable, r)``.

    )rp   r]   r   )rS   r   r   s      rL   r4   r4   t  s8     ??DYD			AAa!!!rN   c                     t          |           t                    }t          t          t	          |          |                    }t          fd|D                       S )zReturn a random *r* length subsequence of the elements in *iterable*.

        >>> random_combination(range(5), 3)  # doctest:+SKIP
        (2, 3, 4)

    This equivalent to taking a random selection from
    ``itertools.combinations(iterable, r)``.

    c              3   (   K   | ]}|         V  d S rI   r   r   r   r   s     rL   r   z%random_combination.<locals>.<genexpr>  '      **Qa******rN   )rp   r]   r   r   r   )rS   r   rR   indicesr   s       @rL   r3   r3     s[     ??DD		AVE!HHa(())G****'******rN   c                     t          |           t                    t          fdt          |          D                       }t          fd|D                       S )aS  Return a random *r* length subsequence of elements in *iterable*,
    allowing individual elements to be repeated.

        >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP
        (0, 0, 1, 2, 2)

    This equivalent to taking a random selection from
    ``itertools.combinations_with_replacement(iterable, r)``.

    c              3   6   K   | ]}t                    V  d S rI   )r   )r   r   rR   s     rL   r   z6random_combination_with_replacement.<locals>.<genexpr>  s)      44aYq\\444444rN   c              3   (   K   | ]}|         V  d S rI   r   r   s     rL   r   z6random_combination_with_replacement.<locals>.<genexpr>  r   rN   )rp   r]   r   r   )rS   r   r   rR   r   s      @@rL   r2   r2     sg     ??DD		A444458844444G****'******rN   c                    t          |           }t          |          }|dk     s||k    rt          d}t          |||z
            }t	          d|dz             D ]}|||z
  |z   z  |z  }|dk     r||z  }|dk     s||k    rt
          g }|rS||z  |z  |dz
  |dz
  }}}||k    r||z  }|||z
  z  |z  |dz
  }}||k    |                    |d|z
                      |St          |          S )a  Equivalent to ``list(combinations(iterable, r))[index]``.

    The subsequences of *iterable* that are of length *r* can be ordered
    lexicographically. :func:`nth_combination` computes the subsequence at
    sort position *index* directly, without computing the previous
    subsequences.

        >>> nth_combination(range(5), 3, 5)
        (0, 3, 4)

    ``ValueError`` will be raised If *r* is negative or greater than the length
    of *iterable*.
    ``IndexError`` will be raised if the given *index* is invalid.
    r   rf   r   )rp   r]   r   minr   
IndexErrorr   )	rS   r   indexr   rR   cr   r   results	            rL   r&   r&     s8    ??DD		A	A1q55	AAq1uA1a!e__ ! !QOq qyy
		uzzF
 $a%1*a!eQUa1qjjQJEA;!#QUqA qjj 	d26l###  $ ==rN   c                 $    t          | g|          S )a  Yield *value*, followed by the elements in *iterator*.

        >>> value = '0'
        >>> iterator = ['1', '2', '3']
        >>> list(prepend(value, iterator))
        ['0', '1', '2', '3']

    To prepend multiple values, see :func:`itertools.chain`
    or :func:`value_chain`.

    )r   )valuera   s     rL   r/   r/     s     %(###rN   c              #     K   t          |          ddd         }t          |          }t          dg|          |z  }t          | t	          d|dz
                      D ])}|                    |           t          ||          V  *dS )aB  Convolve the iterable *signal* with the iterable *kernel*.

        >>> signal = (1, 2, 3, 4, 5)
        >>> kernel = [3, 2, 1]
        >>> list(convolve(signal, kernel))
        [3, 8, 14, 20, 26, 14, 5]

    Note: the input arguments are not interchangeable, as the *kernel*
    is immediately consumed and stored.

    Nr   r   rY   rf   )rp   r]   r   r   r   r   _sumprod)signalkernelrR   windowrJ   s        rL   r   r     s       6]]44R4 FFAA3q!!!A%F66!QU++,, ' 'avv&&&&&&' 'rN   c                 p     t                    g  fd}t                    } |            |fS )a  A variant of :func:`takewhile` that allows complete access to the
    remainder of the iterator.

         >>> it = iter('ABCdEfGhI')
         >>> all_upper, remainder = before_and_after(str.isupper, it)
         >>> ''.join(all_upper)
         'ABC'
         >>> ''.join(remainder) # takewhile() would lose the 'd'
         'dEfGhI'

    Note that the first iterator must be fully consumed before the second
    iterator can generate valid results.
    c               3   d   K   D ])}  |           r| V                       |             d S d S rI   )r   )elemr   	predicate
transitions    rL   true_iteratorz'before_and_after.<locals>.true_iterator  sV       	 	Dy 



!!$'''	 	rN   )r^   r   )r   r   r   remainder_iteratorr   s   ``  @rL   r   r     s^     
bBJ       z2..=??...rN   c              #   h   K   t          t          |                     D ]\  \  }}\  }}|||fV  dS )zReturn overlapping triplets from *iterable*.

    >>> list(triplewise('ABCDE'))
    [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E')]

    Nr   )rS   r~   _r   r   s        rL   rA   rA     sN       #8H#5#566  AAAg rN   c              #      K   t          |           }t          t          ||dz
            |          }|D ](}|                    |           t	          |          V  )dS )aY  Return a sliding window of width *n* over *iterable*.

        >>> list(sliding_window(range(6), 4))
        [(0, 1, 2, 3), (1, 2, 3, 4), (2, 3, 4, 5)]

    If *iterable* has fewer than *n* items, then nothing is yielded:

        >>> list(sliding_window(range(3), 4))
        []

    For a variant with more features, see :func:`windowed`.
    rf   rY   N)r^   r   r   r   rp   )rS   rR   r   r   rJ   s        rL   r9   r9   "  ss       
hB6"a!e$$Q///F  aFmm rN   c           
          t          |           }t          t          t          t	          t          |          dz             d                    }t          t          j        t          |          |          S )zReturn all contiguous non-empty subslices of *iterable*.

        >>> list(subslices('ABC'))
        [['A'], ['A', 'B'], ['A', 'B', 'C'], ['B'], ['B', 'C'], ['C']]

    This is similar to :func:`substrings`, but emits items in a different
    order.
    rf   re   )
rP   r   slicer   r   r]   rU   rr   getitemr   )rS   seqslicess      rL   r:   r:   6  sU     x..CULs3xx!|)<)<a@@AAFxf555rN   c                     t          t          d          t          t          j        |                     }t          t          t          |dg                    S )zCompute a polynomial's coefficients from its roots.

    >>> roots = [5, -4, 3]  # (x - 5) * (x + 4) * (x - 3)
    >>> polynomial_from_roots(roots)  # x^3 - 4 * x^2 - 17 * x + 60
    [1, -4, -17, 60]
    rf   )r}   r   rU   rr   negrP   r   r   )rootsfactorss     rL   r,   r,   D  sA     &))Su5566Gx1#..///rN   c              #     K   t          | dd          }|7t          | ||          }t          ||          D ]\  }}||u s||k    r|V  dS |t          |           n|}|dz
  }	 	  |||dz   |          x}V  # t          $ r Y dS w xY w)a  Yield the index of each place in *iterable* that *value* occurs,
    beginning with index *start* and ending before index *stop*.


    >>> list(iter_index('AABCADEAF', 'A'))
    [0, 1, 4, 7]
    >>> list(iter_index('AABCADEAF', 'A', 1))  # start index is inclusive
    [1, 4, 7]
    >>> list(iter_index('AABCADEAF', 'A', 1, 7))  # stop index is not inclusive
    [1, 4]

    The behavior for non-scalar *values* matches the built-in Python types.

    >>> list(iter_index('ABCDABCD', 'AB'))
    [0, 4]
    >>> list(iter_index([0, 1, 2, 3, 0, 1, 2, 3], [0, 1]))
    []
    >>> list(iter_index([[0, 1], [2, 3], [0, 1], [2, 3]], [0, 1]))
    [0, 2]

    See :func:`locate` for a more general means of finding the indexes
    associated with particular values.

    r   Nrf   )getattrr   r   r]   r   )rS   r   rW   stop	seq_indexr   r   r   s           rL   r"   r"   O  s      2 '400IHeT**#B.. 	 	JAw%7e#3#3	 	
 !%s8}}}$AI	;%IeQUD999q:::; 	 	 	DD	s   &A< <
B
	B
c              #     K   | dk    rdV  d}t          d          | dz  z  }t          j        |           dz   }t          |d||          D ]_}t          |d|||z            E d{V  t	          t          t          ||z  | ||z                                 |||z  | ||z   <   ||z  }`t          |d|          E d{V  dS )zdYield the primes less than n.

    >>> list(sieve(30))
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
    re   r   )r   rf   rf   N)	bytearraymathisqrtr"   bytesr]   r   )rR   rW   datalimitr   s        rL   r8   r8   z  s       	1uuEVQ'DJqMMAEa..  dAua!e444444444"'E!a%AE,B,B(C(C"D"DQUQQA$5)))))))))))rN   c             #   "  K   |dk     rt          d          t          |           }t          t          ||                    x}rI|r"t	          |          |k    rt          d          |V  t          t          ||                    x}GdS dS )a  Batch data into tuples of length *n*. If the number of items in
    *iterable* is not divisible by *n*:
    * The last batch will be shorter if *strict* is ``False``.
    * :exc:`ValueError` will be raised if *strict* is ``True``.

    >>> list(batched('ABCDEFG', 3))
    [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]

    On Python 3.13 and above, this is an alias for :func:`itertools.batched`.
    rf   zn must be at least onezbatched(): incomplete batchN)r   r^   rp   r   r]   )rS   rR   rF   r   batchs        rL   _batchedr    s       	1uu1222	hBA''
'%  	<c%jjAoo:;;; A''
'%     rN   i )r   c                &    t          | ||          S )NrE   )itertools_batched)rS   rR   rF   s      rL   r   r     s     1V<<<<rN   c                     t          |  S )a  Swap the rows and columns of the input matrix.

    >>> list(transpose([(1, 2, 3), (11, 22, 33)]))
    [(1, 11), (2, 22), (3, 33)]

    The caller should ensure that the dimensions of the input are compatible.
    If the input is empty, no output will be produced.
    )_zip_strictr   s    rL   r@   r@     s     rN   c                 F    t          t          j        |           |          S )zReshape the 2-D input *matrix* to have a column count given by *cols*.

    >>> matrix = [(0, 1), (2, 3), (4, 5)]
    >>> cols = 3
    >>> list(reshape(matrix, cols))
    [(0, 1, 2), (3, 4, 5)]
    )r   r   ro   )matrixcolss     rL   r1   r1     s     5&v..555rN   c                     t          |d                   }t          t          t          t	          | t          |                              |          S )zMultiply two matrices.

    >>> list(matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]))
    [(49, 80), (41, 60)]

    The caller should ensure that the dimensions of the input matrices are
    compatible with each other.
    r   )r]   r   r   r   r   r@   )m1m2rR   s      rL   r#   r#     s=     	BqE

A78WR2%?%?@@!DDDrN   c              #      K   t          t          j        |           dz             D ]}| |z  s|V  | |z  } | dk    r dS | |z  | dk    r| V  dS dS )zTYield the prime factors of n.

    >>> list(factor(360))
    [2, 2, 2, 3, 3, 5]
    rf   N)r8   r  r  )rR   primes     rL   r   r     s       tz!}}q())  e) 	KKK%KAAvv	 e) 	
 	1uu urN   c           	          t          |           }|dk    r|dz  S t          t          t          |          t	          t          |                              }t          | |          S )zEvaluate a polynomial at a specific value.

    Example: evaluating x^3 - 4 * x^2 - 17 * x + 60 at x = 2.5:

    >>> coefficients = [1, -4, -17, 60]
    >>> x = 2.5
    >>> polynomial_eval(coefficients, x)
    8.125
    r   )r]   rU   powr   reversedr   r   )coefficientsrJ   rR   powerss       rL   r+   r+     sX     	LAAvv1ufQii%((!3!344FL&)))rN   c                 .    t          t          |            S )zfReturn the sum of the squares of the input values.

    >>> sum_of_squares([10, 20, 30])
    1400
    )r   r   r  s    rL   r;   r;     s     SWWrN   c                     t          |           }t          t          d|                    }t          t	          t
          j        | |                    S )a  Compute the first derivative of a polynomial.

    Example: evaluating the derivative of x^3 - 4 * x^2 - 17 * x + 60

    >>> coefficients = [1, -4, -17, 60]
    >>> derivative_coefficients = polynomial_derivative(coefficients)
    >>> derivative_coefficients
    [3, -8, -17]
    rf   )r]   r  r   rP   rU   rr   rs   )r  rR   r   s      rL   r-   r-     sB     	LAeAqkk""FHL,77888rN   c                 Z    t          t          |                     D ]}| |z  |dz
  z  } | S )zReturn the count of natural numbers up to *n* that are coprime with *n*.

    >>> totient(9)
    6
    >>> totient(12)
    4
    rf   )r   r   )rR   r   s     rL   r?   r?   	  s8     ^^  Fa!eHrN   )r   rI   )r   N)NF)NN)r   N)]__doc__r  rr   collectionsr   collections.abcr   	functoolsr   r   	itertoolsr   r   r	   r
   r   r   r   r   r   r   r   r   randomr   r   r   sysr   __all__objectr   r}   r  r   r  r   r>   r<   r=   r   r%   r   r   r0   r(   r'   r$   r   r   r6   r   r)   r   ImportErrorr   r   r   r   r    r7   r*   r.   rC   rD   rB   r!   r   r5   r4   r3   r2   r&   r/   r   r   rA   r9   r:   r,   r"   r8   r  r   r  r@   r1   r#   r   r+   r;   r-   r?   r   rN   rL   <module>r.     s            ! ! ! ! ! ! % % % % % % % %                            - , , , , , , , , ,      / / /b &((,Ct '#d+++KK    KKK 74$A$ABB% % % ' ' ' '$3 3 3$%+ %+ %+ %+P
4 
4 
4 
4= = = =* ! $ $ $ $) ) ) ; ; ;. . .	, 	, 	,. . . .6  	)888888
, , , !(H    HHH    J     / / / %= %= %= %=P( ( ($D D D8N N N** * * *ZJ J J JP P P P&   >1 1 1 1( "# 1 1 1 1 1(" " " "$+ + + + + +"' ' 'T$ $ $' ' ',/ / /B    (6 6 60 0 0( ( ( (V* * *$ %*     ( 666666', = = = = = = G&GO	 	 	6 6 6
E 
E 
E   * * *"  9 9 9    s$   A4 4A>=A> C C C 