
    Zi                         d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	m
Z
 d dlZddlmZ ddlmZmZmZmZmZmZ  G d d          ZdS )    N)LiteralSequenceOptionalListUnionAsyncGenerator	Awaitable   )get_max_items_from_list)UsageLimitExceededErrorInvalidAPIKeyErrorMissingAPIKeyErrorBadRequestErrorForbiddenErrorTimeoutErrorc            )       >   e Zd ZdZ	 	 	 	 	 	 dVdee         dee         deeeef                  dee         dee         d	ee         fd
Zd Z	d Z
d Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dWdeded         ded         ded         dededededee         dee         deeed         f         deeed         f         d ed!ed"ed#ed$ed%ed&ed'ef(d(Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dWdeded         ded         ded         dededededee         dee         deeed         f         deeed         f         d ed!ed"ed#ed$ed%ed&ed'ef(d)Z	 	 	 	 	 	 	 	 dXd+eee         ef         d ed,ed         d-ed         d!ed$ed%eded.ed'efd/Z	 	 	 	 	 	 	 	 dXd+eee         ef         d ed,ed         d-ed         d!ed$ed%eded.ed'efd0Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dYd2ed3ed4ed5ed6ed7ee         d8ee         d9ee         dee         d:ed ed,ed         d-ed         d!ed$ed%ed.ed'ef$d;Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dYd2ed3ed4ed5ed6ed7ee         d8ee         d9ee         dee         d:ed,ed         d ed-ed         d!ed$ed%ed.ed'ef$d<Z	 	 	 	 	 	 	 	 	 	 	 	 dZd2ed3ed4ed5ed6ed7ee         d8ee         d9ee         dee         d:ed ed!ed%ed'efd=Z	 	 	 	 	 	 	 	 	 	 	 	 dZd2ed3ed4ed5ed6ed7ee         d8ee         d9ee         dee         d:ed ed!ed%ed'efd>Z	 	 	 	 	 	 	 	 	 	 d[deded         ded         dededee         dee         dDed!ed"ed$ed'efdEZ	 	 	 	 	 	 	 	 	 d\deded         ded         dededee         dee         d!ed"ed$ed'efdGZ	 	 	 	 d]deded         ded!ed"ed'ee         fdHZ	 	 	 	 	 d^dKedLedM         dNedOedPedQ         d!ee         d'eeedf         ee         f         fdRZ 	 	 	 	 	 d^dKedLedM         dNedOedPedQ         d!ee         d'eeeedf         f         fdSZ!dTed'efdUZ"dS )_AsyncTavilyClientz(
    Async Tavily API client class.
    Nnewsgeneralfinanceapi_keycompany_info_tagsproxiesapi_base_urlclient_source
project_idc                 ,   |t          j        d          }|st                      |pi }|                    dt          j        d                    |                    dt          j        d                    d}d |                                D             }|rd |                                D             nd }|pt          j        d	          }	|pd
| _        t          j        dd| |pdd|	rd|	ini | j        |          | _        || _	        d S )NTAVILY_API_KEYhttpTAVILY_HTTP_PROXYhttpsTAVILY_HTTPS_PROXY)zhttp://zhttps://c                     i | ]
\  }}|||S  r%   ).0keyvalues      N/root/projects/butler/venv/lib/python3.11/site-packages/tavily/async_tavily.py
<dictcomp>z.AsyncTavilyClient.__init__.<locals>.<dictcomp>$   s$    WWWeQVW#uWWW    c                 @    i | ]\  }}|t          j        |           S ))proxy)httpxAsyncHTTPTransport)r&   schemer-   s      r)   r*   z.AsyncTavilyClient.__init__.<locals>.<dictcomp>'   s,    ggg}vuVU-E:::gggr+   TAVILY_PROJECTzhttps://api.tavily.comzapplication/jsonzBearer ztavily-python)zContent-TypeAuthorizationzX-Client-SourcezX-Project-ID)headersbase_urlmounts)
osgetenvr   getitems_api_base_urlr.   AsyncClient_client_company_info_tags)
selfr   r   r   r   r   r   mapped_proxiesproxy_mountstavily_projects
             r)   __init__zAsyncTavilyClient.__init__   sf    ?i 011G 	'$&&&-R {{6295H+I+IJJGRY7K-L-LMM
 

 XW~7K7K7M7MWWW ggP^PdPdPfPfgggg 	 $Bry1A'B'B)E-E ( 2!47!4!4#0#CO  8FMNN332	 '	
 	
 	
 #4r+   c                 H   K   | j                                          d{V  dS )z7Close the client and release connection pool resources.N)r<   acloser>   s    r)   closezAsyncTavilyClient.close=   s2      l!!###########r+   c                 
   K   | S Nr%   rE   s    r)   
__aenter__zAsyncTavilyClient.__aenter__A   s      r+   c                 >   K   |                                   d {V  d S rH   )rF   )r>   exc_typeexc_valexc_tbs       r)   	__aexit__zAsyncTavilyClient.__aexit__D   s,      jjllr+   <   querysearch_depth)basicadvancedfastz
ultra-fasttopic)r   r   r   
time_range)dayweekmonthyear
start_dateend_datedaysmax_resultsinclude_domainsexclude_domainsinclude_answer)rR   rS   include_raw_content)markdowntextinclude_imagestimeoutcountryauto_parametersinclude_faviconinclude_usageexact_matchreturnc                   K   i d|d|d|d|d|d|d|d|d	|d
|d|	d|
d|d|d|d|d|d|i}d |                                 D             }|r|                    |           t          |d          }	 | j                            dt          j        |          |           d{V }n"# t          j        $ r t          |          w xY w|j
        dk    r|                                S d}	 |                                                    di                               dd          }n# t          $ r Y nw xY w|j
        dk    rt          |          |j
        dv rt          |          |j
        dk    rt          |          |j
        dk    rt!          |          |                                ) zH
        Internal search method to send the request to the API.
        rP   rQ   rU   rV   r[   r\   r]   ra   rb   r^   r_   r`   re   rg   rh   ri   rj   rk   c                     i | ]
\  }}|||S rH   r%   r&   kvs      r)   r*   z-AsyncTavilyClient._search.<locals>.<dictcomp>v       ???A1r+   x   z/searchcontentrf   N    detailerror  i  i  i      )r9   updateminr<   postjsondumpsr.   TimeoutExceptionr   status_coder8   	Exceptionr   r   r   r   raise_for_status)r>   rP   rQ   rU   rV   r[   r\   r]   r^   r_   r`   ra   rb   re   rf   rg   rh   ri   rj   rk   kwargsdataresponserx   s                           r)   _searchzAsyncTavilyClient._searchG   s     4
U
L
 U
 *	

 *
 
 D
 n
 "#6
 ;
 
 
 n
 w
 
  !
" ]#
$ ;%
 
* @???? 	 KKgs##	(!\..y$*TBRBR\c.ddddddddHH% 	( 	( 	(w'''	( 3&&==??"F!,,Xr::>>wMM    #s**-f555%66$V,,,%,,(000%,,%f---//111s   5B8 8C<<D9 9
EEc                    K   t          |d          } | j        |fi d|d|d|d|d|d|d|d	|	d
|
d|d|d|d|d|d|d|d|d|| d{V }|                    dg           }||d<   |S )zr
        Combined search method. Set search_depth to either "basic", "advanced", "fast", or "ultra-fast".
        rs   rQ   rU   rV   r[   r\   r]   r^   r_   r`   ra   rb   re   rf   rg   rh   ri   rj   rk   Nresultsr   r   r8   )r>   rP   rQ   rU   rV   r[   r\   r]   r^   r_   r`   ra   rb   re   rf   rg   rh   ri   rj   rk   r   response_dicttavily_resultss                          r)   searchzAsyncTavilyClient.search   s`     2 gs##*dl5 - - -8D-16- 7Aj- 7Aj	-
 5=H- 15- 8C{- <K?- <K?- ;I.- @S?R- ;I.- 4;7- 4;7- <K?-  <K?!-" :G#-$ 8C{-3'- - - - - - - -, '**9b99#1i r+      urlsextract_depthformatchunks_per_sourcec
           
        K   |||||||||	d	}d |                                 D             }|
r|                    |
           	 | j                            dt	          j        |          |           d{V }n"# t          j        $ r t          |          w xY w|j	        dk    r|                                S d}	 |                                
                    di           
                    d	d          }n# t          $ r Y nw xY w|j	        d
k    rt          |          |j	        dv rt          |          |j	        dk    rt          |          |j	        dk    rt          |          |                                )z
        Internal extract method to send the request to the API.
        include_favicon: If True, include the favicon in the extraction results.
        )	r   re   r   r   rf   ri   rj   rP   r   c                     i | ]
\  }}|||S rH   r%   ro   s      r)   r*   z.AsyncTavilyClient._extract.<locals>.<dictcomp>   rr   r+   z/extractrt   Nrv   rw   rx   ry   rz   r{   r|   r}   )r9   r~   r<   r   r   r   r.   r   r   r   r8   r   r   r   r   r   r   )r>   r   re   r   r   rf   ri   rj   rP   r   r   r   r   rx   s                 r)   _extractzAsyncTavilyClient._extract   s     $ ,*.*!2

 

 @???? 	 KK	(!\..z4:dCSCS]d.eeeeeeeeHH% 	( 	( 	(w'''	( 3&&==??"F!,,Xr::>>wMM    #s**-f555%66$V,,,%,,(000%,,%f---//111s   5A; ;B?<C< <
D	D	c
                    K    | j         |||||f||||	d|
 d{V }|                    dg           }|                    dg           }||d<   ||d<   |S )z{
        Combined extract method.
        include_favicon: If True, include the favicon in the extraction results.
        )ri   rj   rP   r   Nr   failed_results)r   r8   )r>   r   re   r   r   rf   ri   rj   rP   r   r   r   r   r   s                 r)   extractzAsyncTavilyClient.extract  s        ,dmD,:,9,2,3	
.
 =L:G27>O
. 
. /5
. 
. 
. 
. 
. 
. 
. 
. '**9b99&**+;R@@#1i *8&'r+      url	max_depthmax_breadthlimitinstructionsselect_pathsselect_domainsexclude_pathsallow_externalc                 ^  K   i d|d|d|d|d|d|d|d|d	|	d
|
d|d|d|d|d|d|d|}|r|                     |           d |                                D             }	 | j                            dt	          j        |          |           d{V }n"# t          j        $ r t          |          w xY w|j	        dk    r|                                S d}	 |                                
                    di           
                    dd          }n# t          $ r Y nw xY w|j	        dk    rt          |          |j	        dv rt          |          |j	        dk    rt          |          |j	        dk    rt          |          |                                )zG
        Internal crawl method to send the request to the API.
        r   r   r   r   r   r   r   r   r`   r   re   r   r   rf   ri   rj   r   c                     i | ]
\  }}|||S rH   r%   ro   s      r)   r*   z,AsyncTavilyClient._crawl.<locals>.<dictcomp>Z  rr   r+   z/crawlrt   Nrv   rw   rx   ry   rz   r{   r|   r}   r~   r9   r<   r   r   r   r.   r   r   r   r8   r   r   r   r   r   r   )r>   r   r   r   r   r   r   r   r   r`   r   re   r   r   rf   ri   rj   r   r   r   r   rx   s                         r)   _crawlzAsyncTavilyClient._crawl,  st     .
3

 ;
 U	

 L
 L
 n
 ]
 
 n
 n
 ]
 f
 w
 
  ]!
"  !2#
(  	 KK?????	(!\..xDAQAQ[b.ccccccccHH% 	( 	( 	(w'''	( 3&&==??"F!,,Xr::>>wMM    #s**-f555%66$V,,,%,,(000%,,%f---//111s   .5B$ $C(<D% %
D21D2c                    K    | j         |fi d|d|d|d|d|d|d|d|	d	|
d
|d|d|d|d|d|d|| d{V }|S )z)
        Combined crawl method.

        r   r   r   r   r   r   r   r`   r   r   re   r   rf   ri   rj   r   N)r   )r>   r   r   r   r   r   r   r   r   r`   r   r   re   r   rf   ri   rj   r   r   r   s                       r)   crawlzAsyncTavilyClient.crawlu  s     0 *dk# . . ..7i.0;. +0%. 2>	.
 2>. 4B>. 3@-. 5DO. 4B>. 3@-. 4B>. ,26. -4G. 5DO. 3@-.  7H6G&,#. . . . . . . .& r+   c                   K   |||||||||	|
|||d}|r|                     |           d |                                D             }	 | j                            dt	          j        |          |           d{V }n"# t          j        $ r t          |          w xY w|j	        dk    r|                                S d}	 |                                
                    di           
                    d	d          }n# t          $ r Y nw xY w|j	        d
k    rt          |          |j	        dv rt          |          |j	        dk    rt          |          |j	        dk    rt          |          |                                )zE
        Internal map method to send the request to the API.
        )r   r   r   r   r   r   r   r   r`   r   re   rf   rj   c                     i | ]
\  }}|||S rH   r%   ro   s      r)   r*   z*AsyncTavilyClient._map.<locals>.<dictcomp>  rr   r+   z/maprt   Nrv   rw   rx   ry   rz   r{   r|   r}   r   )r>   r   r   r   r   r   r   r   r   r`   r   re   rf   rj   r   r   r   rx   s                     r)   _mapzAsyncTavilyClient._map  s     ( "&((,*.,,*
 
   	 KK?????	(!\..vtz$?O?OY`.aaaaaaaaHH% 	( 	( 	(w'''	( 3&&==??"F!,,Xr::>>wMM    #s**-f555%66$V,,,%,,(000%,,%f---//111s   	5A? ?B<D   
DDc                 L   K    | j         |f||||||||	|
|||d| d{V }|S )z'
        Combined map method.

        )r   r   r   r   r   r   r   r`   r   re   rf   rj   N)r   )r>   r   r   r   r   r   r   r   r   r`   r   re   rf   rj   r   r   s                   r)   mapzAsyncTavilyClient.map  s{      ( (di ..70;*/1=1=3A2?4C3A3A,32?. . '-. . . . . . . . r+   rR   r           
max_tokensc                    K   t          |	d          }	 | j        |f||||||ddd|	|
|d| d{V }|                    dg           }d |D             }t          j        t          ||                    S )a  
        Get the search context for a query. Useful for getting only related content from retrieved websites
        without having to deal with context extraction and limitation yourself.

        max_tokens: The maximum number of tokens to return (based on openai token compute). Defaults to 4000.

        Returns a string of JSON containing the search context up to context limit.
        rs   F)rQ   rU   r]   r^   r_   r`   ra   rb   re   rf   rg   ri   Nr   c                 0    g | ]}|d          |d         dS )r   ru   )r   ru   r%   )r&   sources     r)   
<listcomp>z8AsyncTavilyClient.get_search_context.<locals>.<listcomp>/  s)    ^^^F6%=VI5FGG^^^r+   )r   r   r8   r   r   r   )r>   rP   rQ   rU   r]   r^   r_   r`   r   rf   rg   ri   r   r   sourcescontexts                   r)   get_search_contextz$AsyncTavilyClient.get_search_context  s      , gs##*dl5 -8D16047B;J;J:??D:?5<3:;J- - .4- - - - - - - -  ##Ir22^^V]^^^z1':FFGGGr+   rS   c                    K   t          |d          } | j        |f||||||ddd||	|
d| d{V }|                    dd          S )z`
        Q&A search method. Search depth is advanced by default to get the best answer.
        rs   FT)rQ   rU   r]   r^   r_   r`   rb   re   ra   rf   rg   ri   Nanswerrw   r   )r>   rP   rQ   rU   r]   r^   r_   r`   rf   rg   ri   r   r   s                r)   
qna_searchzAsyncTavilyClient.qna_search2  s        gs##*dl5 -8D16047B;J;J?D:?:>5<3:;J- - .4- - - - - - - -   2...r+   c                 $   	K   t          d          dt          f fd	g }t          j        	fd j        D               d{V D ]!}d|v r|                    |d                    "t          |d d	          d         }|S )
z` Company information search method. Search depth is advanced by default to get the best answer. rs   rU   c           	      L   K                        | d           d {V S )NF)rQ   rU   r^   ra   rf   rg   )r   )rU   rg   r^   rP   rQ   r>   rf   s    r)   _perform_searchz;AsyncTavilyClient.get_company_info.<locals>._perform_search^  sT      e3?,12=5:07.5 & 7 7 7 7 7 7 7 7 7r+   c                 &    g | ]} |          S r%   r%   )r&   rU   r   s     r)   r   z6AsyncTavilyClient.get_company_info.<locals>.<listcomp>h  s#    *g*g*ge??5+A+A*g*g*gr+   Nr   c                     | d         S )Nscorer%   )xs    r)   <lambda>z4AsyncTavilyClient.get_company_info.<locals>.<lambda>m  s
    1W: r+   T)r'   reverse)r   strasynciogatherr=   extendsorted)
r>   rP   rQ   r^   rf   rg   all_resultsr   sorted_resultsr   s
   ``````   @r)   get_company_infoz"AsyncTavilyClient.get_company_infoT  s       gs##	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 !.*g*g*g*gtOf*g*g*ghhhhhhh 	4 	4DD  ""4	?333  1E1EtTTTUaVaUabr+   Fnumberedinputmodel)miniproautooutput_schemastreamcitation_format)r   mlaapachicagoc                     
 |||||d
d 
                                 D             
|r
                    |           |r&dt          t          df         f
 fd} |            S 
 fd}	 |	            S )zJ
        Internal research method to send the request to the API.
        )r   r   r   r   r   c                     i | ]
\  }}|||S rH   r%   ro   s      r)   r*   z/AsyncTavilyClient._research.<locals>.<dictcomp>  rr   r+   rl   Nc                 v  K   	 j                             ddt          j                            4 d {V 	 } | j        dk    r	 |                                  d {V }t          |t                    r|                    d          n|}n# t          $ r d}Y nw xY w| j        dk    rt          |          | j        dv rt          |          | j        d	k    rt          |          | j        d
k    rt          |          t          d| j         d|           |                                 2 3 d {V }|r|W V  6 	 d d d           d {V  d S # 1 d {V swxY w Y   d S # t          j        $ r t#                    t          $ r$}t          dt%          |                     d }~ww xY w)NPOST	/researchrt   rv   zutf-8zUnknown errorrz   r{   r|   r}   zError z: zError during research stream: )r<   r   r   r   r   aread
isinstancebytesdecoder   r   r   r   r   aiter_bytesr.   r   r   r   )r   
error_textchunker   r>   rf   s       r)   stream_generatorz5AsyncTavilyClient._research.<locals>.stream_generator  s     O#|22# $
4 0 0 '	  3     , , , , , , , ,
 "#/366=3;>>3C3C-C-C-C-C-C-C
KUV`bgKhKh-xZ->->w-G-G-Gnx

#, = = =-<


=  (3s::&=j&I&I I!)!5!F!F&4Z&@&@ @!)!5!<!<&8&D&D D!)!5!<!<&5j&A&A A&/0]9M0]0]Q[0]0]&^&^ ^+3+?+?+A+A , , , , , , ,%$ ,&+ ,B+A1, , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,6 - 0 0 0&w///  O O O#$MSVV$M$MNNNOsl   6E- E	ABEBEBBE6E<
EE- 
E$$E- 'E$(E- -'F8F33F8c                    K   	 j                             dt          j                             d {V } n"# t          j        $ r t                    w xY w| j        dk    r|                                 S d}	 |                                                     di                               dd           }n# t          $ r Y nw xY w| j        dk    rt          |          | j        dv rt          |          | j        d	k    rt          |          | j        d
k    rt          |          |                                 )Nr   rt   rv   rw   rx   ry   rz   r{   r|   r}   )r<   r   r   r   r.   r   r   r   r8   r   r   r   r   r   r   )r   rx   r   r>   rf   s     r)   _make_requestz2AsyncTavilyClient._research.<locals>._make_request  sp     0%)\%6%6{DJW[L\L\fm%6%n%nnnnnnnHH- 0 0 0&w///0 '3..#==??*F!)!4!4Xr!B!B!F!FwPT!U!U$     +s225f===!->>,V444!-440888!-44-f555&77999s   5; A?<B< <
C	C	)r9   r~   r   r   )r>   r   r   r   r   r   rf   r   r   r   r   s   `     `   @r)   	_researchzAsyncTavilyClient._researchq  s     *.
 
 @???? 	 KK ?	# ON5$;,G  O  O  O  O  O  O  O  OD $#%%%: : : : : : :4 !=??"r+   c           
      F   K    | j         d||||||d|}|r|S | d{V S )a   
        Research method to create a research task.

        Args:
            input: The research task description (required).
            model: Research depth - must be either 'mini', 'pro', or 'auto'.
            output_schema: Schema for the 'structured_output' response format (JSON Schema dict).
            stream: Whether to stream the research task.
            citation_format: Citation format - must be either 'numbered', 'mla', 'apa', or 'chicago'.
            timeout: Optional HTTP request timeout in seconds.
            **kwargs: Additional custom arguments.

        Returns:
            When stream=False: dict - the response dictionary.
            When stream=True: AsyncGenerator[bytes, None] - iterate over this to get streaming chunks.
        )r   r   r   r   r   rf   Nr%   )r   )	r>   r   r   r   r   r   rf   r   results	            r)   researchzAsyncTavilyClient.research  sb      2   
+ /
 
 
 
  	 M<<<<<<r+   
request_idc                 j  K   	 | j                             d|            d{V }n$# t          $ r}t          d|           d}~ww xY w|j        dv r|                                }|S d}	 |                                                    di                               dd          }n# t          $ r Y nw xY w|j        dk    rt          |          |j        d	v rt          |          |j        d
k    rt          |          |j        dk    rt          |          |	                                )z
        Get research results by request_id.

        Args:
            request_id: The research request ID.

        Returns:
            dict: Research response containing request_id, created_at, completed_at, status, content, and sources.
        z
/research/NzError getting research: )rv      rw   rx   ry   rz   r{   r|   r}   )
r<   r8   r   r   r   r   r   r   r   r   )r>   r   r   r   r   rx   s         r)   get_researchzAsyncTavilyClient.get_research  sr     	<!\--.G:.G.GHHHHHHHHHH 	< 	< 	<:q::;;;	< :--==??DKF!,,Xr::>>wMM    #s**-f555%66$V,,,%,,(000%,,%f---//111s&   #( 
A	AA	.<B+ +
B87B8)Nr   NNNN)NNNNNNNNNNNNrO   NNNNN)NNNr   NNNN)NNNNNNNNNNNNr   NNN)NNNNNNNNNNr   N)
rR   r   r   r   NNr   rO   NN)	rS   r   r   r   NNrO   NN)rS   r   rO   N)NNFr   N)#__name__
__module____qualname____doc__r   r   r   dictrB   rF   rI   rN   r   intr   boolfloatr   r   r   r   r   r   r   r   r   r   r   r   r   r   r	   r   r   r   r%   r+   r)   r   r      s.         154R59/304-1*4 *4 *4$,SM*4"4S>2*4  (}*4 !)	*4
 &c]*4 *4 *4 *4X$ $ $     PT;?BF" #-1-1HLLP#'$($("& $)M2 M2M2 ""KLM2 78	M2
   >?M2 M2 M2 M2 M2 &c]M2 &c]M2 "$0C(D"DEM2 "'tW5G-H'H!IM2 !M2 M2  !M2" "#M2$ "%M2&  'M2( )M2, 
-M2 M2 M2 M2b Y]DHKO'+%)!%(,6:6:QUUY,0&($(-1-1+/)-'4 44#*+T#U4 $$@A4 "))G!H	4
 "%4  #4 4 #&4 '/sm4 '/sm4 &+49L1M+M%N4 +0g>P6Q0Q*R4 &*4 $4 "4  '+!4" '+#4$ %)%4& #''4* +4 4 4 4r $(:>26$("&%):2 :2S	3':2 !:2 ##67	:2
 ./:2 :2 ":2  :2 :2  #:2 
:2 :2 :2 :2| .2DH<@').2,0#'/3" "!$s)S.1"&*" &--@%A" &&89	"
  %" (," &*" !" *-"  " " " "L !%"& #'-1/3.204&*&*=A59 #'+%)(,#G2 G2G2G2  G2 	G2
 !G2 &c]G2  (}G2 'smG2 !)G2  $G2  $G2 &&9:G2 12G2 G2 !%G2  #!G2" #&#G2& 'G2 G2 G2 G2V &*'+!%(,26483759+/BF+/:>%(,0*.-1#+ ++"+ "%+ 	+
 #&+ #+3-+ %-SM+ $,C=+ &.c]+ %)+ $++>#?+ %)+ $$67+ #+ &*+  $(!+" (+#+& '+ + + +^ !%"& #'-1/3.204&*&* #%)?2 ?2?2?2  ?2 	?2
 !?2 &c]?2  (}?2 'sm?2 !)?2  $?2  $?2 ?2 #?2 ?2 ?2 ?2 ?2F &*'+!%(,26483759+/+/%(*.# ##"# "%# 	#
 #&# #+3-# %-SM# $,C=# &.c]# %)# %)# ## $(# # # # #N elPY-.45BFBF3724049=(H (H(+(H/67`/a(H )00L(M(H (+	(H
 /2(H 3;3-(H 3;3-(H .1(H +0(H +.(H 37(H '*(H (H (H (HX ]gHQ%&,-:>:>*,(,15 /  / # /'./X'Y / !((D E /  #	 /
 '* / +33- / +33- / #( / #& / +/ / " /  /  /  /H cm2302.2 &)-45^-_ -0 ).	
 ), %-TN   > ;?(,!&R\-1X# X#X# !67X# "&X# 	X#
 $++N#OX# $E?X# ^E4K8)D/IJX# X# X# X#x @D-1&+Wa26%  % !% %&;<%  '+%   $	% 
 )00S(T%  !)%  "$ud{(C"CD%  %  %  % N$2'*$2 $$2 $2 $2 $2 $2 $2r+   r   )r   r   r6   typingr   r   r   r   r   r   r	   r.   utilsr   errorsr   r   r   r   r   r   r   r%   r+   r)   <module>r      s     				 V V V V V V V V V V V V V V V V V V  * * * * * * C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  CJ2 J2 J2 J2 J2 J2 J2 J2 J2 J2r+   