a
    &ñ»j8P  ã                   @  s@  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	 d dl
mZ d dlmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZmZ d	d
lmZ d	dlmZ g d¢ZedƒZ eddd�Z!g d¢Z"g d¢Z#dd„ e#D ƒZ$G dd„ deee  ƒZ%G dd„ de%e ƒZ&G dd„ de%e ƒZ'G dd„ de%e ƒZ(dS )é    )ÚannotationsN)ÚABCÚabstractmethod)ÚPath)	ÚAnyÚGenericÚIterableÚIteratorÚListÚLiteralÚOptionalÚTypeVarÚUnioné   )ÚRotatorError)ÚHeaderTypesÚIdentifierTypesé   )ÚHeaders)ÚProxy)ÚBaseRotatorÚProxyRotatorÚTLSIdentifierRotatorÚHeaderRotatorÚTÚRr   )Úbound)Z
chrome_120Z
chrome_124Z
chrome_131Z
chrome_133Zfirefox_120Zfirefox_123Zfirefox_132Zfirefox_133Zsafari_16_0Zsafari_ios_16_0Zsafari_ios_17_0Zsafari_ios_18_0Zsafari_ios_18_5),zoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36zoMozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36ztMozilla/5.0 (Macintosh; Intel Mac OS X 14_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zeMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zeMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36zPMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0zTMozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0zFMozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0zPMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15ztMozilla/5.0 (Macintosh; Intel Mac OS X 14_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15z‡Mozilla/5.0 (iPhone; CPU iPhone OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1z~Mozilla/5.0 (iPad; CPU OS 17_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1z}Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0zƒMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0zvMozilla/5.0 (Linux; Android 14; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 14; SM-S918B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36z‡Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1z¤Mozilla/5.0 (Linux; Android 15; SM-S931B Build/AP3A.240905.015.A2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.103 Mobile Safari/537.36z~Mozilla/5.0 (Linux; Android 14; SM-S928B/DS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.230 Mobile Safari/537.36z†Mozilla/5.0 (Linux; Android 14; SM-F956U) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 13; SM-S911U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 13; SM-S901B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 13; SM-S908U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 13; SM-G998U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36z£Mozilla/5.0 (Linux; Android 14; Pixel 9 Pro Build/AD1A.240418.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.54 Mobile Safari/537.36z¢Mozilla/5.0 (Linux; Android 14; Pixel 9 Build/AD1A.240411.003.A5; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.54 Mobile Safari/537.36z¤Mozilla/5.0 (Linux; Android 15; Pixel 8 Pro Build/AP4A.250105.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.163 Mobile Safari/537.36z Mozilla/5.0 (Linux; Android 15; Pixel 8 Build/AP4A.250105.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.163 Mobile Safari/537.36zyMozilla/5.0 (Linux; Android 13; Pixel 7 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36zuMozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36z¥Mozilla/5.0 (Linux; Android 15; moto g - 2025 Build/V1VK35.22-13-2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.163 Mobile Safari/537.36zžMozilla/5.0 (Linux; Android 13; 23129RAA4G Build/TKQ1.221114.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36z¥Mozilla/5.0 (Linux; Android 15; 24129RT7CC Build/AP3A.240905.015.A2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.86 Mobile Safari/537.36zœMozilla/5.0 (Linux; Android 12; HBP-LX9 Build/HUAWEIHBP-L29; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Mobile Safari/537.36z»Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; ADA-AL00 Build/HUAWEIADA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/6.11.2.531 Mobile Safari/537.36zžMozilla/5.0 (Linux; Android 12; PSD-AL00 Build/HUAWEIPSD-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Mobile Safari/537.36z£Mozilla/5.0 (Linux; Android 14; 24030PN60G Build/UKQ1.231003.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/122.0.6261.119 Mobile Safari/537.36zuMozilla/5.0 (Linux; Android 10; VOG-L29) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36zvMozilla/5.0 (Linux; Android 10; MAR-LX1A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36c                 C  s   g | ]}d dd|dœ‘qS )z*/*z
keep-alivezgzip, deflate, br, zstd)ÚacceptÚ
connectionzaccept-encodingú
User-Agent© )Ú.0Zuar    r    úBE:\soccer\ml_env\Lib\site-packages\tls_requests/models/rotators.pyÚ
<listcomp>Ã   s   ûür#   c                   @  s   e Zd ZdZd3ddddœdd	„Zed
dœdd„ƒZed4dddddœdd„ƒZee	dddœdd„ƒƒZ
ddœdd„Zddddœdd „Zd!dœd"d#„Zd!ddœd$d%„Zd!ddœd&d'„Zd!dœd(d)„Zd!ddœd*d+„Zd!ddœd,d-„Zd.dœd/d0„Zddœd1d2„ZdS )5r   ao  
    A unified, thread-safe and coroutine-safe abstract base class for a
    generic rotating data source.

    This class provides a dual API for both synchronous and asynchronous contexts.
    - For synchronous, thread-safe operations, use methods like `next()`, `add()`.
    - For asynchronous, coroutine-safe operations, use methods prefixed with 'a',
      like `anext()`, `aadd()`.

    It uses a `threading.Lock` for thread safety and an `asyncio.Lock` for
    coroutine safety.

    Attributes:
        items (List[T]): The list of items to rotate through.
        strategy (str): The rotation strategy in use.
    NÚrandomzOptional[Iterable[T]]ú,Literal['round_robin', 'random', 'weighted']ÚNone©ÚitemsÚstrategyÚreturnc                 C  s6   t |pg ƒ| _|| _d| _t ¡ | _d| _|  ¡  dS )z¢
        Initializes the BaseRotator.

        Args:
            items: An iterable of initial items.
            strategy: The rotation strategy to use.
        N)	Úlistr(   r)   Ú	_iteratorÚ	threadingÚLockÚ_lockÚ_async_lockÚ_rebuild_iterator©Úselfr(   r)   r    r    r"   Ú__init__à   s    
zBaseRotator.__init__zasyncio.Lock)r*   c                 C  s   | j du rt ¡ | _ | j S )zâ
        Lazily creates and returns an `asyncio.Lock`. This ensures that the lock
        is created within the correct event loop and avoids issues in
        synchronous contexts or older Python versions (like 3.9).
        N)r0   Úasyncior.   ©r3   r    r    r"   Ú
async_lockó   s    

zBaseRotator.async_lockztype[R]zUnion[str, Path, list]r   )ÚclsÚsourcer)   r*   c           
        sæ   g }t |ttfƒržt|ƒ}| ¡ s0td|› �ƒ‚|jdkr\t | ¡ ¡}‡ fdd„|D ƒ}qÎ| ¡  	¡ }|D ].}| 
dd¡d  ¡ }|sŠql| ˆ  |¡¡ qln0t |tƒr¼‡ fdd„|D ƒ}ntd	t|ƒ› �ƒ‚d
d„ |D ƒ}	ˆ |	|ƒS )z“
        Factory method to create a rotator from a file or a list. This method
        is synchronous as it's typically used during setup.
        zSource file not found: z.jsonc                   s   g | ]}ˆ   |¡‘qS r    ©Úrebuild_item©r!   Úitem©r8   r    r"   r#     ó    z)BaseRotator.from_file.<locals>.<listcomp>ú#r   r   c                   s   g | ]}ˆ   |¡‘qS r    r:   r<   r>   r    r"   r#     r?   zUnsupported source type: c                 S  s   g | ]}|d ur|‘qS ©Nr    r<   r    r    r"   r#     r?   )Ú
isinstanceÚstrr   ÚexistsÚFileNotFoundErrorÚsuffixÚjsonÚloadsÚ	read_textÚ
splitlinesÚsplitÚstripÚappendr;   r+   r   Útype)
r8   r9   r)   r(   ÚpathÚdataÚlinesÚlineZline_contentZvalid_itemsr    r>   r"   Ú	from_fileþ   s&    

zBaseRotator.from_filer   zOptional[T]©r=   r*   c                 C  s   t ‚dS )zw
        Abstract method to convert a raw item into a typed object. Must be
        implemented by subclasses.
        N)ÚNotImplementedError©r8   r=   r    r    r"   r;   !  s    zBaseRotator.rebuild_itemc                 C  s|   | j sd| _dS | jdkr*t | j ¡| _nN| jdkr<d| _n<| jdkrhdd„ | j D ƒ}|  | j |¡| _ntd| j› �ƒ‚dS )z‹
        Reconstructs the internal iterator. This is a core logic method and
        should be called only after acquiring a lock.
        NÚround_robinr$   Úweightedc                 S  s   g | ]}t |d dƒ‘qS )Úweightg      ð?)Úgetattrr<   r    r    r"   r#   8  r?   z1BaseRotator._rebuild_iterator.<locals>.<listcomp>zUnsupported strategy: )r(   r,   r)   Ú	itertoolsÚcycleÚ_weighted_cycleÚ
ValueError)r3   Úweightsr    r    r"   r1   *  s    


zBaseRotator._rebuild_iteratorzList[T]zList[float]zIterator[T])r(   r_   r*   c                 c  s   t j||dd�d V  q dS )z@Creates an infinite iterator that yields items based on weights.r   )r_   Úkr   N)r$   Úchoices)r3   r(   r_   r    r    r"   r]   =  s    zBaseRotator._weighted_cycler   c                 O  s†   | j �l | jstdƒ‚| jdkr:t | j¡W  d  ƒ S | jdu rL|  ¡  | jdusZJ ‚t| jƒW  d  ƒ S 1 sx0    Y  dS )zÔ
        Retrieves the next item using a thread-safe mechanism.

        Returns:
            The next item from the collection.

        Raises:
            ValueError: If the rotator contains no items.
        úRotator is empty.r$   N)	r/   r(   r^   r)   r$   Úchoicer,   r1   Únext©r3   ÚargsÚkwargsr    r    r"   rd   B  s    


zBaseRotator.nextc                 C  s>   | j �$ | j |¡ |  ¡  W d  ƒ n1 s00    Y  dS )zI
        Adds a new item to the rotator in a thread-safe manner.
        N)r/   r(   rM   r1   ©r3   r=   r    r    r"   ÚaddV  s    zBaseRotator.addc                   sH   | j �. ‡ fdd„| jD ƒ| _|  ¡  W d  ƒ n1 s:0    Y  dS )zK
        Removes an item from the rotator in a thread-safe manner.
        c                   s   g | ]}|ˆ kr|‘qS r    r    ©r!   Úi©r=   r    r"   r#   c  r?   z&BaseRotator.remove.<locals>.<listcomp>N)r/   r(   r1   rh   r    rl   r"   Úremove^  s    zBaseRotator.removec              	   Ï  s    | j 4 I dH šx | jstdƒ‚| jdkrHt | j¡W  d  ƒI dH  S | jdu rZ|  ¡  | jdushJ ‚t| jƒW  d  ƒI dH  S 1 I dH s’0    Y  dS )z×
        Retrieves the next item using a coroutine-safe mechanism.

        Returns:
            The next item from the collection.

        Raises:
            ValueError: If the rotator contains no items.
        Nrb   r$   )	r7   r(   r^   r)   r$   rc   r,   r1   rd   re   r    r    r"   Úanextf  s    

 
zBaseRotator.anextc              	   Ã  sR   | j 4 I dH š* | j |¡ |  ¡  W d  ƒI dH  qN1 I dH sD0    Y  dS )zL
        Adds a new item to the rotator in a coroutine-safe manner.
        N)r7   r(   rM   r1   rh   r    r    r"   Úaaddz  s    zBaseRotator.aaddc              	   ƒ  s\   | j 4 I dH š4 ‡ fdd„| jD ƒ| _|  ¡  W d  ƒI dH  qX1 I dH sN0    Y  dS )zN
        Removes an item from the rotator in a coroutine-safe manner.
        Nc                   s   g | ]}|ˆ kr|‘qS r    r    rj   rl   r    r"   r#   ‡  r?   z'BaseRotator.aremove.<locals>.<listcomp>)r7   r(   r1   rh   r    rl   r"   Úaremove‚  s    zBaseRotator.aremoveÚintc                 C  s
   t | jƒS rA   )Úlenr(   r6   r    r    r"   Ú__len__Š  s    zBaseRotator.__len__c                 C  s
   t | jƒS rA   )Úiterr(   r6   r    r    r"   Ú__iter__�  s    zBaseRotator.__iter__)Nr$   )r$   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r4   Úpropertyr7   ÚclassmethodrS   r   r;   r1   r]   rd   ri   rm   rn   ro   rp   rs   ru   r    r    r    r"   r   Î   s,     ý
 ý"c                   @  sd   e Zd ZdZedddœdd„ƒZddd	d
ddœdd„Zddd	d
ddœdd„Zddd	d
dœdd„ZdS )r   zh
    A unified rotator for managing `Proxy` objects, supporting both sync and
    async operations.
    r   zOptional[Proxy]rT   c                 C  sZ   z@t |tƒr|W S t |tƒr(t |¡W S t |tƒr>t |¡W S W n tyT   Y dS 0 dS )z5Constructs a `Proxy` object from various input types.N)rB   r   ÚdictÚ	from_dictrC   Zfrom_stringÚ	ExceptionrV   r    r    r"   r;   —  s    


zProxyRotator.rebuild_itemNr   ÚboolzOptional[float]r&   )ÚproxyÚsuccessÚlatencyr*   c                 C  s8   | j � |  |||¡ W d  ƒ n1 s*0    Y  dS )zI
        Thread-safely updates a proxy's performance statistics.
        N)r/   Ú_update_proxy_stats©r3   r€   r�   r‚   r    r    r"   Úmark_result¥  s    zProxyRotator.mark_resultc              	   Ã  sL   | j 4 I dH š$ |  |||¡ W d  ƒI dH  qH1 I dH s>0    Y  dS )zL
        Coroutine-safely updates a proxy's performance statistics.
        N)r7   rƒ   r„   r    r    r"   Úamark_result¬  s    zProxyRotator.amark_result)r€   r�   r‚   c                 C  s.   |r|  |¡ n| ¡  | jdkr*|  ¡  dS )zNInternal logic for updating proxy stats. Must be called from a locked context.rX   N)Zmark_successZmark_failedr)   r1   r„   r    r    r"   rƒ   ³  s
    
z ProxyRotator._update_proxy_stats)N)N)N)	rv   rw   rx   ry   r{   r;   r…   r†   rƒ   r    r    r    r"   r   ‘  s   r   c                      s@   e Zd ZdZdddddœ‡ fdd	„Zed
ddœdd„ƒZ‡  ZS )r   z[
    A unified rotator for TLS Identifiers, supporting both sync and async operations.
    NrW   z#Optional[Iterable[IdentifierTypes]]r%   r&   r'   c                   s   t ƒ  |pt|¡ d S rA   )Úsuperr4   ÚCLIENT_IDENTIFIER_TEMPLATESr2   ©Ú	__class__r    r"   r4   Ã  s    zTLSIdentifierRotator.__init__r   zOptional[IdentifierTypes]rT   c                 C  s   t |tƒr|S dS )z4Processes a raw item to be used as a TLS identifier.N)rB   rC   rV   r    r    r"   r;   Ê  s    
z!TLSIdentifierRotator.rebuild_item)NrW   )rv   rw   rx   ry   r4   r{   r;   Ú__classcell__r    r    r‰   r"   r   ¾  s     ýr   c                      sl   e Zd ZdZdddddœ‡ fdd	„Zed
ddœdd„ƒZddddœ‡ fdd„Zddddœ‡ fdd„Z‡  Z	S )r   aÃ  
    A unified rotator for managing `Headers` objects, supporting both sync and
    async operations.

    This rotator can dynamically update the 'User-Agent' header for each request
    without modifying the original header templates.

    Examples:
        >>> common_headers = {
        ...     "Accept": "application/json",
        ...     "Accept-Language": "en-US,en;q=0.9",
        ...     "User-Agent": "Default-Bot/1.0"
        ... }
        >>> mobile_headers = {
        ...     "Accept": "*/*",
        ...     "User-Agent": "Default-Mobile/1.0",
        ...     "X-Custom-Header": "mobile"
        ... }
        >>>
        >>> rotator = HeaderRotator.from_file([common_headers, mobile_headers])
        >>>
        >>> # Get headers without modification
        >>> h1 = rotator.next()
        >>> print(h1['User-Agent'])
        Default-Bot/1.0
        >>>
        >>> # Get headers with a new, dynamic User-Agent
        >>> h2 = rotator.next(user_agent="My-Custom-UA/2.0")
        >>> print(h2['User-Agent'])
        My-Custom-UA/2.0
        >>>
        >>> # The original header set remains unchanged
        >>> h3 = rotator.next()
        >>> print(h3['User-Agent'])
        Default-Mobile/1.0
    Nr$   zOptional[Iterable[HeaderTypes]]r%   r&   r'   c                   s   t ƒ  |pt|¡ d S rA   )r‡   r4   ÚHEADER_TEMPLATESr2   r‰   r    r"   r4   ø  s    zHeaderRotator.__init__r   zOptional[Headers]rT   c                 C  s4   zt |tƒr|W S t|ƒW S  ty.   Y dS 0 dS )aF  
        Constructs a `Headers` object from various input types.

        It can process existing `Headers` objects, dictionaries, or lists of tuples.

        Args:
            item: The raw data to convert into a `Headers` object.

        Returns:
            A `Headers` instance, or None if the input is invalid.
        N)rB   r   r~   rV   r    r    r"   r;   ÿ  s    

zHeaderRotator.rebuild_itemzOptional[str]r   )Ú
user_agentr*   c                   s4   t ƒ  ¡ }| ¡ }t|tƒs$t|ƒ}|r0||d< |S )a|  
        Retrieves the next `Headers` object in a thread-safe manner and
        optionally updates its User-Agent.

        Args:
            user_agent: If provided, this string will replace the 'User-Agent'
                        header in the returned object.

        Returns:
            A copy of the next `Headers` object, potentially with a modified User-Agent.
        r   )r‡   rd   ÚcopyrB   r   ©r3   r�   rg   ÚheadersZheaders_copyr‰   r    r"   rd     s    

zHeaderRotator.nextc                 ‹  s:   t ƒ  ¡ I dH }| ¡ }t|tƒs*t|ƒ}|r6||d< |S )a  
        Retrieves the next `Headers` object in a coroutine-safe manner and
        optionally updates its User-Agent.

        Args:
            user_agent: If provided, this string will replace the 'User-Agent'
                        header in the returned object.

        Returns:
            A copy of the next `Headers` object, potentially with a modified User-Agent.
        Nr   )r‡   rn   rŽ   rB   r   r�   r‰   r    r"   rn   '  s    
zHeaderRotator.anext)Nr$   )N)N)
rv   rw   rx   ry   r4   r{   r;   rd   rn   r‹   r    r    r‰   r"   r   Ò  s   '  ýr   ))Ú
__future__r   r5   r[   rG   r$   r-   Úabcr   r   Úpathlibr   Útypingr   r   r   r	   r
   r   r   r   r   Ú
exceptionsr   Útypesr   r   r�   r   Úurlsr   Ú__all__r   r   rˆ   ZUSER_AGENTSrŒ   r   r   r   r   r    r    r    r"   Ú<module>   s4   , ù D-