§
    �Øj]ˆ  ã                   ó¾  — d dl mZ d dlZd dlZd dlmZ d dlmZ dZ e	d„  e
d¦  «        D ¦   «         g d¢z   ¦  «        Z ed	¦  «        Zd
Z e ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «        eh e	 ee e
dd¦  «        ¦  «        ¦  «        z  ¦  «        Zd ej        z  ej        z  ej        z  ej        z  ej        z  ej        z  Zd>d!„Zd"ed#ed$efd%„Zd&„ Zd$efd'„Zd$efd(„Zd$efd)„Z d>d*„Z!d>d+„Z"d?d-„Z#d>d$efd.„Z$d$efd/„Z%d0„ Z&d1„ Z'd2„ Z(d3„ Z)	 d@d5„Z*d6„ Z+d@d7„Z,d@d8e-d$e.fd9„Z/d:„ Z0d;„ Z1dAd<„Z2d=„ Z3dS )Bé    )ÚPathN)Úmupdf)Úanalyze_pageÚGlyphLessFontc                 ó,   — g | ]}t          |¦  «        ‘ŒS © )Úchr©Ú.0Úis     úŽ/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/pymupdf4llm/helpers/utils.pyú
<listcomp>r   
   s   € ÐÐÐ�…Sˆ�V„VÐÐÐó    é!   )õ   Â u   â€€u   â€�u   â€‚u   â€ƒu   â€„u   â€…u   â€†u   â€‡u   â€ˆu   â€‰u   â€Šu   â€¯u   â�Ÿu   ã€€iýÿ  ÚType3é*   é-   é>   éo   é¶   é·   é   é   é   é   é   é   i    i!   i"   é"  i"  i§ð  i·ð  i %  i &  Fc                 ó  ‡‡‡‡	— i Š	 t          j        | ¦  «        }n# t          $ r}‰cY d}~S d}~ww xY wt          j        t          j        |¦  «        t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        ¦  «        }|                     ¦   «         s‰S d„ | D ¦   «         Šdˆˆˆ	ˆfd„	Š	t          |                     ¦   «         ¦  «        D ]"}| 	                    |¦  «        } ‰	|¦  «         Œ#‰S )	zº
    Traverse /AcroForm/Fields hierarchy and return a dict:
    fully qualified field name -> {"field_value": ..., "pages": [...]}
    Optionally, the xref of the field is included.
    NÚRootÚAcroFormÚFieldsc                 ó(   — i | ]}|j         |j        “ŒS r   )ÚxrefÚnumber)r   Úpages     r   ú
<dictcomp>z2extract_form_fields_with_pages.<locals>.<dictcomp>`   s   € Ð9Ð9Ð9¨T�$”)˜Tœ[Ð9Ð9Ð9r   Ú c                 ó  •— |                       ¦   «         }|                      t          j        d¦  «        ¦  «        }|                     ¦   «         }|sd S |r|› d|› �n|}t          j        | ¦  «        t
          j        k    r#t          j        | ¦  «        t
          j	        z  rd S |                      t          j        d¦  «        ¦  «        }| 
                    ¦   «         r|                     ¦   «         }n|r|                     ¦   «         nd}g }d}	|                      t          j        d¦  «        ¦  «        }
|
                     ¦   «         rìt          |
                     ¦   «         ¦  «        D ]Ê}|
                     |¦  «        }|                     t          j        d¦  «        ¦  «        }|                     ¦   «         }|rd}	 ‰||¦  «         Œc|                     t          j        d¦  «        ¦  «        }|                      ¦   «         }|‰v r(|                     ‰                     |¦  «        ¦  «         ŒË|
                     ¦   «         sg|                      t          j        d¦  «        ¦  «        }|                      ¦   «         }|‰v r(|                     ‰                     |¦  «        ¦  «         |t%          t'          |¦  «        ¦  «        d	œ}‰r||d
<   |	|d<   ‰                     |¦  «        }|€|‰|<   d S ‰r)|d
         }t)          |t*          ¦  «        r|n|g|gz   |d
<   t%          t'          |d         ¦  «        t'          |¦  «        z  ¦  «        |d<   |d         o|	|d<   |d         dv r|dvr	||d<   d S d S d S )NÚTú.ÚVr)   TÚKidsFÚP)Úfield_valueÚpagesr%   Úterminalr1   r0   )Nr)   ÚOff)Ú
pdf_to_numÚpdf_dict_getÚpymupdfÚPDF_NAMEÚpdf_to_text_stringr   Úpdf_field_typeÚPDF_WIDGET_TYPE_BUTTONÚpdf_field_flagsÚPDF_BTN_FIELD_IS_PUSHBUTTONÚpdf_is_nameÚpdf_to_nameÚpdf_is_arrayÚrangeÚpdf_array_lenÚpdf_array_getÚappendÚgetÚsortedÚsetÚ
isinstanceÚlist)ÚfieldÚprefixÚ
field_xrefÚname_xÚnameÚfq_nameÚvalue_xÚvaluer1   r2   Úkidsr   ÚkidÚ
kid_name_xÚkid_nameÚpage_xref_xÚ	page_xrefÚ
page_ref_xÚ
value_dictÚexistingÚex_xrefÚ
page_xrefsÚresultÚ
walk_fieldÚxrefss                        €€€€r   r]   z2extract_form_fields_with_pages.<locals>.walk_fieldb   sÎ  ø€ à×%Ò%Ñ'Ô'ˆ
Ø×#Ò#¥GÔ$4°SÑ$9Ô$9Ñ:Ô:ˆØ×(Ò(Ñ*Ô*ˆØð 	ØˆFØ(.Ð8�VÐ$Ð$˜dÐ$Ð$Ð$°Dˆõ Ô Ñ&Ô&­%Ô*FÒFÐFÝÔ! %Ñ(Ô(­5Ô+LÑLð Gð ˆFð ×$Ò$¥WÔ%5°cÑ%:Ô%:Ñ;Ô;ˆØ×ÒÑ Ô ð 	DØ×'Ò'Ñ)Ô)ˆEˆEà4;ÐC�G×.Ò.Ñ0Ô0Ð0ÀˆEð ˆØˆØ×!Ò!¥'Ô"2°6Ñ":Ô":Ñ;Ô;ˆØ×ÒÑÔð 	@Ý˜4×-Ò-Ñ/Ô/Ñ0Ô0ð @ð @�Ø×(Ò(¨Ñ+Ô+�Ø ×-Ò-­gÔ.>¸sÑ.CÔ.CÑDÔD�
Ø%×8Ò8Ñ:Ô:�Øð @ð  %�HØ�J˜s GÑ,Ô,Ð,Ð,ð #&×"2Ò"2ÝÔ(¨Ñ-Ô-ñ#ô #�Kð !,× 6Ò 6Ñ 8Ô 8�IØ  JÐ.Ð.ØŸš Z§^¢^°IÑ%>Ô%>Ñ?Ô?Ð?øð ×!Ò!Ñ#Ô#ð 	8Ø×+Ò+­GÔ,<¸SÑ,AÔ,AÑBÔBˆJØ"×-Ò-Ñ/Ô/ˆIØ˜JÐ&Ð&Ø—’˜ZŸ^š^¨IÑ6Ô6Ñ7Ô7Ð7ð &+µV½CÀ¹J¼JÑ5GÔ5GÐHÐHˆ
Øð 	,Ø!+ˆJ�vÑØ!)ˆ
�:Ñà—:’:˜gÑ&Ô&ˆØÐØ(ˆF�7‰OˆOˆOð
 ð !Ø" 6Ô*�å)¨'µ4Ñ8Ô8ÐG�G�G¸w¸iØ�Lñ$!�˜Ñ õ !'¥s¨8°GÔ+<Ñ'=Ô'=ÅÀEÁ
Ä
Ñ'JÑ KÔ KˆH�WÑØ#+¨JÔ#7Ð#D¸HˆH�ZÑ Ø˜Ô&Ð*;Ð;Ð;Àð Nð Að Að
 +0�˜Ñ'Ð'Ð'ð <Ð;ð Að Ar   )r)   )
r6   Ú_as_pdf_documentÚ	Exceptionr   Úpdf_dict_getlÚpdf_trailerr7   rA   r@   rB   )
Údocr^   ÚpdfdocÚeÚfieldsr   rI   r[   r\   r]   s
    `     @@@r   Úextract_form_fields_with_pagesrg   G   sS  øøøø€ ð €FðÝÔ)¨#Ñ.Ô.ˆˆøÝð ð ð ØˆˆˆˆˆˆøøøøðøøøåÔ ÝÔ˜&Ñ!Ô!ÝÔ˜Ñ Ô ÝÔ˜Ñ$Ô$ÝÔ˜Ñ"Ô"ñ	ô €Fð ×ÒÑ!Ô!ð àˆð :Ð9°SÐ9Ñ9Ô9€JðP0ð P0ð P0ð P0ð P0ð P0ð P0ð P0ð P0õd �6×'Ò'Ñ)Ô)Ñ*Ô*ð ð ˆØ×$Ò$ QÑ'Ô'ˆØˆ
�5ÑÔÐÐà€Ms   ˆ �
3§.¨3®3ÚfolderÚfilenameÚreturnc                 ó`  — t          j        ¦   «         }|                      ¦   «         dk    r|}n3t          | ¦  «                             ¦   «                              ¦   «         }|                     dd¬¦  «         |t          |¦  «        j        z  }	 |                     |¦  «        }|                     ¦   «         }n$# t          $ r |                     ¦   «         }Y nw xY w| 
                    dd¦  «         
                    dd¦  «         
                    dd¦  «         
                    dd¦  «         
                    d	d
¦  «         
                    t          d¦  «        d¦  «         
                    t          d¦  «        d¦  «         
                    t          d¦  «        d¦  «         
                    t          d¦  «        d¦  «         
                    t          d¦  «        d¦  «         
                    t          d¦  «        d¦  «         
                    t          d¦  «        d¦  «        }||fS )zÏ
    Normalize a folder path ("" = script folder), ensure it exists,
    and return a Markdown-safe file reference using forward slashes.
    Prefers relative paths to avoid Windows drive-letter issues.
    r)   T)ÚparentsÚexist_okú(ú-ú)ú[ú]ú Ú_r   r   r   r   r   r   r   )r   ÚcwdÚstripÚ
expanduserÚresolveÚmkdirrM   Úrelative_toÚas_posixÚ
ValueErrorÚreplacer	   )rh   ri   Ú
script_dirÚbaseÚ	full_pathÚrelÚmd_refs          r   Úmd_pathrƒ   »   sÃ  € õ ”‘”€Jà‡|‚|�~„~˜ÒÐØˆˆå�F‰|Œ|×&Ò&Ñ(Ô(×0Ò0Ñ2Ô2ˆð 	‡J‚J�t d€JÑ+Ô+Ð+ð •t˜H‘~”~Ô*Ñ*€Ið&Ø×#Ò# JÑ/Ô/ˆØ—’‘”ˆˆøÝð &ð &ð &à×#Ò#Ñ%Ô%ˆˆˆð&øøøð
 	�Š�s˜CÑ Ô ß	Š��cÑ	Ô	ß	Š��cÑ	Ô	ß	Š��cÑ	Ô	ß	Š��cÑ	Ô	ß	Š•�V‘”˜cÑ	"Ô	"ß	Š•�V‘”˜cÑ	"Ô	"ß	Š•�V‘”˜cÑ	"Ô	"ß	Š•�V‘”˜cÑ	"Ô	"ß	Š•�V‘”˜cÑ	"Ô	"ß	Š•�V‘”˜cÑ	"Ô	"ß	Š•�V‘”˜cÑ	"Ô	"ð ð �6ˆ>Ðs   Â)B; Â;CÃCc                 óˆ   — | r|                       t          ¦  «        sdS t          | ¦  «        dk    rdS | d         dk    rdS dS )z-Check if text starts with a bullet character.Fé   Trs   )Ú
startswithÚBULLETSÚlen©Útexts    r   Ústartswith_bulletr‹   è   sM   € àð �t—’¥wÑ/Ô/ð ØˆuÝ
ˆ4�y„y�A‚~€~ØˆtØˆA„w�#‚~€~ØˆtØˆ5r   c                 ó˜   — | d         t           k    rdS | d         t          j        j        z  s| d         t          j        j        z  rdS dS )a¶  Check if text span was created by some OCR engine.

    This is a simplified check: We actually return whether the text was neither
    stroked nor filled. This corresponds to PDF text rendering mode 3, which
    is typically used for OCR text layers. Strictly speaking it can also be
    used for other purposes than OCR. In rare cases some OCR engines might
    use other techniques to ensure the generated text layer is invisible.
    ÚfontTÚ
char_flagsF)ÚTESSERACT_FONT_NAMEr6   r   ÚFZ_STEXT_STROKEDÚFZ_STEXT_FILLED)Úspans    r   Úis_ocr_textr“   ó   sS   € ð ˆF„|Õ*Ò*Ð*àˆtØˆ\Ô�Wœ]Ô;Ñ;ð Øˆ\Ô�Wœ]Ô:Ñ:ðð ˆuØˆ4r   c                 ó6   — t                                | ¦  «        S )zIdentify white text.)ÚWHITE_CHARSÚ
issupersetr‰   s    r   Úis_whiter—     s   € å×!Ò! $Ñ'Ô'Ð'r   c                 óJ   — | d         | d         k    p| d         | d         k    S )Nr   é   r…   é   r   )Úbboxs    r   Úbbox_is_emptyrœ     s'   € Ø�Œ7�d˜1”gÒÐ3  a¤¨D°¬GÒ!3Ð3r   c                 ó  — t          | d         |d         ¦  «        t          | d         |d         ¦  «        t          | d         |d         ¦  «        t          | d         |d         ¦  «        f}|r|nt          j        |Ž S )Nr   r…   r™   rš   )ÚmaxÚminr6   ÚRect)Úr1Úr2Ú	bbox_onlyr›   s       r   Úintersect_rectsr¤     sq   € Ý��1”�r˜!”uÑÔ�s 2 a¤5¨"¨Q¬%Ñ0Ô0µ#°b¸´e¸RÀ¼UÑ2CÔ2CÅSÈÈAÌÐPRÐSTÔPUÑEVÔEVÐW€DØÐ5ˆ4ˆ4¥'¤,°Ð"5Ð5r   c                 óv  — | s5|r t          t          j        ¦   «         ¦  «        nt          j        ¦   «         S t          d„ | D ¦   «         ¦  «        }t          d„ | D ¦   «         ¦  «        }t	          d„ | D ¦   «         ¦  «        }t	          d„ | D ¦   «         ¦  «        }|r||||fnt          j        ||||¦  «        S )z8Join a list of rectangles into their bounding rectangle.c              3   ó&   K  — | ]}|d          V — ŒdS ©r   Nr   ©r   Úrs     r   ú	<genexpr>zjoin_rects.<locals>.<genexpr>  ó&   è è € Ð!Ð!�aˆQˆqŒTÐ!Ð!Ð!Ð!Ð!Ð!r   c              3   ó&   K  — | ]}|d          V — ŒdS ©r…   Nr   r¨   s     r   rª   zjoin_rects.<locals>.<genexpr>  r«   r   c              3   ó&   K  — | ]}|d          V — ŒdS ©r™   Nr   r¨   s     r   rª   zjoin_rects.<locals>.<genexpr>  r«   r   c              3   ó&   K  — | ]}|d          V — ŒdS ©rš   Nr   r¨   s     r   rª   zjoin_rects.<locals>.<genexpr>  r«   r   )Útupler6   Ú
EMPTY_RECTrŸ   rž   r    )Úrectsr£   Úx0Úy0Úx1Úy1s         r   Ú
join_rectsr¹     sÎ   € àð RØ.7ÐQ�u•WÔ'Ñ)Ô)Ñ*Ô*Ð*½WÔ=OÑ=QÔ=QÐQÝ	Ð!Ð!˜5Ð!Ñ!Ô!Ñ	!Ô	!€BÝ	Ð!Ð!˜5Ð!Ñ!Ô!Ñ	!Ô	!€BÝ	Ð!Ð!˜5Ð!Ñ!Ô!Ñ	!Ô	!€BÝ	Ð!Ð!˜5Ð!Ñ!Ô!Ñ	!Ô	!€BØ(ÐJˆB��B˜ÐÐ­g¬l¸2¸rÀ2ÀrÑ.JÔ.JÐJr   ç333333ã?c                 ó¼  — t          | d         |d         ¦  «        t          | d         |d         ¦  «        t          | d         |d         ¦  «        t          | d         |d         ¦  «        g}t          d|d         |d         z
  ¦  «        t          d|d         |d         z
  ¦  «        z  }| d         | d         z
  | d         | d         z
  z  }|||z  k    rdS dS )Nr   r…   r™   rš   TF©rž   rŸ   )r›   ÚclipÚportionÚ	intersectÚ
inter_areaÚbox_areas         r   Úalmost_in_bboxrÂ     sÞ   € åˆD�ŒG�T˜!”WÑÔÝˆD�ŒG�T˜!”WÑÔÝˆD�ŒG�T˜!”WÑÔÝˆD�ŒG�T˜!”WÑÔð	€Iõ �Q˜	 !œ y°¤|Ñ3Ñ4Ô4µsØ	ˆ9�QŒ<˜) Aœ,Ñ&ñ8ô 8ñ €Jð �Q”˜$˜qœ'Ñ! d¨1¤g°°Q´Ñ&7Ñ8€HØ�X Ñ'Ò'Ð'ØˆtØˆ5r   c                 ó*  — |sI	 | d         |d         k    p5| d         |d         k    p#| d         |d         k    p| d         |d         k    S 	 | d         |d         k    p5| d         |d         k     p#| d         |d         k    p| d         |d         k     S )z"Check if 'bbox' is outside 'cell'.r   r™   r…   rš   r   )r›   ÚcellÚstricts      r   Úare_disjointrÆ   /  sÄ   € àð 
ð"Ø�AŒw˜$˜qœ'Ò!ð"à�AŒw˜$˜qœ'Ò!ð"ð �AŒw˜$˜qœ'Ò!ð"ð �AŒw˜$˜qœ'Ò!ð	
ð!Ø�AŒw˜˜aœÒ ð!à�AŒw˜˜aœÒ ð!ð �AŒw˜˜aœÒ ð!ð �AŒw˜˜aœÒ ð	
r   c                 ó”   — 	 |d         | d         k    o5|d         | d         k    o#|d         | d         k    o|d         | d         k    S )zACheck if 'inner' rectangle is contained within 'outer' rectangle.r…   r   r™   rš   r   ©ÚinnerÚouters     r   Úbbox_in_bboxrË   D  s_   € ð	!Ø�!ŒH˜˜aœÒ ð	!à�!ŒH˜˜aœÒ ð	!ð �!ŒH˜˜aœÒ ð	!ð �!ŒH˜˜aœÒ ðr   c                 ó~  — |s| S t          t          d„ |D ¦   «         ¦  «        | d         ¦  «        }t          t          d„ |D ¦   «         ¦  «        | d         ¦  «        }t          t          d„ |D ¦   «         ¦  «        | d         ¦  «        }t          t          d„ |D ¦   «         ¦  «        | d         ¦  «        }||||fS )	z&Expand 'bbox' to include all 'points'.c              3   ó&   K  — | ]}|d          V — ŒdS r§   r   ©r   Úps     r   rª   z(expand_bbox_by_points.<locals>.<genexpr>S  ó&   è è € Ð&Ð&˜!��1”Ð&Ð&Ð&Ð&Ð&Ð&r   r   c              3   ó&   K  — | ]}|d          V — ŒdS r­   r   rÎ   s     r   rª   z(expand_bbox_by_points.<locals>.<genexpr>T  rÐ   r   r…   c              3   ó&   K  — | ]}|d          V — ŒdS r§   r   rÎ   s     r   rª   z(expand_bbox_by_points.<locals>.<genexpr>U  rÐ   r   r™   c              3   ó&   K  — | ]}|d          V — ŒdS r­   r   rÎ   s     r   rª   z(expand_bbox_by_points.<locals>.<genexpr>V  rÐ   r   rš   )rŸ   rž   )r›   Úpointsrµ   r¶   r·   r¸   s         r   Úexpand_bbox_by_pointsrÕ   O  sÆ   € àð ØˆÝ	�SÐ&Ð&˜vÐ&Ñ&Ô&Ñ&Ô&¨¨Q¬Ñ	0Ô	0€BÝ	�SÐ&Ð&˜vÐ&Ñ&Ô&Ñ&Ô&¨¨Q¬Ñ	0Ô	0€BÝ	�SÐ&Ð&˜vÐ&Ñ&Ô&Ñ&Ô&¨¨Q¬Ñ	0Ô	0€BÝ	�SÐ&Ð&˜vÐ&Ñ&Ô&Ñ&Ô&¨¨Q¬Ñ	0Ô	0€BØ��B˜ÐÐr   c           	      óÒ  — t          dt          | d         |d         ¦  «        t          | d         |d         ¦  «        z
  ¦  «        }t          dt          | d         |d         ¦  «        t          | d         |d         ¦  «        z
  ¦  «        }||z  }|sdS | d         | d         z
  | d         | d         z
  z  }|d         |d         z
  |d         |d         z
  z  }|||z   |z
  z  S )z2Compute intersection over union of two rectangles.r   r™   rš   r…   r¼   )r¡   r¢   ÚixÚiyÚintersectionÚarea1Úarea2s          r   ÚiourÜ   Z  sà   € å	ˆQ•�B�q”E˜2˜aœ5Ñ!Ô!¥C¨¨1¬¨r°!¬uÑ$5Ô$5Ñ5Ñ	6Ô	6€BÝ	ˆQ•�B�q”E˜2˜aœ5Ñ!Ô!¥C¨¨1¬¨r°!¬uÑ$5Ô$5Ñ5Ñ	6Ô	6€BØ˜‘7€LØð ØˆqØ�ŒU�R˜”U‰]˜r !œu r¨!¤u™}Ñ-€EØ�ŒU�R˜”U‰]˜r !œu r¨!¤u™}Ñ-€EØ˜5 5™=¨<Ñ7Ñ8Ð8r   c                 óV  ‡‡— d„ | j         D ¦   «         }t          t          |¦  «        ¦  «        D ]øŠ| j         ‰         d         dvrŒt          j        | j         ‰         dd…         ¦  «        }|D ]Š}|d         dvrŒt          j        |d         ¦  «        Š|d         dk    rt          ‰¦  «        r‰d	z  Š|                     ‰¦  «        r.t          ˆˆfd
„t          |¦  «        D ¦   «         ¦  «        s|‰z  }Œ‹t          |¦  «        | j         ‰         d         gz   | j         ‰<   ŒùdS )z¨Extend picture / formula / table bboxes.

    Join layout boxes with intersecting text, image, vectors.

    'blocks' is the TextPage.extractDict()["blocks"] list.
    c                 óF   — g | ]}t          j        |d d…         ¦  «        ‘ŒS ©Né   ©r6   r    ©r   Úbs     r   r   z"clean_pictures.<locals>.<listcomp>n  ó*   € ÐGÐGÐG¨!•'”,˜q  ! œuÑ%Ô%ÐGÐGÐGr   rà   )ÚpictureÚformulaNÚtype)r   r…   rš   r›   rš   )éÿÿÿÿrè   r…   r…   c              3   óT   •K  — | ]"\  }}|‰k    ¯|                      ‰¦  «        V — Œ#d S ©N©Ú
intersects)r   ÚjÚbbÚ
block_bboxr   s      €€r   rª   z!clean_pictures.<locals>.<genexpr>}  sH   øè è € ð 7ð 7Ù.3¨a°ÐPQÐUVÒPVÐPV�—’˜jÑ)Ô)ÐPVÐPVÐPVÐPVð7ð 7r   )Úlayout_informationr@   rˆ   r6   r    ÚIRectrœ   rì   ÚanyÚ	enumeraterH   )r'   ÚblocksÚ
all_bboxesr›   rã   rï   r   s        @@r   Úclean_picturesrö   f  sm  øø€ ð HÐG¨tÔ/FÐGÑGÔG€Jå•3�z‘?”?Ñ#Ô#ð Rð RˆØÔ" 1Ô% aÔ(Ð0FÐFÐFàõ Œ|˜DÔ3°AÔ6°r¸°rÔ:Ñ;Ô;ˆØð 		#ð 		#ˆAØ�Œy 	Ð)Ð)ØÝ œ q¨¤yÑ1Ô1ˆJØ�Œy˜AŠ~ˆ~¥-°
Ñ";Ô";ˆ~Ø˜nÑ,�
Ø�Š˜zÑ*Ô*ð #µ3ð 7ð 7ð 7ð 7ð 7Ý7@ÀÑ7LÔ7Lð7ñ 7ô 7ñ 4ô 4ð #ð ˜
Ñ"�øÝ%)¨$¡Z¤Z°4Ô3JÈ1Ô3MÈaÔ3PÐ2QÑ%QˆÔ Ñ"Ð"ð#Rð Rr   c                 ó¤  ‡ ‡
‡‡‡— d„ ‰ j         D ¦   «         }t          ‰ j        ¦  «        dz  }g }|D ]y}|d         dk    rŒt          ‰ j        |d         ¦  «        Š‰j        dk    s‰j        dk    rŒAt          ‰¦  «        st          ‰¦  «        |k    rŒd|                     ‰¦  «         Œzg }t          ˆ fd„|D ¦   «         d„ d	¬
¦  «        }|dd…         }|D ]‹Št          ‰¦  «        |k    rŒdt          ‰¦  «        z  Šdt          ‰¦  «        z  Št          ˆˆfd„|D ¦   «         ¦  «        rŒWt          ˆˆfd„|D ¦   «         ¦  «        rŒt|                     d‰i¦  «         ŒŒ‰  
                    |dd¬¦  «        }d„ |D ¦   «         }t          ||z   d„ d	¬
¦  «        }|dd…         }g }	|D ]2Št          ˆfd„|	D ¦   «         ¦  «        s|	                     ‰¦  «         Œ3|	D ]mŠt          ‰¦  «        Š
t          ˆ
ˆfd„|D ¦   «         ¦  «        s@‰ j                              t          ‰¦  «        dgz   ¦  «         |                     ‰¦  «         ŒndS )zvAdd orphan images as layout boxes of class 'picture'.

    'blocks' is the TextPage.extractDict()["blocks"] list.
    c                 óF   — g | ]}t          j        |d d…         ¦  «        ‘ŒS rß   rá   râ   s     r   r   z%add_image_orphans.<locals>.<listcomp>Š  rä   r   gÍÌÌÌÌÌì?rç   r…   r›   rš   c                 óâ   •— g | ]k}|d          dk    r]|d         d         |d         d         z
  dk    r<|d         d         |d         d         z
  dk    ¯Pt          ‰j        |d         ¦  «        ‘ŒlS )rç   rš   r›   r…   r™   r   )r¤   Úrect)r   rã   r'   s     €r   r   z%add_image_orphans.<locals>.<listcomp>š  s‚   ø€ ð 	
ð 	
ð 	
àØ�Œy˜AŠ~ˆ~Ø�&”	˜!”˜q œy¨œ|Ñ+¨aÒ/Ð/Ø�&”	˜!”˜q œy¨œ|Ñ+¨aÒ/Ð/õ	 ˜DœI q¨¤yÑ1Ô1ð 0Ð/Ð/r   c                 ó    — t          | ¦  «        S rê   ©Úabs)Úvs    r   ú<lambda>z#add_image_orphans.<locals>.<lambda>¡  s   € •c˜!‘f”f€ r   T©ÚkeyÚreverseNiô  çš™™™™™¹?gš™™™™™é?c              3   ó–   •K  — | ]C}t          t          ‰|¦  «        ¦  «        t          ‰t          |¦  «        d z  ¦  «        k    V — ŒDdS ©r  N©rý   r¤   rŸ   )r   rî   r©   Úr_low_limits     €€r   rª   z$add_image_orphans.<locals>.<genexpr>®  sb   øè è € ð 
ð 
àõ •  2Ñ&Ô&Ñ'Ô'­#¨k½3¸r¹7¼7ÀS¹=Ñ*IÔ*IÒIð
ð 
ð 
ð 
ð 
ð 
r   c              3   óZ   •K  — | ]%}t          t          ‰|¦  «        ¦  «        ‰k    V — Œ&d S rê   )rý   r¤   )r   r   r©   Ú
r_hi_limits     €€r   rª   z$add_image_orphans.<locals>.<genexpr>´  s:   øè è € ÐGÐG¸1�s•? 1 aÑ(Ô(Ñ)Ô)¨JÒ6ÐGÐGÐGÐGÐGÐGr   rú   é   )ÚdrawingsÚx_toleranceÚy_tolerancec                 ó>   — g | ]}|j         d k    ¯|j        d k    ¯|‘ŒS )é   )ÚwidthÚheight)r   rþ   s     r   r   z%add_image_orphans.<locals>.<listcomp>º  s)   € ÐDÐDÐD�Q Q¤W¨r¢\ \°a´hÀ²m°mˆq°m°m°mr   c                 ó    — t          | ¦  «        S rê   rü   ©r©   s    r   rÿ   z#add_image_orphans.<locals>.<lambda>½  s   € µ#°a±&´&€ r   c              3   ó8   •K  — | ]}t          ‰|¦  «        V — Œd S rê   )rË   )r   Úfrr©   s     €r   rª   z$add_image_orphans.<locals>.<genexpr>Á  s-   øè è € Ð?Ð?¨2•<  2Ñ&Ô&Ð?Ð?Ð?Ð?Ð?Ð?r   c           	   3   ó–   •K  — | ]C}t          t          ‰|¦  «        ¦  «        d t          ‰t          |¦  «        ¦  «        z  k    V — ŒDdS r  r  )r   r›   Úabs_rr©   s     €€r   rª   z$add_image_orphans.<locals>.<genexpr>Ç  sc   øè è € ð 
ð 
àõ •  4Ñ(Ô(Ñ)Ô)¨Cµ#°e½SÀ¹Y¼YÑ2GÔ2GÑ,GÒGð
ð 
ð 
ð 
ð 
ð 
r   rå   )rð   rý   rú   r¤   r  r  rœ   rC   rE   rò   Úcluster_drawingsrH   )r'   rô   rõ   Ú
area_limitÚimagesrã   ÚpathsÚvectorsÚimgsÚfiltered_imgsr  r©   r	  r  s   `         @@@@r   Úadd_image_orphansr  „  s  øøøøø€ ð HÐG¨tÔ/FÐGÑGÔG€JÝ�T”Y‘” #Ñ%€JØ€FØð 	ð 	ˆØˆVŒ9˜Š>ˆ>ØÝ˜DœI q¨¤yÑ1Ô1ˆàŒ7�aŠ<ˆ<˜1œ8 qš=˜=ØÝ˜ÑÔð 	�s 1™vœv¨Ò3Ð3ØØ�Š�aÑÔÐÐà€EÝð	
ð 	
ð 	
ð 	
àð	
ñ 	
ô 	
ð ÐØð
ñ 
ô 
€Gð �d�s�dŒm€Gàð "ð "ˆÝˆq‰6Œ6�ZÒÐØØ�C ™FœF‘lˆØ�3˜q™6œ6‘\ˆ
õ ð 
ð 
ð 
ð 
ð 
à ð
ñ 
ô 
ñ 
ô 
ð 	ð åÐGÐGÐGÐGÐGÀÐGÑGÔGÑGÔGð 	ØØ�Š�f˜a�[Ñ!Ô!Ð!Ð!ð ×#Ò#¨UÀÐPRÐ#ÑSÔS€GØDÐD˜'ÐDÑDÔD€Gõ �&˜7Ñ"Ð(8Ð(8À$ÐGÑGÔG€DØ���Œ:€DØ€MØð $ð $ˆÝÐ?Ð?Ð?Ð?°Ð?Ñ?Ô?Ñ?Ô?ð 	$Ø× Ò  Ñ#Ô#Ð#øàð !ð !ˆå�A‘”ˆÝð 
ð 
ð 
ð 
ð 
à"ð
ñ 
ô 
ñ 
ô 
ð 	!ð Ô#×*Ò*­4°©7¬7°i°[Ñ+@ÑAÔAÐAØ×Ò˜aÑ Ô Ð øØ
€Fr   é   c                 ó   ‡— d„ }d„ }| s| S t          | d„ ¬¦  «        }g } || ¦  «        r| gS |j        h}|D ]Æ}	|	d         }
|
|j        k    rŒ ||
||¦  «        Št          ˆfd„| D ¦   «         ¦  «        sˆt          ˆfd„|D ¦   «         d¬	¦  «        }|€Œ^|‰_        d
}|D ]<}‰                     |¦  «        r%|j        ‰j        k    r‰j        |j        k    r|dz  }Œ=|dk    r|                     ‰j        ¦  «         ŒÇt          |¦  «        }g }|D ]k}
|rN|d
         d         |
k    r<|                     |                     d
¦  «        ¦  «         |r|d
         d         |
k    °<|r|                     |¦  «         g }Œl|S )aŒ  
    Divide page into horizontal stripes based on vertical gaps.

    Args:
        boxes (list): List of bounding boxes.
        joined_boxes: rectangle containing all boxes
        vectors: boxes of significant vector graphics
        vertical_gap (float): Minimum vertical gap to separate stripes.

    Returns:
        List of disjoint horizontal stripes. Each stripe is a list of boxes.
    c                 óR  — t          | d„ ¬¦  «        }g }|d         g}|dd…         D ]X}t          d„ |D ¦   «         ¦  «        }|d         |z
  dk    r|                     |¦  «         |g}ŒC|                     |¦  «         ŒY|                     |¦  «         t          |¦  «        dk    S )z¥Check if the boxes have a clean multi-column layout.

        If False, the boxes represent only 1 column
        Used to early exit from stripe clustering.
        c                 ó   — | d         S ©Nr   r   ©rã   s    r   rÿ   zAcluster_stripes.<locals>.is_multi_column_layout.<locals>.<lambda>î  s
   € °1°Q´4€ r   ©r  r   r…   Nc                 ó   — g | ]
}|d          ‘ŒS ©r™   r   râ   s     r   r   zCcluster_stripes.<locals>.is_multi_column_layout.<locals>.<listcomp>ò  ó   € Ð;Ð;Ð; q˜a œdÐ;Ð;Ð;r   rš   )rE   rž   rC   rˆ   )ÚboxesÚsorted_boxesÚcolumnsÚcurrent_columnÚboxÚ
prev_rights         r   Úis_multi_column_layoutz/cluster_stripes.<locals>.is_multi_column_layoutè  sÆ   € õ ˜e¨¨Ð8Ñ8Ô8ˆØˆØ& qœ/Ð*ˆØ   Ô#ð 	+ð 	+ˆCÝÐ;Ð;¨NÐ;Ñ;Ô;Ñ<Ô<ˆJØ�1Œv˜
Ñ" QÒ&Ð&Ø—’˜~Ñ.Ô.Ð.Ø"% ��à×%Ò% cÑ*Ô*Ð*Ð*Ø�Š�~Ñ&Ô&Ð&Ý�7‰|Œ|˜aÒÐr   c                 óR   — t          j        |d         | |d         | |z   ¦  «        }|S )zlCreate a rectangle of full box width.

        Its height equals vertical_gap and its top equals y.
        r   r™   rá   )Úyr.  Úvertical_gapr©   s       r   Údividerz cluster_stripes.<locals>.dividerû  s+   € õ
 ŒL˜˜Qœ  C¨¤F¨A°Ñ,<Ñ=Ô=ˆØˆr   c                 ó   — | d         S )Nrš   r   r%  s    r   rÿ   z!cluster_stripes.<locals>.<lambda>  s
   € ¨q°¬t€ r   r&  rš   c              3   óv   •K  — | ]3}‰                      t          j        |d d…         ¦  «        ¦  «        V — Œ4d S rß   )rì   r6   r    ©r   rã   Údivs     €r   rª   z"cluster_stripes.<locals>.<genexpr>  sA   øè è € ÐFÐF¸1�3—>’>¥'¤,¨q°°!°¬uÑ"5Ô"5Ñ6Ô6ÐFÐFÐFÐFÐFÐFr   c              3   óJ   •K  — | ]}|d          ‰j         k    ¯|d          V — ŒdS r­   ©r¸   r7  s     €r   rª   z"cluster_stripes.<locals>.<genexpr>  s1   øè è € ÐCÐC˜q°A°a´D¸C¼F²N°N�a˜”d°N°N°N°NÐCÐCr   N)Údefaultr   r…   )	rE   r¸   rò   rŸ   rì   r¶   ÚaddrC   Úpop)r*  Újoined_boxesr  r3  r0  r4  r+  ÚstripesÚy_valuesr.  r2  r¶   Úinter_countÚvrÚcurrent_striper8  s                  @r   Úcluster_stripesrD  Ú  s  ø€ ð ð  ð  ð&ð ð ð ð Øˆõ ˜% ^ ^Ð4Ñ4Ô4€LØ€Gð Ð˜eÑ$Ô$ð Øˆwˆð ”Ð €HØð %ð %ˆà�ŒFˆØ�”ÒÐØàˆg�a˜ |Ñ4Ô4ˆÝÐFÐFÐFÐFÀÐFÑFÔFÑFÔFð 	%åÐCÐCÐCÐC LÐCÑCÔCÈTÐRÑRÔRˆBØˆzØØˆCŒFàˆKð ð %ð %�Ø—>’> "Ñ%Ô%ð %¨"¬%°3´6ª/¨/¸c¼fÈÌºo¸oØ 1Ñ$�KøØ˜aÒÐØ—’˜SœVÑ$Ô$Ð$øÝ�hÑÔ€HØ€NØð  ð  ˆØð 	7˜|¨Aœ¨qÔ1°QÒ6Ð6Ø×!Ò! ,×"2Ò"2°1Ñ"5Ô"5Ñ6Ô6Ð6ð ð 	7˜|¨Aœ¨qÔ1°QÒ6Ð6àð 	 Ø�NŠN˜>Ñ*Ô*Ð*ØˆNøØ€Nr   c                 ój  ‡ ‡‡‡	‡
‡‡‡— dŠˆfd„}t          d„ ‰ D ¦   «         ¦  «        Št          d„ ‰ D ¦   «         ¦  «        }t          d„ ‰ D ¦   «         ¦  «        Št          d„ ‰ D ¦   «         ¦  «        }ˆˆfd„Šˆˆ fd„‰ D ¦   «         Š‰s |‰ ¦  «        S ‰                     d	„ ¬
¦  «         g }|Š	‰D ]OŠ
ˆ	ˆ
fd„‰ D ¦   «         } ||¦  «        }|                     |¦  «         ‰
d         Š	|                     ‰
g¦  «         ŒPˆfd„‰ D ¦   «         }|r  ||¦  «        }|                     |¦  «         |S )a1  
    Within a stripe, group boxes into columns based on horizontal proximity.

    We use a small horizontal gap threshold to decide when a new column starts.

    Args:
        stripe (list): List of boxes we look at here.

    Returns:
        list: List of columns, each column is a list of boxes.
    r…   c                 óz  •— g }| s| S t          | d„ ¬¦  «        }|d         g}|dd …         D ]h}t          d„ |D ¦   «         ¦  «        }|d         |z
  ‰k    r)|                     t          |d„ ¬¦  «        ¦  «         |g}ŒS|                     |¦  «         Œi|                     t          |d„ ¬¦  «        ¦  «         |S )Nc                 ó   — | d         S r$  r   r%  s    r   rÿ   zFcluster_columns_in_stripe.<locals>.cluster_substripe.<locals>.<lambda>H  s
   € °q¸´t€ r   r&  r   r…   c                 ó   — g | ]
}|d          ‘ŒS r(  r   râ   s     r   r   zHcluster_columns_in_stripe.<locals>.cluster_substripe.<locals>.<listcomp>L  r)  r   c                 ó   — | d         S ©Nr…   r   r%  s    r   rÿ   zFcluster_columns_in_stripe.<locals>.cluster_substripe.<locals>.<lambda>N  s
   € ÀAÀaÄD€ r   c                 ó   — | d         S rJ  r   r%  s    r   rÿ   zFcluster_columns_in_stripe.<locals>.cluster_substripe.<locals>.<lambda>S  s
   € ¸A¸a¼D€ r   )rE   rž   rC   )Ú	substriper,  r+  r-  r.  r/  ÚHORIZONTAL_GAPs         €r   Úcluster_substripez4cluster_columns_in_stripe.<locals>.cluster_substripeC  så   ø€ àˆØð 	ØÐÝ˜i¨^¨^Ð<Ñ<Ô<ˆØ& qœ/Ð*ˆà   Ô#ð 	+ð 	+ˆCÝÐ;Ð;¨NÐ;Ñ;Ô;Ñ<Ô<ˆJØ�1Œv˜
Ñ" ^Ò3Ð3Ø—’�v n¸.¸.ÐIÑIÔIÑJÔJÐJØ"% ��à×%Ò% cÑ*Ô*Ð*Ð*à�Š•v˜n°.°.ÐAÑAÔAÑBÔBÐBØˆr   c              3   ó&   K  — | ]}|d          V — ŒdS r§   r   râ   s     r   rª   z,cluster_columns_in_stripe.<locals>.<genexpr>W  ó&   è è € Ð"Ð"�aˆQˆqŒTÐ"Ð"Ð"Ð"Ð"Ð"r   c              3   ó&   K  — | ]}|d          V — ŒdS r­   r   râ   s     r   rª   z,cluster_columns_in_stripe.<locals>.<genexpr>X  rP  r   c              3   ó&   K  — | ]}|d          V — ŒdS r¯   r   râ   s     r   rª   z,cluster_columns_in_stripe.<locals>.<genexpr>Y  rP  r   c              3   ó&   K  — | ]}|d          V — ŒdS r±   r   râ   s     r   rª   z,cluster_columns_in_stripe.<locals>.<genexpr>Z  rP  r   c                 ó6   •— ‰| d         ‰| d         | d         gS )Nr…   rš   rà   r   )rã   rµ   r·   s    €€r   Úexpandedz+cluster_columns_in_stripe.<locals>.expanded\  s    ø€ à�A�a”D˜"˜a œd A a¤DÐ)Ð)r   c                 óN   •‡— g | ] Št          ˆˆfd „‰D ¦   «         ¦  «        ¯‰‘Œ!S )c              3   óV   •K  — | ]#}|‰k    ¯t          | ‰‰¦  «        ¦  «        V — Œ$d S rê   )rÆ   )r   r©   rã   rU  s     €€r   rª   z7cluster_columns_in_stripe.<locals>.<listcomp>.<genexpr>c  sA   øè è € Ð XÐ XÀ!ÐQRÐVWÒQWÐQW¥¨a°°¸!±´Ñ!=Ô!=ÐQWÐQWÐQWÐQWÐ XÐ Xr   )Úall)r   rã   rU  Ústripes    @€€r   r   z-cluster_columns_in_stripe.<locals>.<listcomp>b  sO   øø€ ð ð ð Ø�SÐ XÐ XÐ XÐ XÐ XÀvÐ XÑ XÔ XÑXÔXðØ	ðð ð r   c                 ó   — | d         S rJ  r   r%  s    r   rÿ   z+cluster_columns_in_stripe.<locals>.<lambda>k  s
   €  ! A¤$€ r   r&  c                 óP   •— g | ]"}|d          ‰d         k    ¯|d         ‰k    ¯ |‘Œ#S )rš   r…   r   )r   rã   Ús0Úsols     €€r   r   z-cluster_columns_in_stripe.<locals>.<listcomp>r  s2   ø€ ÐFÐFÐF˜¨¨!¬°°A´ª¨¸1¸Q¼4À2º:¸:�1¸:¸:¸:r   rš   c                 óD   •— g | ]}|d          ‰d         d         k    ¯|‘ŒS )r…   rè   rš   r   )r   rã   Ú
solitariess     €r   r   z-cluster_columns_in_stripe.<locals>.<listcomp>w  s0   ø€ Ð>Ð>Ð>�Q A a¤D¨J°r¬N¸1Ô,=Ò$=Ð$=ˆqÐ$=Ð$=Ð$=r   )rŸ   rž   ÚsortÚextendrC   )rY  rN  r¶   r¸   Ú	finalistsÚsstriper,  rM  rU  r\  r]  r_  rµ   r·   s   `      @@@@@@@r   Úcluster_columns_in_striperd  5  sâ  øøøøøøøø€ ð €Nðð ð ð ð õ( 
Ð"Ð"˜6Ð"Ñ"Ô"Ñ	"Ô	"€BÝ	Ð"Ð"˜6Ð"Ñ"Ô"Ñ	"Ô	"€BÝ	Ð"Ð"˜6Ð"Ñ"Ô"Ñ	"Ô	"€BÝ	Ð"Ð"˜6Ð"Ñ"Ô"Ñ	"Ô	"€Bð*ð *ð *ð *ð *ð *ðð ð ð ð Øðñ ô €Jð
 ð )Ø Ð  Ñ(Ô(Ð(ð ‡O‚O˜˜€OÑ'Ô'Ð'ð €IØ	€BØð  ð  ˆàFÐFÐFÐFÐF˜fÐFÑFÔFˆØ#Ð# GÑ,Ô,ˆØ×Ò˜Ñ!Ô!Ð!Ø�ŒVˆØ×Ò˜#˜ÑÔÐÐØ>Ð>Ð>Ð>˜&Ð>Ñ>Ô>€GØð "Ø#Ð# GÑ,Ô,ˆØ×Ò˜Ñ!Ô!Ð!ØÐr   c                 óŒ   — t          | |||¬¦  «        }g }|D ]+}t          |¦  «        }|D ]}|                     |¦  «         ŒŒ,|S )a  
    Compute reading order of boxes delivered by PyMuPDF-Layout.

    Args:
        boxes (list): List of bounding boxes.
        vertical_gap (float): Minimum vertical gap to separate stripes.

    Returns:
        list: List of boxes in reading order.
    ©r3  )rD  rd  ra  )	r*  r>  r  r3  r?  ÚorderedrY  r,  Úcols	            r   Úcompute_reading_orderri  ~  su   € õ ØØØØ!ð	ñ ô €Gð €GØð  ð  ˆÝ+¨FÑ3Ô3ˆØð 	 ð 	 ˆCØ�NŠN˜3ÑÔÐÐð	 à€Nr   r3  c           	      ó*  ‡‡‡— || j         z  dz  }dt          fd„Šdt          fˆfd„}	  ||¦  «        }g }g }g }	|D ]W}
|
\  }}}}}|dk    r|                     |
¦  «         Œ&|dk    r|                     |
¦  «         ŒB|	                     |
¦  «         ŒX|	st	          j        ¦   «         Šnst	          j        t          d„ |	D ¦   «         ¦  «        t          d„ |	D ¦   «         ¦  «        t          d	„ |	D ¦   «         ¦  «        t          d
„ |	D ¦   «         ¦  «        ¦  «        Št          ‰¦  «        s<t          d„ |	D ¦   «         ¦  «        Šˆˆfd„|D ¦   «         }t          |	‰||¬¦  «        }ng }t          |d„ ¬¦  «        |z   t          |d„ ¬¦  «        z   }|S )aä  Given page layout information, return the boxes in reading order.

    Args:
        boxes: List of classified bounding boxes with class info as defined
               by pymupdf_layout: (x0, y0, x1, y1, "class").
        vertical_gap: Minimum vertical gap to separate stripes. The default
                      value of 36 works well for most documents. It roughly
                      corresponds to 2 -3 text line heights

    Returns:
        List of boxes in reading order.
    i   rj   c                 ó    — 	 |d         | d         k    o;|d         | d         k    o)|d         | d         k    o|d         | d         k    o| |k    S )z7Check if inner box is fully contained within outer box.r…   r   r™   rš   r   rÈ   s     r   Úis_containedz(find_reading_order.<locals>.is_contained¨  sm   € ðØ�a”˜E !œHÒ$ðà�a”˜E !œHÒ$ðð �a”˜E !œHÒ$ðð �a”˜E !œHÒ$ð	ð
 ˜’ð	
r   c                 ó    •‡— t          | d„ d¬¦  «        }g }|D ]3Št          ˆˆfd„|D ¦   «         ¦  «        s|                     ‰¦  «         Œ4|S )z9Remove boxes that are fully contained within another box.c                 óH   — | d         | d         z
  | d         | d         z
  z  S )Nr™   r   rš   r…   r   r  s    r   rÿ   z>find_reading_order.<locals>.filter_contained.<locals>.<lambda>·  s#   €  ! A¤$¨¨1¬¡+°!°A´$¸¸1¼±+Ñ!>€ r   Tr   c              3   ó`   •K  — | ](} ‰‰|¦  «        o‰d          dk    p|d          dk    V — Œ)dS )rà   Útablerå   Nr   )r   Úotherrl  r©   s     €€r   rª   z?find_reading_order.<locals>.filter_contained.<locals>.<genexpr>Ä  s^   øè è € ð ð àð �˜Q Ñ&Ô&ÐU¨A¨a¬D°GªOÐ,T¸uÀQ¼xÈ9Ò?Tðð ð ð ð ð r   )rE   rò   rC   )r*  r+  r\   r©   rl  s      @€r   Úfilter_containedz,find_reading_order.<locals>.filter_contained³  s”   øø€ õ ØÐ>Ð>Èð
ñ 
ô 
ˆð ˆØð 	!ð 	!ˆAõ ð ð ð ð ð à#ðñ ô ñ ô ð !ð —’˜aÑ Ô Ð øØˆr   zpage-headerzpage-footerc              3   ó&   K  — | ]}|d          V — ŒdS r§   r   râ   s     r   rª   z%find_reading_order.<locals>.<genexpr>ä  ó&   è è € Ð)Ð)˜��!”Ð)Ð)Ð)Ð)Ð)Ð)r   c              3   ó&   K  — | ]}|d          V — ŒdS r­   r   râ   s     r   rª   z%find_reading_order.<locals>.<genexpr>å  rt  r   c              3   ó&   K  — | ]}|d          V — ŒdS r¯   r   râ   s     r   rª   z%find_reading_order.<locals>.<genexpr>æ  rt  r   c              3   ó&   K  — | ]}|d          V — ŒdS r±   r   râ   s     r   rª   z%find_reading_order.<locals>.<genexpr>ç  rt  r   c              3   ó8   K  — | ]}|d          |d         z
  V — ŒdS )rš   r…   Nr   râ   s     r   rª   z%find_reading_order.<locals>.<genexpr>ì  s.   è è € Ð>Ð>¨a˜a œd Q q¤T™kÐ>Ð>Ð>Ð>Ð>Ð>r   c                 óš   •— g | ]G}|d          d         |d          d         z
  ‰k    r$|d          ‰v ¯-t          j        |d          ¦  «        ‘ŒHS )r›   rš   r…   rá   )r   rã   r>  Úmin_bbox_heights     €€r   r   z&find_reading_order.<locals>.<listcomp>í  sb   ø€ ð 
ð 
ð 
àØ�Œy˜Œ|˜a œi¨œlÑ*¨oÒ=Ð=Ø�&”	˜\Ð)Ð)õ ŒL˜˜6œÑ#Ô#ð *Ð)Ð)r   rf  c                 ó"   — | d         | d         fS ©Nr…   r   r   r  s    r   rÿ   z$find_reading_order.<locals>.<lambda>ÿ  s   € ¨A¨a¬D°!°A´$¨<€ r   r&  c                 ó"   — | d         | d         fS r|  r   r  s    r   rÿ   z$find_reading_order.<locals>.<lambda>  s   € ¨a°¬d°A°a´D¨\€ r   )r  ÚboolrH   rC   r6   r³   r    rŸ   rž   rœ   ri  rE   )Ú	page_rectrô   r*  r3  Úthis_vertical_gaprr  ÚfilteredÚpage_headersÚpage_footersÚ
body_boxesr.  rµ   r¶   r·   r¸   Úbclassr  rg  Úfinalrl  r>  rz  s                      @@@r   Úfind_reading_orderr‡  —  sX  øøø€ ð % yÔ'7Ñ7¸#Ñ=Ðð	
¥dð 	
ð 	
ð 	
ð 	
ð¥4ð ð ð ð ð ð ð0ð
  Ð Ñ&Ô&€HØ€LØ€LØ€Jð ð #ð #ˆØ!$ÑˆˆB��B˜Ø�]Ò"Ð"Ø×Ò Ñ$Ô$Ð$Ð$Ø�}Ò$Ð$Ø×Ò Ñ$Ô$Ð$Ð$à×Ò˜cÑ"Ô"Ð"Ð"ð ð 
ÝÔ)Ñ+Ô+ˆˆå”|ÝÐ)Ð)˜jÐ)Ñ)Ô)Ñ)Ô)ÝÐ)Ð)˜jÐ)Ñ)Ô)Ñ)Ô)ÝÐ)Ð)˜jÐ)Ñ)Ô)Ñ)Ô)ÝÐ)Ð)˜jÐ)Ñ)Ô)Ñ)Ô)ñ	
ô 
ˆõ ˜Ñ&Ô&ð ÝÐ>Ð>°:Ð>Ñ>Ô>Ñ>Ô>ˆð
ð 
ð 
ð 
ð 
àð
ñ 
ô 
ˆõ (ØØØØ*ð	
ñ 
ô 
ˆˆð ˆõ 	ˆ|Ð!7Ð!7Ð8Ñ8Ô8Ø
ñ	å
�Ð#9Ð#9Ð
:Ñ
:Ô
:ñ	;ð 
ð
 €Lr   c           	      óÈ  — d}g }| s|S | d         g}| dd…         D �]D}|d         }	 	 t          |d         d         |d         d         z
  ¦  «        |k     rôt          |d         d         |d         d         z
  ¦  «        |k     rÆ|d         d         |d         d         dz   k    r¥t          |d         d         |d         d         ¦  «        t          |d         d         |d         d         ¦  «        t          |d         d         |d         d         ¦  «        t          |d         d         |d         d         ¦  «        g}||d<   �Œ/|                     |¦  «         �ŒF|S )zCJoin vectors that are horizontally adjacent and vertically aligned.r…   r   Nrè   r›   rš   r™   )rý   rŸ   rž   rC   )r  ÚY_TOLERANCEÚnew_vectorsrþ   Úlast_vÚnew_bboxs         r   Úsimplify_vectorsr�    sk  € à€KØ€KØð ØÐØ˜1”:�,€KØ�Q�R�RŒ[ð "ñ "ˆØ˜R”ˆàð	"å�A�f”I˜a”L 6¨&¤>°!Ô#4Ñ4Ñ5Ô5¸ÒCÐCÝ�A�f”I˜a”L 6¨&¤>°!Ô#4Ñ4Ñ5Ô5¸ÒCÐCØ�&”	˜!”  v¤¨qÔ 1°AÑ 5Ò5Ð5õ �A�f”I˜a”L &¨¤.°Ô"3Ñ4Ô4Ý�A�f”I˜a”L &¨¤.°Ô"3Ñ4Ô4Ý�A�f”I˜a”L &¨¤.°Ô"3Ñ4Ô4Ý�A�f”I˜a”L &¨¤.°Ô"3Ñ4Ô4ð	ˆHð &ˆF�6‰N‰Nà×Ò˜qÑ!Ô!Ð!Ñ!ØÐr   c                 ód  ‡‡— d„ }t          ˆfd„|D ¦   «         d„ ¬¦  «        }g }g }|D �]}	t          j        |	d         ¦  «                             ¦   «         Š‰dz  Š‰‰z  Št	          ‰¦  «        rŒI|	d         sY‰j        dk    rN‰j        d	k    rC|                     ‰j        ‰j	        f¦  «         |                     ‰j
        ‰j        f¦  «         Œª‰j        d	k    rM‰j        d
k    rBt          ˆfd„|D ¦   «         ¦  «        s' |‰‰|¦  «        }
|
D ]}|                     |¦  «         Œ�Œ||fS )a8  Return virtual lines for a given table bbox.

    This utility looks for:
    * horizontal non-stroke vectors and uses their top and bottom edges
      as virtual lines. Should work for tables with alternating row colors.
    * horizontal thin lines and uses their left x-coordinate as column
      borders.
    c                 óN  ‡ ‡‡— |j         dz
  Št          j        ‰j        ‰ j        ¦  «        Št          ˆˆfd„|D ¦   «         d„ ¬¦  «        }|r|d         j        ‰_        t          ˆ ˆfd„|D ¦   «         d„ ¬¦  «        }|r|d         j        ‰_        n‰ j        ‰_        ‰‰fg}|S )	N)r™   r   c                 ó’   •— g | ]C}|j         ‰j        k    ¯|j        ‰j        k    ¯"|j        ‰j        cxk     r|j        k     ¯>n n|‘ŒDS r   )r¶   r2  r¸   rµ   Úxr·   )r   ÚwrÚbottomÚtops     €€r   r   z=find_virtual_lines.<locals>.make_vertical.<locals>.<listcomp>3  se   ø€ ð ð ð àØ”5˜CœE’>�> b¤e¨v¬xÒ&7Ð&7¸B¼EÀCÄEÐ<QÐ<QÒ<QÐ<QÈBÌEÒ<QÐ<QÐ<QÐ<QÐ<Qð à<QÐ<QÐ<Qr   c                 ó   — | j         S rê   r:  r  s    r   rÿ   z;find_virtual_lines.<locals>.make_vertical.<locals>.<lambda>8  ó   € ˜!œ$€ r   r&  r   c                 ó’   •— g | ]C}|j         ‰j         k    ¯|j        ‰j        k    ¯"|j        ‰j        cxk     r|j        k     ¯>n n|‘ŒDS r   )r¶   r¸   r2  rµ   r‘  r·   )r   r’  Ú
table_bboxr”  s     €€r   r   z=find_virtual_lines.<locals>.make_vertical.<locals>.<listcomp>?  sg   ø€ ð ð ð àØ”5˜JœMÒ)Ð)¨b¬e°s´uªn¨nÀÄÈÌÐAVÐAVÒAVÐAVÐQSÔQVÒAVÐAVÐAVÐAVÐAVð àAVÐAVÐAVr   c                 ó   — | j         S rê   r:  r  s    r   rÿ   z;find_virtual_lines.<locals>.make_vertical.<locals>.<lambda>D  r–  r   rè   )Útlr6   ÚPointr‘  r¸   rE   r¶   r2  )r˜  Ú	line_bboxÚ
word_boxesÚ	my_wboxesÚextenderr“  r”  s   `    @@r   Úmake_verticalz)find_virtual_lines.<locals>.make_vertical,  s  øøø€ àŒl˜VÑ#ˆÝ”˜sœu j¤mÑ4Ô4ˆõ ðð ð ð ð à$ðñ ô ð
 �ð
ñ 
ô 
ˆ	ð ð 	'Ø  ”|”ˆFŒHõ ðð ð ð ð à$ðñ ô ð
 �ð
ñ 
ô 
ˆ	ð ð 	"Ø˜b”MÔ$ˆCŒEˆEà”MˆCŒEð ˜&�M�?ˆØˆr   c                 ó¬   •— g | ]P}|d          |d         z
  dk    ¯‰                      |dd…         ¦  «        ¯4t          j        |dd…         ¦  «        ‘ŒQS )rš   r…   é   Nrà   )Úcontainsr6   r    )r   Úwr˜  s     €r   r   z&find_virtual_lines.<locals>.<listcomp>P  sg   ø€ ð 	
ð 	
ð 	
àØ�!”�q˜”t‘˜qÒ Ð  Z×%8Ò%8¸¸2¸A¸2¼Ñ%?Ô%?Ð õ ŒL˜˜2˜A˜2œÑÔà Ð Ð r   c                 ó   — | j         S rê   r:  r  s    r   rÿ   z$find_virtual_lines.<locals>.<lambda>U  s   € �a”d€ r   r&  r›   )r   g      à¿r   ç      à?Ústrokedr¢  r
  rš   c              3   óB   •K  — | ]}‰                      |¦  «        V — Œd S rê   rë   )r   ÚlrÚvbboxs     €r   rª   z%find_virtual_lines.<locals>.<genexpr>g  s1   øè è € ÐBÐB°˜×(Ò(¨Ñ,Ô,ÐBÐBÐBÐBÐBÐBr   )rE   r6   r    Ú	normalizerœ   r  r  rC   rš  ÚtrÚblÚbrrò   )r'   r˜  Úwordsr  Ú
link_rectsr   r�  Ú	all_linesÚ	all_boxesrþ   ÚlinesÚlinerª  s    `          @r   Úfind_virtual_linesrµ  "  s   øø€ ð!ð !ð !õF ð	
ð 	
ð 	
ð 	
àð	
ñ 	
ô 	
ð
 ˆNðñ ô €Jð €IØ€IØð 'ñ 'ˆÝ”˜Q˜vœYÑ'Ô'×1Ò1Ñ3Ô3ˆØÐ"Ñ"ˆØ�ÑˆÝ˜ÑÔð 	ØØ�Œ|ð 	 ¤°Ò 1Ð 1°e´kÀBÒ6FÐ6FØ×Ò˜eœh¨¬Ð1Ñ2Ô2Ð2Ø×Ò˜eœh¨¬Ð1Ñ2Ô2Ð2ØàŒK˜"ÒÐØ” Ò!Ð!ÝÐBÐBÐBÐB°zÐBÑBÔBÑBÔBð "ð "�M *¨e°ZÑ@Ô@ˆEØð 'ð '�Ø× Ò  Ñ&Ô&Ð&Ð&ùà�iÐÐr   c           	      óŒ  — d}| D �]Y}t          |d         |¦  «        rŒ|d         D �]5}t          |d         |¦  «        rŒ|r	||rdndz  }|d         dk    p|d         dk    }|d	         D �]î}t          |d         |¦  «        rŒ|r	|d
         }	nAd}	|d         D ]6}
|
d         }t          |
d         |d¬¦  «        r|	|z  }	Œ(|t          v r|	dz  }	Œ7|	sŒi|s||	z  }Œq|d         t          j        z  }|d         t          j        z  ot          |¦  «         }|d         t          j        z  p|d         t          j        j	        z  }|d         t          j
        z  }|d         t          j        j        z  }|d         t          j        j        z  }|d         t          j        j        z  }g }g }|r*|                     d¦  «         |                     d¦  «         |r*|                     d¦  «         |                     d¦  «         |r*|                     d¦  «         |                     d¦  «         |r,|r*|                     d¦  «         |                     d¦  «         |r*|                     d¦  «         |                     d¦  «         d                     |¦  «        }d                     t!          |¦  «        ¦  «        }t#          |	¦  «        dk    r|	                     ¦   «         }	t#          |¦  «        x}r(|                     |¦  «        r|d| …         |	z   |z   }�Œ¶|	                     ¦   «         s|dz  }�ŒÑ|||	                     ¦   «         z   |z   z  }�Œð�Œ7�Œ[|                     dd¦  «                             dd¦  «                             dd¦  «                             dd¦  «        }|                     ¦   «         S )a2  Extract text from a rect-like 'cell' as plain or MD styled text.

    This function should ultimately be used to extract text from a table cell.
    Markdown output will only work correctly if extraction flag bit
    TEXT_COLLECT_STYLES is set.

    Args:
        table_blocks: A list of PyMuPDF TextPage text blocks (type = 0). Must
            have been created with TEXT_COLLECT_STYLE for correct markdown.
            Format is either "dict" or "rawdict" depending on ocrpage.
        cell: A tuple (x0, y0, x1, y1) defining the cell's bbox.
        markdown: If True, return text formatted for Markdown.
        ocrpage: If True, text is OCR-detected. In this case, table_blocks
        is in format "dict" (no char-level info available).

    Returns:
        A string with the text extracted from the cell.
    r)   r›   r³  z<br>ú
Údir)r   r…   )r…   r   ÚspansrŠ   ÚcharsÚcr¦  )r¾   rs   ÚflagsrŽ   z<sup>z</sup>z**rt   z~~ú`r™   Nz$<br>z$ z $ <br>z$
z $ 
)rÆ   rÂ   r•   r6   ÚTEXT_FONT_SUPERSCRIPTÚTEXT_FONT_MONOSPACEDr“   ÚTEXT_FONT_BOLDr   ÚFZ_STEXT_BOLDÚTEXT_FONT_ITALICÚFZ_STEXT_STRIKEOUTÚFZ_STEXT_UNDERLINEÚFZ_STEXT_HIGHLIGHTrC   ÚjoinÚreversedrˆ   ÚrstripÚendswithrv   r}   )Útable_blocksrÄ   ÚmarkdownÚocrpagerŠ   Úblockr´  Ú
horizontalr’   Ú	span_textÚcharÚ	this_charÚsuperscriptÚmonoÚboldÚitalicÚ	strikeoutÚ	underlineÚ	highlightrJ   ÚsuffixÚlss                         r   Úextract_cellsrÛ  p  s?  € ð( €DØð \Dñ \DˆÝ˜˜fœ tÑ,Ô,ð 	ØØ˜'”Nð Y	Dñ Y	DˆDÝ˜D œL¨$Ñ/Ô/ð ØØð 5Ø (Ð4˜˜°Ñ4�ð ˜eœ¨Ò.ÐG°$°u´+ÀÒ2GˆJà˜Wœð PDñ PD�Ý  V¤¨dÑ3Ô3ð ØØð -Ø $ V¤�I�Ið !#�IØ $ W¤ð -ð -˜Ø$(¨¤I˜	Ý)¨$¨v¬,¸ÀcÐJÑJÔJð -Ø%¨Ñ2˜I˜IØ&­+Ð5Ð5Ø%¨Ñ,˜Iøà ð Øàð Ø˜IÑ%�DØð # 7œm­gÔ.KÑK�Ø˜G”}¥wÔ'CÑCð ÍKØñMô Mð I�ð ˜”M¥GÔ$:Ñ:ð HØ˜LÔ)­G¬MÔ,GÑGð ð ˜gœ­Ô)AÑA�Ø  Ô.µ´Ô1QÑQ�	Ø  Ô.µ´Ô1QÑQ�	Ø  Ô.µ´Ô1QÑQ�	à�Ø�Øð ,Ø—M’M 'Ñ*Ô*Ð*Ø—M’M (Ñ+Ô+Ð+àð (Ø—M’M $Ñ'Ô'Ð'Ø—M’M $Ñ'Ô'Ð'àð 'Ø—M’M #Ñ&Ô&Ð&Ø—M’M #Ñ&Ô&Ð&àð ( )ð (Ø—M’M $Ñ'Ô'Ð'Ø—M’M $Ñ'Ô'Ð'ð ð 'Ø—M’M #Ñ&Ô&Ð&Ø—M’M #Ñ&Ô&Ð&àŸš ™œ�ØŸš¥¨&Ñ!1Ô!1Ñ2Ô2�å�y‘>”> AÒ%Ð%Ø )× 0Ò 0Ñ 2Ô 2�Iõ ˜f™+œ+Ð%�Bð D¨4¯=ª=¸Ñ+@Ô+@ð DØ  "  œ:¨	Ñ1°FÑ:�D‘Dà$Ÿ?š?Ñ,Ô,ð DØ ™˜™à ¨¯ªÑ):Ô):Ñ :¸VÑ CÑC˜™ñaPDñY	Dðv 	�Š�W˜dÑ#Ô#ß	Š�˜DÑ	!Ô	!ß	Š�˜Ñ	Ô	ß	Š�˜$Ñ	Ô	ð	 	ð �:Š:‰<Œ<Ðr   c                 ód  — d}dd                      | d         ¦  «        z   dz   }||z  }|dd                      d„ t          t          | d         ¦  «        ¦  «        D ¦   «         ¦  «        z   dz   z  }d}| |d …         D ]/}d}t          |¦  «        D ]\  }}|€d}||dz   z  }Œ|dz  }||z  }Œ0|dz   S )Nr)   ú|r   z|
c              3   ó   K  — | ]}d V — ŒdS )z---Nr   r
   s     r   rª   z$table_to_markdown.<locals>.<genexpr>ñ  s"   è è € ÐAÐA q˜UÐAÐAÐAÐAÐAÐAr   r…   r·  )rÆ  r@   rˆ   ró   )ÚcellsÚoutputÚheaderrí   Úrowr´  r   rÄ   s           r   Útable_to_markdownrã  ë  sé   € Ø€Fà�3—8’8˜E !œHÑ%Ô%Ñ%¨Ñ-€FØ
ˆfÑ€Fà
ˆc�C—H’HÐAÐA­Eµ#°e¸A´h±-´-Ñ,@Ô,@ÐAÑAÔAÑAÔAÑAÀEÑIÑI€Fð 	
€Að �Q�R�RŒyð 	ð 	ˆØˆÝ  ‘~”~ð 	ð 	‰GˆAˆtð ˆ|Ø�Ø�D˜3‘JÑˆDˆDØ�‰ˆØ�$‰ˆˆØ�D‰=Ðr   )F)rº   )r   )FF)4Úpathlibr   ÚnumpyÚnpr6   r   Úpymupdf4llm.ocr.analyze_pager   r�   rF   r@   r•   r	   ÚREPLACEMENT_CHARACTERÚTYPE3_FONT_NAMEr²   Úmapr‡   ÚTEXT_COLLECT_STYLESÚTEXT_COLLECT_VECTORSÚTEXT_PRESERVE_IMAGESÚTEXT_ACCURATE_BBOXESÚTEXT_MEDIABOX_CLIPÚTEXT_IGNORE_ACTUALTEXTÚFLAGSrg   Ústrrƒ   r‹   r~  r“   r—   rœ   r¤   r¹   rÂ   rÆ   rË   rÕ   rÜ   rö   r  rD  rd  ri  ÚfloatrH   r‡  r�  rµ  rÛ  rã  r   r   r   ú<module>rô     sG  ðØ Ð Ð Ð Ð Ð à Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5à%Ð ØˆcØÐ�U�U˜2‘Y”YÐÑÔðð ð ññô €ð* ˜˜F™œÐ Ø€à
ˆ%àˆˆD‰	Œ	ØˆˆD‰	Œ	ØˆˆD‰	Œ	ØˆˆD‰	Œ	ØˆˆD‰	Œ	ØˆˆD‰	Œ	ØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØˆˆF‰ŒØð+ð. 
€cˆ#ˆ#ˆc�5�5˜ Ñ(Ô(Ñ
)Ô
)Ñ*Ô*ñ/+ñô €ð8 ØÔ!ñ"àÔ"ñ#ð Ô"ñ#ð Ô"ñ	#ð
 Ô ñ!ð Ô$ñ%ð ðqð qð qð qðh*�Cð * 3ð *¨3ð *ð *ð *ð *ðZð ð ð˜ð ð ð ð ð&(�dð (ð (ð (ð (ð
4˜4ð 4ð 4ð 4ð 4ð6ð 6ð 6ð 6ð
Kð Kð Kð Kðð ð ð ð 
ð 
¨dð 
ð 
ð 
ð 
ð* $ð ð ð ð ðð ð ð	9ð 	9ð 	9ðRð Rð Rð<Ið Ið IðXðXð Xð Xð XðvFð Fð FðRð ð ð ð2lð l¸uð lÈdð lð lð lð lð^ð ð ð8K ð K ð K ð\xð xð xð xðvð ð ð ð r   