
    @ jR[                        d dl Z d dl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 ddlmZ ddlmZmZmZmZmZmZ dZdZdZdZeeeeef         f         Zed	eeef         f         Zerdd
lmZ eefdedededefdZ efdedededefdZ!dedededededefdZ"efdede#defdZ$efdede#defdZ%	 d.dedededefdZ&dede	e         fdZ'de	e         de	e	e                  fd Z( G d! d"e)          Z* G d# d$e*          Z+ G d% d&e)          Z,g d'Z-g d(Z. G d) d*e/          Z0 e0d           Z1e G d+ d	                      Z2 G d, d-e)          Z3dS )/    N)	dataclass)
itemgetter)TYPE_CHECKINGAnyDictListOptionalSetTupleUnion   )utils)T_bboxT_numT_obj
T_obj_iter
T_obj_listT_point   TableSettings)Pageedgesx_tolerancey_tolerancereturnc                     g g d}| D ]#}||d                                       |           $t          j        |d         d|          }t          j        |d         d|          }||z   S )zs
    Given a list of edges, snap any within `tolerance` pixels of one another
    to their positional average.
    vhorientationr   x0r   top)appendr   snap_objects)r   r   r   by_orientatione	snapped_v	snapped_hs          dC:\Users\Terasoftware\OneDrive\Desktop\faahhh\fyndo\fyndo\venv\Lib\site-packages\pdfplumber/table.py
snap_edgesr*      s~     352,>,>N 3 3q'(//2222">##6kJJI">##6{KKIy      r    	tolerancec                    |dk    rd\  }}n|dk    rd\  }}nt          d          t          t          | t          |                              }|d         g}|dd	         D ]f}|d
         }||         ||         |z   k    r2||         ||         k    rt	          j        ||||                   |d
<   Q|                    |           g|S )z
    Given a list of edges along the same infinite line, join those that
    are within `tolerance` pixels of one another.
    r   )r!   x1r   )r"   bottomzOrientation must be 'v' or 'h'keyr   r   N)
ValueErrorlistsortedr   r   resize_objectr#   )	r   r    r,   min_propmax_propsorted_edgesjoinedr&   lasts	            r)   join_edge_groupr<   '   s     c ;'((		 ;,((9:::u*X*>*>???@@L1oF!""  bzX;4>I56 	{T(^+ N"0x8MMr
 MM!Mr+   snap_x_tolerancesnap_y_tolerancejoin_x_tolerancejoin_y_tolerancec                 .   dt           dt          t          t          f         fd}|dk    s|dk    rt	          | ||          } t          | |          }t          j        ||          }fd|D             }t          t          j	        |           } | S )z|
    Using the `snap_edges` and `join_edge_group` methods above,
    merge a list of edges into a more "seamless" list.
    edger   c                 B    | d         dk    r
d| d         fS d| d         fS )Nr    r   r"   r   r!    )rB   s    r)   	get_groupzmerge_edges.<locals>.get_groupP   s2    #% 	%e%%d$$r+   r   r0   c              3   h   K   | ],\  }}t          ||d          |d          dk    rn          V  -dS )r   r   N)r<   ).0kitemsr?   r@   s      r)   	<genexpr>zmerge_edges.<locals>.<genexpr>[   sf         Au 	1Q4adckO**?O	
 	
     r+   )
r   r   strr   r*   r5   	itertoolsgroupbyr4   chain)	r   r=   r>   r?   r@   rE   _sortededge_groupsedge_gens	      ``    r)   merge_edgesrR   D   s    % %%U
"3 % % % % ! F/!3 F5"24DEEU	***G#G;;;K     $	  H (+,,ELr+   wordsword_thresholdc           
         t          j        | t          d          d          }t          fd|          }t	          t          t           j        |                    }t          |          dk    rg S t          t          t          d          |                    }t          t          t          d          |                    }g }|D ]5}||||d         |d         ||z
  dd|||d	         |d	         ||z
  ddgz  }6|S )
zi
    Find (imaginary) horizontal lines that connect the tops
    of at least `word_threshold` words.
    r"   r   c                 *    t          |           k    S NlenxrT   s    r)   <lambda>z"words_to_edges_h.<locals>.<lambda>m       c!ff&> r+   r   r!   r.   r   )r!   r.   r"   r/   widthr    r/   )
r   cluster_objectsr   filterr4   mapobjects_to_rectrY   minmax)	rS   rT   by_toplarge_clustersrectsmin_x0max_x1r   rs	    `       r)   words_to_edges_hrk   e   s)    "5*U*;*;Q??F>>>>GGNU*N;;<<E
5zzQ 	Z%%u--..FZ%%u--..FE 
 
 xE(&"  {H+&" 
 	
. Lr+   c                    t          j        | t          d          d          }t          j        | t          d          d          }dt          dt          fd}t          j        | |d          }||z   |z   }t          |d           }t          fd	|          }t          t          t           j	        |                    }	g }
|	D ]4t          fd
|
D                       }|s|
                               5t          |
          dk    rg S t          t           j        |
          }t          t          |t          d                              }t          t          t          d          |                    }t          t          t          d          |                    t          t          t          d          |                    fd|D             ||z
  ddgz   S )zy
    Find (imaginary) vertical lines that connect the left, right, or
    center of at least `word_threshold` words.
    r!   r   r.   wordr   c                 D    t          | d         | d         z             dz  S )Nr!   r.      )float)rm   s    r)   
get_centerz$words_to_edges_v.<locals>.get_center   s"    T$Z$t*,--11r+   c                 "    t          |            S rW   rX   )r[   s    r)   r\   z"words_to_edges_v.<locals>.<lambda>   s    c!ffW r+   r0   c                 *    t          |           k    S rW   rX   rZ   s    r)   r\   z"words_to_edges_v.<locals>.<lambda>   r]   r+   c              3   B   K   | ]}t          j        |          V  d S rW   )r   get_bbox_overlap)rG   cbboxs     r)   rJ   z#words_to_edges_v.<locals>.<genexpr>   s0      PP!e,T155PPPPPPr+   r   r"   r/   c           	      @    g | ]}|d          |d          z
  ddS )r!   r   r!   r.   r"   r/   heightr    rD   )rG   b
max_bottommin_tops     r)   
<listcomp>z$words_to_edges_v.<locals>.<listcomp>   sQ     
 
 
  D'D'  7*	
 	

 
 
r+   r   ry   )r   r_   r   r   r   r5   r`   r4   ra   objects_to_bboxanyr#   rY   bbox_to_rectrd   rc   )rS   rT   by_x0by_x1rq   	by_centerclusterssorted_clustersrf   bboxescondensed_bboxesoverlapcondensed_rectssorted_rectsri   rw   r|   r}   s    `             @@@r)   words_to_edges_vr      s6    !%D)9)91==E!%D)9)91==E2 25 2 2 2 2 %eZ;;Iu}y(H X+<+<===O>>>>PPN #e+^<<==F &( * *PPPP?OPPPPP 	*##D)))
! 	%,.>??OJt4D4DEEEFFLZ%%|4455F#j''6677GSH--|<<==J
 
 
 
 
 
 
 
   7*	
 	
		 r+   c                     i } fddD             \  }}t          |t          dd                    D ]}t          |t          dd                    D ]}|d         |d         |z   k    r|d         |d         |z
  k    r|d         |d         |z
  k    rs|d         |d         |z   k    r^|d         |d         f}||vrg g d||<   ||         d                             |           ||         d	                             |           |S )
zi
    Given a list of edges, return the points at which they intersect
    within `tolerance` pixels.
    c                 R    g | ]"t          t          fd                     #S )c                     | d         k    S )Nr    rD   )r[   os    r)   r\   z3edges_to_intersections.<locals>.<listcomp>.<lambda>   s    a.!3 r+   )r4   r`   )rG   r   r   s    @r)   r~   z*edges_to_intersections.<locals>.<listcomp>   sC       ABV3333U;;<<  r+   r   r!   r"   r0   r/   r.   r   r   )r5   r   r#   )	r   r   r   intersectionsv_edgesh_edgesr   r   vertexs	   `        r)   edges_to_intersectionsr      sn    &(M   FP  GW GD%!8!8999 5 5Zt%<%<=== 	5 	5A5ah45
5x[QuX%;<
5 tW4;!67
5 tW4;!67	
5 D'1U8,. ?242,>,>M&)f%c*11!444f%c*11!444	5 r+   r   c                     dt           dt           dt          f fdt          t                                                               t                    dt          t                    dt          dt          t                   f fdfdt          t                              D             }t          t          d	|                    S )
a8  
    Given a list of points (`intersections`), return all rectangular "cells"
    that those points describe.

    `intersections` should be a dictionary with (x0, top) tuples as keys,
    and a list of edge objects as values. The edge objects should correspond
    to the edges that touch the intersection.
    p1p2r   c                    dt           dt          t                   fd}| d         |d         k    rP ||          d                                        ||         d                             }t	          |          rdS | d         |d         k    rP ||          d                                        ||         d                             }t	          |          rdS d	S )
Nr   r   c                 P    t          t          t          j        |                     S rW   )setra   r   obj_to_bbox)r   s    r)   edges_to_setzCintersections_to_cells.<locals>.edge_connects.<locals>.edges_to_set   s    s5,e44555r+   r   r   Tr   r   F)r   r
   r   intersectionrY   )r   r   r   commonr   s       r)   edge_connectsz-intersections_to_cells.<locals>.edge_connects   s   	6
 	6s6{ 	6 	6 	6 	6 a5BqE> 	!\-"3C"899FF]2.s344 F 6{{ ta5BqE> 	!\-"3C"899FF]2.s344 F 6{{ tur+   pointsic                 f   |dz
  k    rd S | |         | |dz   d          }fd|D             }fd|D             }|D ]o} 	|          s|D ]]} 	|          s|d         |d         f}|
v r: 	||          r. 	||          r"d         d         |d         |d         fc c S ^pd S )Nr   c                 8    g | ]}|d          d          k    |S r   rD   rG   r[   pts     r)   r~   zFintersections_to_cells.<locals>.find_smallest_cell.<locals>.<listcomp>  *    222qAaDBqEM2222r+   c                 8    g | ]}|d          d          k    |S r   rD   r   s     r)   r~   zFintersections_to_cells.<locals>.find_smallest_cell.<locals>.<listcomp>  r   r+   r   rD   )r   r   restbelowrightbelow_ptright_ptbottom_rightr   r   r   n_pointss           @r)   find_smallest_cellz2intersections_to_cells.<locals>.find_smallest_cell
  s?   1 	4AYa!egg2222D2222222D222 	L 	LH =X.. ! L L$}R22  (Xa[9 "]2L%lH==L &lH==L qE2a5,q/<?KKKKKKL tr+   c              3   0   K   | ]} |          V  d S rW   rD   )rG   r   r   r   s     r)   rJ   z)intersections_to_cells.<locals>.<genexpr>%  s1      JJ!""61--JJJJJJr+   N)r   boolr4   r5   keysrY   r   intr	   r   ranger`   )r   cell_genr   r   r   r   s   ` @@@@r)   intersections_to_cellsr      s    ' w 4      & &++--..//F6{{H4= S Xf=M        6 KJJJJuS[[7I7IJJJHtX&&'''r+   cellsc                    dt           dt          t          t          t          t          f         fd}t          |           }t	                      g }g }t          |          rFt          |          }t          |          D ]} ||          }t          |          dk    r=t	          |          z  |                    |           |                    |           ]t          fd|D                       }|dk    r<t	          |          z  |                    |           |                    |           t          |          |k    rJ|                    t          |                     	                                 |	                                 t          |          Ft          |          r"|                    t          |                     t          |d           }	d |	D             }
|
S )	z
    Given a list of bounding boxes (`cells`), return a list of tables that
    hold those cells most simply (and contiguously).
    rw   r   c                 ,    | \  }}}}||f||f||f||ffS rW   rD   )rw   r!   r"   r.   r/   s        r)   bbox_to_cornersz(cells_to_tables.<locals>.bbox_to_corners/  s/    "CVS	B<"cRLAAr+   r   c              3       K   | ]}|v V  	d S rW   rD   )rG   rv   current_cornerss     r)   rJ   z"cells_to_tables.<locals>.<genexpr>H  s(      "N"NA1#7"N"N"N"N"N"Nr+   c                 4    t          d | D                       S )Nc              3   6   K   | ]}|d          |d         fV  dS )r   r   NrD   )rG   rv   s     r)   rJ   z4cells_to_tables.<locals>.<lambda>.<locals>.<genexpr>a  s.      .G.G!ad|.G.G.G.G.G.Gr+   )rc   )ts    r)   r\   z!cells_to_tables.<locals>.<lambda>a  s    3.G.GQ.G.G.G+G+G r+   r0   c                 8    g | ]}t          |          d k    |S r   rX   )rG   r   s     r)   r~   z#cells_to_tables.<locals>.<listcomp>b  s'    111ac!ffqj1111r+   )r   r   r   r4   r   rY   r#   removesumclearr5   )r   r   remaining_cellscurrent_cellstablesinitial_cell_countcellcell_cornerscorner_countrO   filteredr   s              @r)   cells_to_tablesr   )  s#   Bf Bw'/Q)R B B B B 5kkO
 %(EEO"$MF
o

 " //)) 	1 	1D*?400L=!!Q& 13|#4#44$$T***&&t,,,,  #"N"N"N"N"N"N"NNN  !# 1#s<'8'88O!((...#**4000 }!33 	"MM$}--...!!###!!!5 o

 "> = +d=))*** V!G!GHHHG117111HOr+   c                   2    e Zd Zdeee                  fdZdS )	CellGroupr   c                    || _         t          t          t          d          t	          d |                              t          t          t          d          t	          d |                              t          t          t          d          t	          d |                              t          t          t          d          t	          d |                              f| _        d S Nr   r   ro   r   )r   rc   ra   r   r`   rd   rw   )selfr   s     r)   __init__zCellGroup.__init__g  s    
JqMM6$#6#67788JqMM6$#6#67788JqMM6$#6#67788JqMM6$#6#67788	
			r+   N)__name__
__module____qualname__r   r	   r   r   rD   r+   r)   r   r   f  s9        
d8F#34 
 
 
 
 
 
r+   r   c                       e Zd ZdS )RowNr   r   r   rD   r+   r)   r   r   q          Dr+   r   c                       e Zd Zdddee         fdZedefd            Zedee         fd            Z	de
deeee                           fd	Zd
S )Tablepager   r   c                 "    || _         || _        d S rW   )r   r   )r   r   r   s      r)   r   zTable.__init__v  s    	


r+   r   c           
      \   | j         }t          t          t          d          |                    t          t          t          d          |                    t	          t          t          d          |                    t	          t          t          d          |                    fS r   )r   rc   ra   r   rd   )r   rv   s     r)   rw   z
Table.bboxz  s    JJqMM1%%&&JqMM1%%&&JqMM1%%&&JqMM1%%&&	
 	
r+   c                    t          | j        t          dd                    }t          t          t	          t          t          d          | j                                                }g }t          j        |t          d                    D ]A\  }}d |D             t          fd|D                       }|	                    |           B|S )Nr   r   r0   c                      i | ]}|d          |S r   rD   )rG   r   s     r)   
<dictcomp>zTable.rows.<locals>.<dictcomp>  s    999tT!Wd999r+   c                 :    g | ]}                     |          S rD   )get)rG   r[   xdicts     r)   r~   zTable.rows.<locals>.<listcomp>  s#    000uyy||000r+   )
r5   r   r   r4   r   ra   rL   rM   r   r#   )r   rO   xsrowsy	row_cellsrowr   s          @r)   r   z
Table.rows  s    Aq)9)9:::&SA
;;<<==>>%-gz!}}EE 	 	LAy99y999E0000R00011CKKr+   kwargsc                   	
 | j         j        }g }dt          dt          dt          fd	| j        D ]
g }	
fd|D             }
j        D ]d }nd	fd|D             }t          |          rDd|v r-d         d	         z
  |d
<   d         d         z
  |d<   |d<   t          j	        |fi |}nd}|
                    |           |
                    |           |S )Ncharrw   r   c                     | d         | d         z   dz  }| d         | d         z   dz  }|\  }}}}t          ||k    o||k     o||k    o||k               S )Nr"   r/   ro   r!   r.   )r   )r   rw   v_midh_midr!   r"   r.   r/   s           r)   char_in_bboxz#Table.extract.<locals>.char_in_bbox  sr    %[4>1Q6E$Z$t*,1E"&BR"V52:VESLVuv~  r+   c                 6    g | ]} |j                   |S rD   )rw   )rG   r   r   r   s     r)   r~   z!Table.extract.<locals>.<listcomp>  s,    PPP$<<ch3O3OPPPPr+   c                 ,    g | ]} |          |S rD   rD   )rG   r   r   r   s     r)   r~   z!Table.extract.<locals>.<listcomp>  s:     " " "!%ll46N6N"" " "r+   layoutro   r   layout_widthr   r   layout_heightlayout_bbox )r   charsr   r   r   r   r   rY   r   extract_textr#   )r   r   r   	table_arrarr	row_chars	cell_text
cell_charsr   r   r   s           @@@r)   extractzTable.extract  sc   			u 	F 	t 	 	 	 	 9 	" 	"CCPPPPP%PPPI	 & & ' $II" " " " ")2" " "J : '#v- 959!WtAw5FF>26:1gQ6GF?348F=1$)$6z$L$LV$L$L		$&	

9%%%%S!!!!r+   N)r   r   r   r   r   r   propertyrw   r   r   r   r	   rK   r  rD   r+   r)   r   r   u  s        V DL     
f 
 
 
 X
 d3i    X$ $T(3--@(A $ $ $ $ $ $r+   r   )lineslines_stricttextexplicit)snap_tolerancer=   r>   join_tolerancer?   r@   edge_min_lengthmin_words_verticalmin_words_horizontalintersection_toleranceintersection_x_toleranceintersection_y_tolerancec                       e Zd ZdS )
UnsetFloatNr   rD   r+   r)   r  r    r   r+   r  c                      e Zd ZU dZeed<   dZeed<   dZee	e
eef                           ed<   dZee	e
eef                           ed<   eZeed<   eZeed<   eZeed	<   eZeed
<   eZeed<   eZeed<   dZeed<   eZeed<   eZeed<   dZeed<   eZeed<   eZeed<   dZ ee!ee"f                  ed<   ddZ#e$dee%         dd fd            Z&dS )r   r  vertical_strategyhorizontal_strategyNexplicit_vertical_linesexplicit_horizontal_linesr  r=   r>   r	  r?   r@   r   r
  r  r  r  r  r  text_settingsr   c           	      $   t           D ]+}t          | |          pddk     rt          d| d          ,dD ]K}t          | |dz             }|t          vr-t          | dd                    t                     d          L| j        i | _        d
D ].}|| j        vr#| j                            dd          | j        |<   /d| j        v r| j        d= dD ];\  }}t          | |          t          u rt          | |t          | |                     <| S )a  Clean up user-provided table settings.

        Validates that the table settings provided consists of acceptable values and
        returns a cleaned up version. The cleaned up version fills out the missing
        values with the default values in the provided settings.

        TODO: Can be further used to validate that the values are of the correct
            type. For example, raising a value error when a non-boolean input is
            provided for the key ``keep_blank_chars``.

        :param table_settings: User-provided table settings.
        :returns: A cleaned up version of the user-provided table settings.
        :raises ValueError: When an unrecognised key is provided.
        r   zTable setting 'z' cannot be negative)
horizontalvertical	_strategyz_strategy must be one of{,}N)r   r   r,   r   ))r=   r  )r>   r  )r?   r	  )r@   r	  )r  r  )r  r  )	NON_NEGATIVE_SETTINGSgetattrr3   TABLE_STRATEGIESjoinr  r   UNSETsetattr)r   settingr    strategyattrfallbacks         r)   __post_init__zTableSettings.__post_init__  s     - 	R 	RGg&&+!q0 R !P7!P!P!PQQQR 6 	 	Kt[;%>??H//  " 8 8"2338 8 8    	$!#D 3 	R 	RD4-- R+/+=+A+A+q+Q+Q"4($,, 	0";/
 		= 		=ND( tT""e+ =dGD($;$;<<<r+   settingsc                 $   |
 |             S t          ||           r|S t          |t                    rLi }i }|                                D ]&\  }}|d d         dk    r|||dd          <   !|||<   '||d<    | di |S t          d|           )N   text_r  zCannot resolve settings: rD   )
isinstancedictrI   r3   )clsr)  core_settingsr  rH   r   s         r)   resolvezTableSettings.resolve  s     	E355L#&& 	EO$'' 	EMM (( ) )1RaR5G# )+,M!ABB%(('(M!$$-:M/*3'''''CCCDDDr+   )r   r   )'r   r   r   r  rK   __annotations__r  r  r	   r   r   r   r   r  DEFAULT_SNAP_TOLERANCEr  r"  r=   r>   DEFAULT_JOIN_TOLERANCEr	  r?   r@   r
  DEFAULT_MIN_WORDS_VERTICALr  r   DEFAULT_MIN_WORDS_HORIZONTALr  r  r  r  r  r   r   r(  classmethodT_table_settingsr1  rD   r+   r)   r   r     s        $s$$$&&&&CGXd5+>&?@GGGEIxU5%<-@(ABIII2NE222#e####e###2NE222#e####e###OU8888 <#<<<$%E%%%&+e+++&+e+++.2M8DcN+2223 3 3 3j Ex(89 Eo E E E [E E Er+   c                   <    e Zd ZdZd	dddee         fdZdefdZdS )
TableFindera0  
    Given a PDF page, find plausible table structures.

    Largely borrowed from Anssi Nurminen's master's thesis:
    http://dspace.cc.tut.fi/dpub/bitstream/handle/123456789/21520/Nurminen.pdf?sequence=3

    ... and inspired by Tabula:
    https://github.com/tabulapdf/tabula-extractor/issues/16
    Nr   r   r)  c                 `    | _         t                              |           _                                          _        t           j         j        j         j        j                   _	        t           j	                   _         fdt           j                  D              _        d S )Nc                 :    g | ]}t          j        |          S rD   )r   r   )rG   
cell_groupr   s     r)   r~   z(TableFinder.__init__.<locals>.<listcomp>@  s2     
 
 
-7E$)Z((
 
 
r+   )r   r   r1  r)  	get_edgesr   r   r  r  r   r   r   r   r   )r   r   r)  s   `  r)   r   zTableFinder.__init__6  s    	%--h77^^%%
3JM2M2
 

 ,D,>??

 
 
 
;J4:;V;V
 
 
r+   r   c           
         | j         }dD ]Z}t          ||dz             }|dk    r?t          |d|z   dz             }t          |          dk     rt          d| d| d	          [|j        }|j        }|d
k    s|d
k    r | j        j        di |j        pi }g }|j	        pg D ]}	t          |	t                    r9t          j        |	          D ]#}
|
d         dk    r|                    |
           $P|                    |	|	| j        j        d         | j        j        d         | j        j        d         | j        j        d         z
  dd           |dk    r t          j        | j        j        d          }nM|dk    r"t          j        | j        j        dd          }n%|d
k    rt%          ||j                  }n|dk    rg }||z   }g }|j        pg D ]}	t          |	t                    r9t          j        |	          D ]#}
|
d         dk    r|                    |
           $P|                    | j        j        d         | j        j        d         | j        j        d         | j        j        d         z
  |	|	dd           |dk    r t          j        | j        j        d          }nM|dk    r"t          j        | j        j        dd          }n%|d
k    rt+          ||j                  }n|dk    rg }||z   }t/          |          t/          |          z   }t1          ||j        |j        |j        |j                  }t          j        ||j                  S )N)r  r  r  r  	explicit__linesro   zIf z"_strategy == 'explicit', explicit_zD_lines must be specified as a list/tuple of two or more floats/ints.r  r    r   r   r   ry   r  r  line)	edge_type)rT   r   r   )r!   r.   r^   r"   r/   r    )r=   r>   r?   r@   )
min_lengthrD   )r)  r  rY   r3   r  r  r   extract_wordsr  r  r-  r.  r   obj_to_edgesr#   rw   filter_edgesr   r   r  r  rk   r  r4   rR   r=   r>   r?   r@   r
  )r   r)  r    r%  r  v_strath_stratrS   
v_explicitdescr&   v_baser   
h_explicith_baser   r   s                    r)   r>  zTableFinder.get_edgesD  s$   =5 
	 
	Kx{)BCCH:% +*Ch*NOOu::> $(k ( ($/( ( (   ,.f 	N6 1 	N+DI+MMx/E/KMME
4: 	 	D$%% +D11 - -A'3. -"))!,,,- !!""#y~a0"&)."3"&)."3dinQ6G"G'* 	 	 	 	 g 	'	==FF& 	'	OOOFF 	%eH<WXXXFF
" 	FZ
6<" 	 	D$%% +D11 - -A'3. -"))!,,,- !!"inQ/"inQ/!%!2TY^A5F!F#"&'* 	 	 	 	 g 		'	==FF& 	'	OOOFF 	%h&C  FF 
" 	FZQ$q''!%6%6%6%6
 
 
 !%H4LMMMMr+   rW   )	r   r   r   __doc__r	   r8  r   r   r>  rD   r+   r)   r:  r:  +  st         
 
V 
x8H/I 
 
 
 
[N: [N [N [N [N [N [Nr+   r:  )r   r   )4rL   dataclassesr   operatorr   typingr   r   r   r   r	   r
   r   r   r   r   _typingr   r   r   r   r   r   r3  r4  r5  r6  rK   T_intersectionsr8  r   r   r*   r<   rR   r   rk   r   r   r   r   objectr   r   r   r   r  rp   r  r"  r   r:  rD   r+   r)   <module>rV     sS       ! ! ! ! ! !       N N N N N N N N N N N N N N N N N N N N       J J J J J J J J J J J J J J J J     wS*_ 556$sCx.89  
 0/! !!! ! 	! ! ! !& =S $'49   :  	
     D .J( (('*(( ( ( (X .H< <<'*<< < < <@ EF $)<A   6<(/ <(d6l <( <( <( <(~:4< :Df,> : : : :z
 
 
 
 
 
 
 
	 	 	 	 	) 	 	 	> > > > >F > > >B A@@     	 	 	 	 	 	 	 	 	
1 YE YE YE YE YE YE YE YExtN tN tN tN tN& tN tN tN tN tNr+   