§
    ŒWêjaÞ ã            '       ó  — d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlZddlZddlmZ ddlmZmZmZmZmZ dd	lmZmZmZmZmZ dd
lmZmZmZm Z m!Z! ddlm"Z"  edd¬¦  «        Z# edd¬¦  «        Z$ddœd„Z% G d„ d¦  «        Z& e&e#¦  «        Z' e&e$¦  «        Z(ej)        Z*ej+        Z,dej-        z  ej.        z  ej/        z  Z0d„ Z1dej2        z  ej3        z  ej4        z  ej/        z  Z5 e6ej7        ¦  «        Z8d„ Z9d„ Z:d„ Z;de<fd„Z=d„ Z>d„ Z?d�d„Z@ G d„ deA¦  «        ZBg d¢ZCg d ¢ZD eBd¦  «        ZEd!ZFd!ZGd!ZHd"ZId!ZJd!ZKd#ZLd$ZM ed%d&d'd(¦  «        ZNd)d*d+d,d-d.d.d/œZOdePfd0„ZQ G d1„ d2¦  «        ZR G d3„ d4¦  «        ZS G d5„ d6¦  «        ZTd7ePdePfd8„ZU ejV        eSjW        ¦  «        jX         Y                    ¦   «         ZZ ejV        eT¦  «        jX         Y                    ¦   «         Z[d7ePdeRfd9„Z\d7ePde]fd:„Z^eJfd;ePde]fd<„Z_d‘d7ePdePfd=„Z`d>„ ZadePfd?„ZbdePfd@„ZcdePfdA„Zd	 	 	 d’dePfdB„Zed“dePfdC„ZfdegfdD„ZhdePfdE„ZidFe]fdG„ZjdHe]dePfdI„ZkeFeFfdJ„ZldKe]fdL„ZmeGfdMe]fdN„ZndO„ ZodegfdP„ZpdegfdQ„ZqdR„ ZrdS„ ZseIfdTetfdU„ZudV„ ZveHfdTetfdW„Zwd”degfdX„ZxdY„ ZydZ„ ZzdePfd[„Z{ G d\„ d]¦  «        Z| G d^„ d_e|¦  «        Z} G d`„ da¦  «        Z~db„ Z e€¦   «         Z� G dc„ dd¦  «        Z‚e
 G de„ df¦  «        ¦   «         Zƒ G dg„ dh¦  «        Z„	 d•di„Z…dj„ Z†dk„ Z‡d–dl„Zˆdm„ Z‰dn„ ZŠdo„ Z‹dp„ ZŒdddqœdr„Z�ds„ ZŽdt„ Z�du„ Z�dv„ Z‘dw„ Z’dx„ Z“dy„ Z”ddzdzddeFddeGddd!eHeId!ddd!d!d!ddddd{dddfd|e]d}e]d~ePdePd€eAd�eAd‚eAdƒeAd„eAd…eAd†eAd‡eAdˆeAd‰eAdŠeAd‹eAdŒe<d�e<dŽe<f&d�„Z•dS )—aë  
Copyright (C) 2023 Artifex Software, Inc.

This file is part of PyMuPDF.

PyMuPDF is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

PyMuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.

You should have received a copy of the GNU Affero General Public License
along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>

Alternative licensing terms are available from the licensor.
For commercial licensing, see <https://www.artifex.com/> or contact
Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
CA 94129, USA, for further information.

---------------------------------------------------------------------
Portions of this code have been ported from pdfplumber, see
https://pypi.org/project/pdfplumber/.

The ported code is under the following MIT license:

---------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2015, Jeremy Singer-Vine

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------------------------------------------------------------------
Also see here: https://github.com/jsvine/pdfplumber/blob/stable/LICENSE.txt
---------------------------------------------------------------------

The porting mainly pertains to files "table.py" and relevant parts of
"utils/text.py" within pdfplumber's repository on Github.
With respect to "text.py", we have removed functions or features that are not
used by table processing. Examples are:

* the text search function
* simple text extraction
* text extraction by lines

Original pdfplumber code does neither detect, nor identify table headers.
This PyMuPDF port adds respective code to the 'Table' class as method '_get_header'.
This is implemented as new class TableHeader with the properties:
* bbox: A tuple for the header's bbox
* cells: A tuple for each bbox of a column header
* names: A list of strings with column header text
* external: A bool indicating whether the header is outside the table cells.

é    N)ÚSequence)Ú
ContextVar)Ú	dataclass)Ú
itemgetter)Úmupdf)Úrefine_grid_structureÚrefine_grid_rowsÚ_refine_cells_to_gridÚ_refine_grid_to_cellsÚ_refine_page_words)Úresolve_spansÚSpanCellÚ_span_select_words_in_rectÚ_span_word_line_tupleÚ_span_words_to_line_text)ÚHeaderRegionÚextend_header_leaf_labelsÚfind_header_regionÚcollapse_cell_wsÚrender_table_html)Úrefine_gridÚpymupdf_table_edges©ÚdefaultÚpymupdf_table_charsF©Únativec                óÔ   — t          | dd¦  «        }|€|                      ¦   «         }n1|s'|                     |                      ¦   «         ¦  «         |d         }|s|S d„ |D ¦   «         S )aŠ  The page's vector drawings, shared within one find_tables() call.

    One call reads them up to ``1 + 2T`` times -- once to build edges, and once
    per refined table for shaded rows and for border lines -- and each read walks
    the whole content stream. find_tables() therefore puts an empty cache on the
    page for the duration of the call and removes it again, so nothing outlives
    the call: a page whose content stream is rewritten between calls cannot be
    served a stale extraction. Calling the public refine helpers directly, with
    no find_tables() around them, extracts afresh exactly as before.

    ``native=True`` returns per-path copies of the mutated members: make_edges
    extends path rects, normalizes rectangle items and appends a closing line, so
    the other consumers must not see its edits. Point and Quad values stay shared
    because make_edges only reads them.
    Ú_table_drawings_cacheNr   c           	      ó‚   — g | ]<}t          |t          j        |d          ¦  «        d„ |d         D ¦   «         ¬¦  «        ‘Œ=S )Úrectc                 ó„   — g | ]=}|d          dk    r-|d          t          j        |d         ¦  «        g|dd…         ¢R n|‘Œ>S )r   Úreé   é   N©ÚpymupdfÚRect)Ú.0Úitems     ú/Users/tedpeters/Documents/Projects/Claude Projects/TPC Houses/house-viewer/.venv/lib/python3.11/site-packages/pymupdf/table.pyú
<listcomp>z2_get_table_drawings.<locals>.<listcomp>.<listcomp>�   sc   € ð ð ð àð @DÀA¼wÈ$º¸��a”�'œ, t¨A¤wÑ/Ô/Ð;°$°q°r°r´(Ð;Ð;Ð;ÐTXðð ð ó    Úitems)r!   r.   )Údictr'   r(   )r)   Úpaths     r+   r,   z'_get_table_drawings.<locals>.<listcomp>™   sm   € ð 
ð 
ð 
ð õ 	ØÝ”˜d 6œlÑ+Ô+ðð à  œMðñ ô ð	
ñ 	
ô 	
ð
ð 
ð 
r-   )ÚgetattrÚget_drawingsÚappend)Úpager   ÚcacheÚpathss       r+   Ú_get_table_drawingsr7   €   s�   € õ  �DÐ1°4Ñ8Ô8€EØ€}Ø×!Ò!Ñ#Ô#ˆˆàð 	.Ø�LŠL˜×*Ò*Ñ,Ô,Ñ-Ô-Ð-Ø�a”ˆØð Øˆð
ð 
ð ð
ñ 
ô 
ð 
r-   c                   óN   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zd„ ZdS )Ú_TableStateListz4List-like proxy for per-call table extraction state.c                 ó   — || _         d S ©N)Ú_var)ÚselfÚvars     r+   Ú__init__z_TableStateList.__init__©   s   € ØˆŒ	ˆ	ˆ	r-   c                 ót   — | j                              ¦   «         }|€g }| j                              |¦  «         |S r;   )r<   ÚgetÚset©r=   Úvalues     r+   Ú_listz_TableStateList._list¬   s4   € Ø”	—’‘”ˆØˆ=ØˆEØŒI�MŠM˜%Ñ Ô Ð Øˆr-   c                 óP   — |                       ¦   «                              |¦  «        S r;   )rE   r3   ©r=   r*   s     r+   r3   z_TableStateList.append³   s   € Ø�zŠz‰|Œ|×"Ò" 4Ñ(Ô(Ð(r-   c                 óN   — |                       ¦   «                              ¦   «         S r;   )rE   Úclear©r=   s    r+   rI   z_TableStateList.clear¶   s   € Ø�zŠz‰|Œ|×!Ò!Ñ#Ô#Ð#r-   c                 óP   — |                       ¦   «                              |¦  «        S r;   )rE   Úextend)r=   r.   s     r+   rL   z_TableStateList.extend¹   s   € Ø�zŠz‰|Œ|×"Ò" 5Ñ)Ô)Ð)r-   c                 óD   — t          |                      ¦   «         ¦  «        S r;   )ÚboolrE   rJ   s    r+   Ú__bool__z_TableStateList.__bool__¼   ó   € Ý�D—J’J‘L”LÑ!Ô!Ð!r-   c                 ó6   — |                       ¦   «         |         S r;   ©rE   rG   s     r+   Ú__getitem__z_TableStateList.__getitem__¿   s   € Ø�zŠz‰|Œ|˜DÔ!Ð!r-   c                 óD   — t          |                      ¦   «         ¦  «        S r;   )ÚiterrE   rJ   s    r+   Ú__iter__z_TableStateList.__iter__Â   rP   r-   c                 óD   — t          |                      ¦   «         ¦  «        S r;   )ÚlenrE   rJ   s    r+   Ú__len__z_TableStateList.__len__Å   s   € Ý�4—:’:‘<”<Ñ Ô Ð r-   c                 ó4   — ||                       ¦   «         |<   d S r;   rR   )r=   ÚkeyrD   s      r+   Ú__setitem__z_TableStateList.__setitem__È   s   € Ø!ˆ�
Š
‰Œ�SÑÐÐr-   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r?   rE   r3   rI   rL   rO   rS   rV   rY   r\   © r-   r+   r9   r9   ¦   s°   € € € € € Ø>Ð>ðð ð ðð ð ð)ð )ð )ð$ð $ð $ð*ð *ð *ð"ð "ð "ð"ð "ð "ð"ð "ð "ð!ð !ð !ð"ð "ð "ð "ð "r-   r9   c                  óv   — t          j        ¦   «         r t           j        rt          t           j        z  S t          S r;   )r'   Ú_layout_availableÚ_layout_enabledÚFLAGSÚTEXT_ACCURATE_BBOXESra   r-   r+   Útextpage_flagsrg   ×   s0   € ÝÔ Ñ"Ô"ð 4¥wÔ'>ð 4Ý•wÔ3Ñ3Ð3Ý€Lr-   c                 ó”   — 	 | d         |d         k    o5| d         |d         k    o#| d         |d         k    o| d         |d         k    S )zBCheck whether rectangle 'inner' is fully inside rectangle 'outer'.r$   r   r%   é   ra   )ÚinnerÚouters     r+   Úrect_in_rectrl   ç   s_   € ð	!Ø�!ŒH˜˜aœÒ ð	!à�!ŒH˜˜aœÒ ð	!ð �!ŒH˜˜aœÒ ð	!ð �!ŒH˜˜aœÒ ðr-   c                 ó:   ‡— t          ˆfd„| D ¦   «         ¦  «        S )zCCheck whether any of the chars in CHAR are inside rectangle 'rect'.c              3   óª   •K  — | ]M}	 ‰d         |d         k    o5|d         ‰d         k    o#‰d          |d         k    o‰d         |d         k    V — ŒNdS )	r$   r   Úx0Úx1r%   Úy0ri   Úy1Nra   )r)   Úcr!   s     €r+   ú	<genexpr>z chars_in_rect.<locals>.<genexpr>ô   sŒ   øè è € ð ð ð ð	Ø�ŒG�q˜”wÒð	àˆdŒG�t˜A”wÒð	ð �ŒG�q˜”wÒð	ð �ŒG�q˜”wÒðð ð ð ð ð r-   ©Úany)ÚCHARSr!   s    `r+   Úchars_in_rectrx   ò   s=   ø€ åð ð ð ð ð ðñ ô ñ ô ð 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%   ri   r$   ©ÚmaxÚmin)Úr1Úr2ÚixÚiyÚintersectionÚarea1Úarea2s          r+   Ú_iour„   þ   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-   Úreturnc                 ó>   ‡ ‡— t          ˆ ˆfd„|D ¦   «         ¦  «        S )zUCheck whether any of the words in bbox are cut through by
    horizontal line y.
    c              3   ól   •K  — | ].}t          |‰¦  «        ¯|j        ‰cxk     o
|j        k     nc V — Œ/d S r;   )rl   rq   rr   )r)   ÚrÚbboxÚys     €€r+   rt   z%intersects_words_h.<locals>.<genexpr>  sJ   øè è € ÐLÐL 1µlÀ1ÀdÑ6KÔ6KÐLˆqŒt�aˆˆŠˆ˜!œ$ŠˆˆˆÐLÐLÐLÐLÐLÐLr-   ru   )r‰   rŠ   Ú
word_rectss   `` r+   Úintersects_words_hrŒ   
  s,   øø€ õ ÐLÐLÐLÐLÐL¨
ÐLÑLÔLÑLÔLÐLr-   c                 ó`   — i }t           j                             | j        j        ||¦  «         |S )zAExtract MuPDF table structure information from a given rectangle.)r'   ÚextraÚmake_table_dictÚthisÚ
m_internal)Útextpager!   Ú
table_dicts      r+   Úget_table_dict_from_rectr”     s,   € à€JÝ„M×!Ò! (¤-Ô":¸JÈÑMÔMÐMØÐr-   c           
      ó–  ‡‡‡— g }t          | |¦  «        }|                     d¦  «        t          j        k    r|S t	          j        |d         ¦  «        }t          |d         d„ ¬¦  «        }t          |d         d„ ¬¦  «        }|d         \  }Šg }	|D ]J\  }
}|d	k    rŒt          ||
|¦  «        rŒ|	r|
|	d
         z
  dk     r|
|	d
<   Œ5|	                     |
¦  «         ŒKt          d	t          t          |	¦  «        dz
  dz  ¦  «        ¦  «        Šˆfd„|D ¦   «         }|j        |d
         dz   k    r|                     |j        ¦  «         t          t          |	¦  «        dz
  ¦  «        D ]Þ}t	          j        |j        |	|         |j        |	|dz            ¦  «        Št          ˆfd„|D ¦   «         d„ ¬¦  «        Šˆfd„|D ¦   «         }t          t          |¦  «        dz
  ¦  «        D ]`}t	          j        ||         |	|         ||dz            |	|dz            ¦  «        }|j        s"|                     t!          |¦  «        ¦  «         ŒaŒß|S )z0Detect table structure within a given rectangle.Útyper‰   Úxposc                 ó   — | d         S ©Nr   ra   ©Úxs    r+   ú<lambda>z&make_table_from_bbox.<locals>.<lambda>$  ó
   € ¨q°¬t€ r-   ©r[   Úyposc                 ó   — | d         S r™   ra   )rŠ   s    r+   rœ   z&make_table_from_bbox.<locals>.<lambda>%  r�   r-   Úmax_uncertainr   éÿÿÿÿri   r%   gffffffÖ?c                 ó8   •— g | ]}|d          ‰k    ¯|d         ‘ŒS ©r$   r   ra   )r)   r›   Úymaxus     €r+   r,   z(make_table_from_bbox.<locals>.<listcomp>>  s&   ø€ Ð1Ð1Ð1�a 1 Q¤4¨5¢= =ˆQˆqŒT = = =r-   r$   c                 ó4   •— g | ]}t          |‰¦  «        ¯|‘ŒS ra   ©rl   )r)   rˆ   Úrow_boxs     €r+   r,   z(make_table_from_bbox.<locals>.<listcomp>G  s(   ø€ Ð?Ð?Ð?�1¥l°1°gÑ&>Ô&>Ð?ˆQÐ?Ð?Ð?r-   c                 ó   — | j         S r;   )ro   ©rˆ   s    r+   rœ   z&make_table_from_bbox.<locals>.<lambda>G  s   € ÈqÌt€ r-   c                 óL   •‡— g | ]Št          ˆfd „‰D ¦   «         ¦  «        °‰‘Œ S )c              3   óL   •K  — | ]}|j         ‰cxk     o
|j        k     nc V — Œd S r;   ©ro   rp   )r)   rˆ   r›   s     €r+   rt   z2make_table_from_bbox.<locals>.<listcomp>.<genexpr>J  s;   øè è € Ð0TÐ0TÀQ°´¸°°²°¸A¼D²°°°Ð0TÐ0TÐ0TÐ0TÐ0TÐ0Tr-   ru   )r)   r›   Ú	row_wordss    @€r+   r,   z(make_table_from_bbox.<locals>.<listcomp>J  s<   øø€ ÐUÐUÐU˜1­SÐ0TÐ0TÐ0TÐ0TÈ)Ð0TÑ0TÔ0TÑ-TÔ-TÐU�QÐUÐUÐUr-   )r”   rA   r   ÚFZ_STEXT_BLOCK_GRIDr'   r(   ÚsortedrŒ   r3   r{   ÚroundrX   rp   Úrangero   Úis_emptyÚtuple)r’   r‹   r!   ÚcellsÚblockr‰   r—   rŸ   ÚxmaxuÚnyposrŠ   ÚyuncÚnxposÚiÚ	this_xposÚjÚcellr¨   r®   r¥   s                    @@@r+   Úmake_table_from_bboxr¿     sƒ  øøø€ à€Eõ % X¨tÑ4Ô4€Eà‡y‚y�ÑÔ�EÔ5Ò5Ð5ØˆÝŒ<˜˜fœÑ&Ô&€Dõ �%˜”- ^ ^Ð4Ñ4Ô4€DÝ�%˜”- ^ ^Ð4Ñ4Ô4€Dð ˜Ô)�L€Eˆ5ð €EØð ð ‰ˆˆ4Ø�!Š8ˆ8ØÝ˜d A zÑ2Ô2ð 	ØØð 	�a˜% œ)‘m aÒ'Ð'ØˆE�"‰IˆIà�LŠL˜‰OŒOˆOˆOõ
 �•5�#˜e™*œ* q™.¨DÑ0Ñ1Ô1Ñ2Ô2€Eð 2Ð1Ð1Ð1˜4Ð1Ñ1Ô1€EØ„w��r”˜Q‘ÒÐØ�Š�T”WÑÔÐõ •3�u‘:”: ‘>Ñ"Ô"ð *ð *ˆÝ”,˜tœw¨¨a¬°$´'¸5ÀÀQÁ¼<ÑHÔHˆåØ?Ð?Ð?Ð?˜
Ð?Ñ?Ô?À^À^ð
ñ 
ô 
ˆ	ð VÐUÐUÐU ÐUÑUÔUˆ	Ý•s˜9‘~”~¨Ñ)Ñ*Ô*ð 	*ð 	*ˆAÝ”< 	¨!¤¨e°A¬h¸	À!ÀaÁ%Ô8HÈ%ÐPQÐTUÑPUÌ,ÑWÔWˆDØ”=ð *Ø—’�U 4™[œ[Ñ)Ô)Ð)øð	*ð
 €Lr-   c           	      óâ  — d}|                       ¦   «         d         D �]¾}|d         dk    rŒ|d         }	 	 |d         |d         k    s6|d         |d         k     s$|d         |d         k    s|d         |d         k     rŒc|d	         D �]Q}|d         }	 	 |d         |d         k    s6|d         |d         k     s$|d         |d         k    s|d         |d         k     rŒV|r	||rd
ndz  }|d         dk    p|d         dk    }|d         D �]Î}	|	d         }
	 	 |
d         |d         k    s6|
d         |d         k     s$|
d         |d         k    s|
d         |d         k     rŒVd}|	d         D ]^}|d         }t          j        |d         ¦  «        }t          ||z  ¦  «        dt          |¦  «        z  k    r||z  }ŒP|t          v r|dz  }Œ_|sŒÂ|s||z  }ŒÊd}d}|r|	d         t
          z  r
|dz  }d|z   }|	d         t          z  r
|dz  }d|z   }|	d         t          j        z  r
|dz  }d|z   }|	d         t          j        z  r
|dz  }d|z   }t          |	d         ¦  «        dk    r| 
                    ¦   «         }t          |¦  «        x}r(|                     |¦  «        r|d| …         |z   |z   }�Œ¨|                     ¦   «         s|dz  }�ŒÃ|||z   |z   z  }�ŒÐ�ŒS�ŒÀ|                     ¦   «         S )aE  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:
        textpage: A PyMuPDF TextPage object. Must have been created with
            TEXTFLAGS_TEXT | TEXT_COLLECT_STYLES.
        cell: A tuple (x0, y0, x1, y1) defining the cell's bbox.
        markdown: If True, return text formatted for Markdown.

    Returns:
        A string with the text extracted from the cell.
    Ú Úblocksr–   r   r‰   r%   r$   ri   Úlinesú<br>ú
Údir)r   r$   r¤   ÚspansÚcharsrs   g      à?ú Ú
char_flagsz~~z**ÚflagsÚ_ú`N)ÚextractRAWDICTr'   r(   ÚabsÚwhite_spacesÚTEXT_STRIKEOUTÚ	TEXT_BOLDÚTEXT_FONT_ITALICÚTEXT_FONT_MONOSPACEDrX   ÚrstripÚendswithÚstrip)r’   r¾   ÚmarkdownÚtextr¶   Ú
block_bboxÚlineÚlbboxÚ
horizontalÚspanÚsbboxÚ	span_textÚcharÚ	this_charr‰   ÚprefixÚsuffixÚlss                     r+   Úextract_cellsræ   S  s·  € ð  €DØ×(Ò(Ñ*Ô*¨8Ô4ð R<ñ R<ˆØ�Œ=˜AÒÐØØ˜6”]ˆ
àð	à˜!Œ}˜t AœwÒ&Ð&Ø˜!Œ}˜t AœwÒ&Ð&Ø˜!Œ}˜t AœwÒ&Ð&Ø˜!Œ}˜t AœwÒ&Ð&àØ˜'”Nð F	<ñ F	<ˆDØ˜”LˆEàðà˜”8˜d 1œgÒ%Ð%Ø˜”8˜d 1œgÒ%Ð%Ø˜”8˜d 1œgÒ%Ð%Ø˜”8˜d 1œgÒ%Ð%ààð 5Ø (Ð4˜˜°Ñ4�ð ˜eœ¨Ò.ÐG°$°u´+ÀÒ2GˆJà˜Wœð 5<ñ 5<�Ø˜Vœ�àðà˜Q”x $ q¤'Ò)Ð)Ø˜Q”x $ q¤'Ò)Ð)Ø˜Q”x $ q¤'Ò)Ð)Ø˜Q”x $ q¤'Ò)Ð)àð �	Ø  œMð )ð )�DØ $ S¤	�IÝ"œ<¨¨V¬Ñ5Ô5�DÝ˜4 $™;Ñ'Ô'¨#µ°D±	´	©/Ò9Ð9Ø! YÑ.˜	˜	Ø"¥lÐ2Ð2Ø! SÑ(˜	øà ð Øàð Ø˜IÑ%�DØà�Ø�Øð + $ |Ô"4µ~Ñ"Eð +Ø˜d‘N�FØ! F™]�FØ˜Ô%­	Ñ1ð +Ø˜d‘N�FØ! F™]�FØ˜”=¥7Ô#;Ñ;ð *Ø˜c‘M�FØ  6™\�FØ˜”=¥7Ô#?Ñ?ð *Ø˜c‘M�FØ  6™\�Få�t˜G”}Ñ%Ô%¨Ò)Ð)Ø )× 0Ò 0Ñ 2Ô 2�Iõ ˜f™+œ+Ð%�Bð <¨4¯=ª=¸Ñ+@Ô+@ð <Ø  "  œ:¨	Ñ1°FÑ:�D‘Dà$Ÿ?š?Ñ,Ô,ð <Ø ™˜™à ¨Ñ 2°VÑ ;Ñ;˜™ñk5<ñ#F	<ðP �:Š:‰<Œ<Ðr-   c                   ó   — e Zd ZdS )Ú
UnsetFloatN©r]   r^   r_   ra   r-   r+   rè   rè   À  ó   € € € € € Ø€Dr-   rè   )Úsnap_toleranceÚsnap_x_toleranceÚsnap_y_toleranceÚjoin_toleranceÚjoin_x_toleranceÚjoin_y_toleranceÚedge_min_lengthÚmin_words_verticalÚmin_words_horizontalÚintersection_toleranceÚintersection_x_toleranceÚintersection_y_tolerance)rÃ   Úlines_strictrÙ   Úexplicitri   r$   g      @é   ro   Útoprp   ÚbottomÚffÚffiÚfflÚfiÚflÚst)u   ï¬€u   ï¬ƒu   ï¬„u   ï¬�u   ï¬‚u   ï¬†u   ï¬…c                 óä   — t          | t          ¦  «        r| S t          | t          ¦  «        rt          | ¦  «        S t          | d¦  «        r|                      d¦  «        }|S t          | ¦  «        S )NÚto_dictÚrecords)Ú
isinstanceÚlistr   Úhasattrr  )Ú
collectionÚress     r+   Úto_listr
  ì  sr   € Ý�*�dÑ#Ô#ð  ØÐÝ	�J¥Ñ	)Ô	)ð  Ý�JÑÔÐÝ	�˜YÑ	'Ô	'ð  Ø× Ò  Ñ+Ô+ˆØˆ
å�JÑÔÐr-   c            	       ó<   — e Zd ZdZddd„Z	 	 	 ddeded	edefd
„ZdS )ÚTextMapz–
    A TextMap maps each unicode character in the text to an individual `char`
    object (or, in the case of layout-implied whitespace, `None`).
    Nr…   c                 ó~   — || _         d                     t          t          d¦  «        |¦  «        ¦  «        | _        d S )NrÁ   r   )ÚtuplesÚjoinÚmapr   Ú	as_string©r=   r  s     r+   r?   zTextMap.__init__þ  s0   € ØˆŒØŸš¥¥Z°¡]¤]°FÑ!;Ô!;Ñ<Ô<ˆŒˆˆr-   r   TÚ
main_groupÚreturn_groupsÚreturn_charsc                 ó&  — | j         |                     |¦  «        |                     |¦  «        …         }d„ |D ¦   «         }t          |¦  «        \  }}}	}
|                     |¦  «        |||	|
dœ}|r|                     ¦   «         |d<   |r||d<   |S )Nc                 ó   — g | ]	\  }}|®|‘Œ
S r;   ra   )r)   rÙ   rs   s      r+   r,   z)TextMap.match_to_dict.<locals>.<listcomp>
  s   € Ð<Ð<Ð<‘y˜˜a¨a¨m�¨m¨m¨mr-   ©rÙ   ro   rú   rp   rû   ÚgroupsrÈ   )r  ÚstartÚendÚobjects_to_bboxÚgroupr  )r=   Úmr  r  r  ÚsubsetrÈ   ro   rú   rp   rû   Úresults               r+   Úmatch_to_dictzTextMap.match_to_dict  s±   € ð ”˜QŸWšW ZÑ0Ô0°1·5²5¸Ñ3DÔ3DÐDÔEˆØ<Ð< FÐ<Ñ<Ô<ˆÝ-¨eÑ4Ô4ÑˆˆC��Vð —G’G˜JÑ'Ô'ØØØØð
ð 
ˆð ð 	*Ø Ÿxšx™zœzˆF�8Ñàð 	$Ø#ˆF�7‰Oàˆr-   r;   ©r…   N)r   TT)	r]   r^   r_   r`   r?   ÚintrN   r/   r!  ra   r-   r+   r  r  ø  sƒ   € € € € € ðð ð
=ð =ð =ð =ð =ð Ø"Ø!ðð ð ðð ð	ð
 ðð 
ðð ð ð ð ð r-   r  c                   óZ   — e Zd ZdZdd„Zdddddeeddedddfded	e	d
e	dededede
fd„ZdS )ÚWordMapz&
    A WordMap maps words->chars.
    r…   Nc                 ó   — || _         d S r;   )r  r  s     r+   r?   zWordMap.__init__#  s   € ØˆŒˆˆr-   Fr   TÚlayoutÚlayout_width_charsÚlayout_height_charsÚuse_text_flowÚ	presortedÚexpand_ligaturesc                 ó®  — g }t          | j        ¦  «        st          |¦  «        S |rt          ni }|rm|r|rt	          d¦  «        ‚nt          t          ||z  ¦  «        ¦  «        }|r|rt	          d¦  «        ‚nt          t          ||z  ¦  «        ¦  «        }dg|z  }ng }d}|s|r| j        nt          | j        d„ ¬¦  «        }|d         d         }|d         |d         z
  }t          t          |d	„ |
¦  «        ¦  «        D �]p\  }}|r|d         d         d         ||	z   z
  |z  nd}t          t          |dk    ¦  «        t          |¦  «        |z
  ¦  «        }t          |¦  «        D ]=}t          |¦  «        r|d
         d         dk    r||z  }|                     d¦  «         Œ>||z  }d}|s|r|nt          |d„ ¬¦  «        }|D ]›\  }}|r|d         |z
  |z  nd}t          t          d|¦  «        t          |¦  «        |z
  ¦  «        }|dg|z  z  }||z  }|D ]E}|                     |d         |d         ¦  «        } | D ]}!|                     |!|f¦  «         |dz  }ŒŒFŒœ|r|dg||z
  z  z  }�Œr|rP||dz   z
  }"t          |"¦  «        D ]"}|dk    r||z  }|                     d¦  «         Œ#|d
         dk    r
|dd
…         }t          |¦  «        S )aÇ  
        Given a list of (word, chars) tuples (i.e., a WordMap), return a list of
        (char-text, char) tuples (i.e., a TextMap) that can be used to mimic the
        structural layout of the text on the page(s), using the following approach:

        - Sort the words by (doctop, x0) if not already sorted.

        - Calculate the initial doctop for the starting page.

        - Cluster the words by doctop (taking `y_tolerance` into account), and
          iterate through them.

        - For each cluster, calculate the distance between that doctop and the
          initial doctop, in points, minus `y_shift`. Divide that distance by
          `y_density` to calculate the minimum number of newlines that should come
          before this cluster. Append that number of newlines *minus* the number of
          newlines already appended, with a minimum of one.

        - Then for each cluster, iterate through each word in it. Divide each
          word's x0, minus `x_shift`, by `x_density` to calculate the minimum
          number of characters that should come before this cluster.  Append that
          number of spaces *minus* the number of characters and spaces already
          appended, with a minimum of one. Then append the word's text.

        - At the termination of each line, add more spaces if necessary to
          mimic `layout_width`.

        - Finally, add newlines to the end if necessary to mimic to
          `layout_height`.

        Note: This approach currently works best for horizontal, left-to-right
        text, but will display all words regardless of orientation. There is room
        for improvement in better supporting right-to-left text, as well as
        vertical text.
        z;`layout_width` and `layout_width_chars` cannot both be set.z=`layout_height` and `layout_height_chars` cannot both be set.)rÉ   Nr   c                 ó8   — t          | d         d         ¦  «        S ©Nr   Údoctop©Úfloatrš   s    r+   rœ   z$WordMap.to_textmap.<locals>.<lambda>z  s   € µ5¸¸1¼¸h¼Ñ3HÔ3H€ r-   rž   r0  rú   c                 ó8   — t          | d         d         ¦  «        S r/  r1  rš   s    r+   rœ   z$WordMap.to_textmap.<locals>.<lambda>‚  s   € ­u°Q°q´T¸(´^Ñ/DÔ/D€ r-   r¢   rÅ   )rÅ   Nc                 ó8   — t          | d         d         ¦  «        S )Nr   ro   r1  rš   s    r+   rœ   z$WordMap.to_textmap.<locals>.<lambda>�  s   € ­e°A°a´D¸´JÑ.?Ô.?€ r-   ro   r$   rÙ   N)rX   r  r  Ú	LIGATURESÚ
ValueErrorr#  r±   r°   Ú	enumerateÚcluster_objectsr{   r²   r3   r|   rA   )#r=   r'  Úlayout_widthÚlayout_heightr(  r)  Ú	x_densityÚ	y_densityÚx_shiftÚy_shiftÚy_tolerancer*  r+  r,  Ú_textmapÚ
expansionsÚ
blank_lineÚnum_newlinesÚwords_sorted_doctopÚ
first_wordÚdoctop_startr»   ÚwsÚy_distÚnum_newlines_prependÚline_lenÚline_words_sorted_x0ÚwordrÈ   Úx_distÚnum_spaces_prependrs   ÚlettersÚletterÚnum_newlines_appends#                                      r+   Ú
to_textmapzWordMap.to_textmap&  sõ  € ðf ˆå�4”;ÑÔð 	%Ý˜8Ñ$Ô$Ð$à"2Ð:•Y�Y¸ˆ
àð 	Ø!ð JØð Ý$ØUñô ð ðõ
 &)­¨|¸iÑ/GÑ)HÔ)HÑ%IÔ%IÐ"à"ð LØ ð Ý$ØWñô ð ðõ
 '*­%°À	Ñ0IÑ*JÔ*JÑ&KÔ&KÐ#à%˜Ð);Ñ;ˆJˆJàˆJàˆð ðJØ)ðJˆDŒKˆKå˜œÐ)HÐ)HÐIÑIÔIð 	ð )¨Ô+¨AÔ.ˆ
Ø! (Ô+¨j¸Ô.?Ñ?ˆåÝØ#Ð%DÐ%DÀkñô ñ
ô 
ð .	Lñ .	L‰EˆAˆrð ð��A”�q”˜(Ô# |°gÑ'=Ñ>À)ÑKÐKàð õ
 $'å�A˜’E‘
”
å�f‘” Ñ,ñ	$ô $Ð õ Ð/Ñ0Ô0ð .ð .�Ý˜8‘}”}ð +¨°¬°Q¬¸4Ò(?Ð(?Ø 
Ñ*�HØ—’ Ñ-Ô-Ð-Ð-àÐ0Ñ0ˆLàˆHð ðAØ -ðA��å˜BÐ$?Ð$?Ð@Ñ@Ô@ð !ð  4ð 
&ð 
&‘��eØ?EÐL˜$˜tœ* wÑ.°)Ñ;Ð;È1�Ý%(­¨Q°Ñ)9Ô)9½5À¹=¼=È8Ñ;SÑ%TÔ%TÐ"Ø˜[˜MÐ,>Ñ>Ñ>�ØÐ.Ñ.�àð &ð &�AØ(Ÿnšn¨Q¨v¬Y¸¸&¼	ÑBÔB�GØ")ð &ð &˜Ø Ÿš¨°¨Ñ4Ô4Ð4Ø  A™˜˜ð&ð&ð ð LØ˜[˜MÐ-?À(Ñ-JÑKÑK�ùð ð 		)Ø"5¸ÈÑ9IÑ"JÐÝÐ.Ñ/Ô/ð .ð .�Ø�q’5�5Ø 
Ñ*�HØ—’ Ñ-Ô-Ð-Ð-ð ˜Œ|˜|Ò+Ð+Ø# C R Cœ=�å�xÑ Ô Ð r-   r"  )r]   r^   r_   r`   r?   ÚDEFAULT_X_DENSITYÚDEFAULT_Y_DENSITYÚDEFAULT_Y_TOLERANCErN   r#  r  rR  ra   r-   r+   r%  r%    sÆ   € € € € € ðð ðð ð ð ð
 ØØØ"#Ø#$Ø#Ø#ØØØ'Ø#ØØ!%ðV!ð V!àðV!ð
  ðV!ð !ðV!ð ðV!ð ðV!ð ðV!ð 
ðV!ð V!ð V!ð V!ð V!ð V!r-   r%  c            	       ót   — e Zd Zeedddddddf	defd„Zdefd„Zdefd	„Z	d
„ Z
d„ Zd„ Zdefd„Zdedefd„ZdS )ÚWordExtractorFTNÚkeep_blank_charsc
                 óÂ   — || _         || _        || _        || _        || _        || _        |€g n|| _        |du rt          j        n|pd| _	        |	rt          ni | _        d S )NTrÁ   )Úx_tolerancer?  rX  r*  Úhorizontal_ltrÚvertical_ttbÚextra_attrsÚstringÚpunctuationÚsplit_at_punctuationr5  rA  )
r=   rZ  r?  rX  r*  r[  r\  r]  r`  r,  s
             r+   r?   zWordExtractor.__init__À  sƒ   € ð 'ˆÔØ&ˆÔØ 0ˆÔØ*ˆÔØ,ˆÔØ(ˆÔØ!,Ð!4˜2˜2¸+ˆÔð
 $ tÐ+Ð+õ ÔÐà&Ð,¨"ð 	Ô!ð (8Ð?�)˜)¸RˆŒˆˆr-   Úordered_charsc           
      óò  ‡ — t          |¦  «        \  }}}}|d         d         |d         d         z
  }|d         d         }|r‰ j        r
n‰ j        rdnd}|d         d         }	d}
|s|	d         dk     rt          |¦  «        }d}
|	d         dk     r|	d	         dk     rd
}
n|	d         dk    rd}
d                     ˆ fd„|D ¦   «         ¦  «        |||||z   ||||
dœ	}‰ j        D ]}|d         |         ||<   Œ|S )Nr   r0  rú   Úuprightr$   r¢   Úmatrixé  ri   é´   éZ   rÁ   c              3   óf   •K  — | ]+}‰j                              |d          |d          ¦  «        V — Œ,dS ©rÙ   N)rA  rA   )r)   rs   r=   s     €r+   rt   z,WordExtractor.merge_chars.<locals>.<genexpr>ð  sN   øè è € ð ð Ø>?�”×#Ò# A f¤I¨q°¬yÑ9Ô9ðð ð ð ð ð r-   )	rÙ   ro   rp   rú   r0  rû   rc  Ú	directionÚrotation)r  r[  r\  Úreversedr  r]  )r=   ra  ro   rú   rp   rû   Ú
doctop_adjrc  rj  rd  rk  rL  r[   s   `            r+   Úmerge_charszWordExtractor.merge_charsÝ  sf  ø€ Ý-¨mÑ<Ô<ÑˆˆC��VØ" 1Ô% hÔ/°-ÀÔ2BÀ5Ô2IÑIˆ
Ø Ô" 9Ô-ˆØ18ÐX˜$Ô-ÐXÐX¸dÔ>OÐX�A�AÐVXˆ	à˜qÔ! (Ô+ˆàˆØð 	˜6 !œ9 qš=˜=Ý$ ]Ñ3Ô3ˆMØˆHà�!Œ9�qŠ=ˆ=˜V AœY¨š]˜]ØˆHˆHØ�AŒY˜Š]ˆ]ØˆHð —G’Gð ð ð ð ØCPðñ ô ñ ô ð ØØØ˜JÑ&ØØØ"Ø ð
ð 
ˆð Ô#ð 	.ð 	.ˆCØ% aÔ(¨Ô-ˆD�‰IˆIàˆr-   r…   c                 óÂ  — |d         rZ| j         }| j        }|d         }|d         }| j        r|d         }|d         }|d         }	nu|d          }|d          }|d          }	nY| j        }| j         }|d         }|d         }| j        r|d         }|d         }|d         }	n|d          }|d          }|d          }	t	          |	|k     p|	||z   k    p|||z   k    ¦  «        S )a”  This method takes several factors into account to determine if
        `curr_char` represents the beginning of a new word:

        - Whether the text is "upright" (i.e., non-rotated)
        - Whether the user has specified that horizontal text runs
          left-to-right (default) or right-to-left, as represented by
          self.horizontal_ltr
        - Whether the user has specified that vertical text the text runs
          top-to-bottom (default) or bottom-to-top, as represented by
          self.vertical_ttb
        - The x0, top, x1, and bottom attributes of prev_char and
          curr_char
        - The self.x_tolerance and self.y_tolerance settings. Note: In
          this case, x/y refer to those directions for non-rotated text.
          For vertical text, they are flipped. A more accurate terminology
          might be "*intra*line character distance tolerance" and
          "*inter*line character distance tolerance"

        An important note: The *intra*line distance is measured from the
        *end* of the previous character to the *beginning* of the current
        character, while the *inter*line distance is measured from the
        *top* of the previous character to the *top* of the next
        character. The reasons for this are partly repository-historical,
        and partly logical, as successive text lines' bounding boxes often
        overlap slightly (and we don't want that overlap to be interpreted
        as the two lines being the same line).

        The upright-ness of the character determines the attributes to
        compare, while horizontal_ltr/vertical_ttb determine the direction
        of the comparison.
        rc  rú   ro   rp   rû   )rZ  r?  r[  r\  rN   )
r=   Ú	prev_charÚ	curr_charr›   rŠ   ÚayÚcyÚaxÚbxÚcxs
             r+   Úchar_begins_new_wordz"WordExtractor.char_begins_new_word  s5  € ðN �YÔð 	*ØÔ ˆAØÔ ˆAØ˜5Ô!ˆBØ˜5Ô!ˆBØÔ"ð &Ø˜t”_�Ø˜t”_�Ø˜t”_��à ”oÐ%�Ø ”oÐ%�Ø ”oÐ%��ð Ô ˆAØÔ ˆAØ˜4”ˆBØ˜4”ˆBØÔ ð *Ø˜uÔ%�Ø˜xÔ(�Ø˜uÔ%��à Ô)Ð)�Ø Ô&Ð&�Ø Ô)Ð)�åà�"ŠWð Ø�R˜!‘V’ðð �R˜!‘V’ñ
ô 
ð 	
r-   c              #   ó‚  ‡K  — g Šdˆfd„	}|D ]¨}|d         }| j         s&|                     ¦   «         r |d ¦  «        E d {V —† Œ7|| j        v r# ||¦  «        E d {V —†  |d ¦  «        E d {V —† Œc‰r.|                      ‰d         |¦  «        r ||¦  «        E d {V —† Œ“‰                     |¦  «         Œ©‰r‰V — d S d S )Nc              3   ó&   •K  — ‰r‰V — | €g n| gŠd S r;   ra   )Únew_charÚcurrent_words    €r+   Ústart_next_wordz:WordExtractor.iter_chars_to_words.<locals>.start_next_wordP  s1   øè è € ð ð #Ø"Ð"Ð"Ð"à!)Ð!1˜2˜2¸°zˆLˆLˆLr-   rÙ   r¢   r;   )rX  Úisspacer`  rw  r3   )r=   ra  r|  rá   rÙ   r{  s        @r+   Úiter_chars_to_wordsz!WordExtractor.iter_chars_to_wordsM  sf  øè è € Øˆð	Bð 	Bð 	Bð 	Bð 	Bð 	Bð "ð 	*ð 	*ˆDØ˜”<ˆDàÔ(ð *¨T¯\ª\©^¬^ð *Ø*˜?¨4Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0à˜Ô2Ð2Ð2Ø*˜?¨4Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ø*˜?¨4Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0àð * $×";Ò";¸LÈÔ<LÈdÑ"SÔ"Sð *Ø*˜?¨4Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0ð ×#Ò# DÑ)Ô)Ð)Ð)ð ð 	ØÐÐÐÐÐð	ð 	r-   c              #   ó€  K  — dt           fd„}t          t          |¦  «        |d¦  «        D ]‘}|d         d         }|rdnd}t          |t          |¦  «        | j        ¦  «        }|D ]U}|rdnd}t          |t          |¦  «        ¬¦  «        }	|r| j        sn| j        st          |	¦  «        E d {V —† ŒM|	E d {V —† ŒVŒ’d S )Nr…   c                 ó.   — t          | d         ¦  «         S ©Nrc  )r#  rš   s    r+   Úupright_keyz2WordExtractor.iter_sort_chars.<locals>.upright_keym  s   € Ý˜˜)œÑ%Ô%Ð%Ð%r-   r   rc  r0  ro   rž   )	r#  r8  r  r   r?  r°   r[  r\  rl  )
r=   rÈ   r‚  Úupright_clusterrc  Úcluster_keyÚsubclustersÚscÚsort_keyÚto_yields
             r+   Úiter_sort_charszWordExtractor.iter_sort_charsl  s-  è è € ð	&�cð 	&ð 	&ð 	&ð 	&õ  /­t°E©{¬{¸KÈÑKÔKð 	(ð 	(ˆOØ% aÔ(¨Ô3ˆGØ&-Ð7˜(˜(°4ˆKõ *Ø¥¨KÑ!8Ô!8¸$Ô:Jñô ˆKð "ð 	(ð 	(�à#*Ð8˜4˜4°�Ý! "­*°XÑ*>Ô*>Ð?Ñ?Ô?�ð 07ð (˜Ô+ð (ð (¸DÔ<Mð (Ý'¨Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1à'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ð'ð	(ð	(ð 	(r-   c              #   ó  K  — | j         r|n|                      |¦  «        }t          dg| j        ¢R Ž }t	          j        ||¦  «        }|D ]6\  }}|                      |¦  «        D ]}|                      |¦  «        |fV — ŒŒ7d S r�  )r*  r‰  r   r]  Ú	itertoolsÚgroupbyr~  rn  )r=   rÈ   ra  Úgrouping_keyÚgrouped_charsÚkeyvalsÚ
char_groupÚ
word_charss           r+   Úiter_extract_tuplesz!WordExtractor.iter_extract_tuples„  s¸   è è € Ø!%Ô!3ÐT˜˜¸×9MÒ9MÈeÑ9TÔ9Tˆå! )Ð?¨dÔ.>Ð?Ð?Ð?ˆÝ!Ô)¨-¸ÑFÔFˆà#0ð 	Að 	AÑˆG�ZØ"×6Ò6°zÑBÔBð Að A�
Ø×'Ò'¨
Ñ3Ô3°ZÐ@Ð@Ð@Ð@Ð@ðAð	Að 	Ar-   c                 ó`   — t          t          |                      |¦  «        ¦  «        ¦  «        S r;   )r%  r  r’  )r=   rÈ   s     r+   Úextract_wordmapzWordExtractor.extract_wordmapŽ  s&   € Ý•t˜D×4Ò4°UÑ;Ô;Ñ<Ô<Ñ=Ô=Ð=r-   rÈ   c                 ó^   — t          d„ |                      |¦  «        D ¦   «         ¦  «        }|S )Nc              3   ó    K  — | ]	\  }}|V — Œ
d S r;   ra   )r)   rL  r‘  s      r+   rt   z.WordExtractor.extract_words.<locals>.<genexpr>’  s'   è è € ÐRÐRÑ.˜d J�TÐRÐRÐRÐRÐRÐRr-   )r  r’  )r=   rÈ   Úwordss      r+   Úextract_wordszWordExtractor.extract_words‘  s1   € ÝÐRÐR°$×2JÒ2JÈ5Ñ2QÔ2QÐRÑRÔRÑRÔRˆØˆr-   )r]   r^   r_   ÚDEFAULT_X_TOLERANCErU  rN   r?   r  rn  rw  r~  r‰  r’  r%  r”  r˜  ra   r-   r+   rW  rW  ¿  s  € € € € € ð (Ø'Ø!&ØØØØØ"Øð@ð @ð ð	@ð @ð @ð @ð:#¨ð #ð #ð #ð #ðJI
ð 
ð	I
ð I
ð I
ð I
ðVð ð ð>(ð (ð (ð0Að Að Að>¨ð >ð >ð >ð >ð 4ð ¨Dð ð ð ð ð ð r-   rW  rÈ   c                 ó@   — t          di |¤Ž                     | ¦  «        S )Nra   )rW  r˜  )rÈ   Úkwargss     r+   r˜  r˜  –  s$   € ÝÐ"Ð"˜6Ð"Ð"×0Ò0°Ñ7Ô7Ð7r-   c                 óÖ   ‡— ‰                      ddi¦  «         t          di ˆfd„t          D ¦   «         ¤Ž}|                     | ¦  «        } |j        di ˆfd„t
          D ¦   «         ¤Ž}|S )Nr+  Tc                 ó*   •— i | ]}|‰v ¯|‰|         “ŒS ra   ra   ©r)   Úkr›  s     €r+   ú
<dictcomp>z$chars_to_textmap.<locals>.<dictcomp>¢  s$   ø€ Ð
FÐ
FÐ
F˜A¸!¸v¸+¸+ˆ1ˆf�QŒi¸+¸+¸+r-   c                 ó*   •— i | ]}|‰v ¯|‰|         “ŒS ra   ra   rž  s     €r+   r   z$chars_to_textmap.<locals>.<dictcomp>¦  s$   ø€ Ð
?Ð
?Ð
?˜A°1¸°;°;ˆ1ˆf�QŒi°;°;°;r-   ra   )ÚupdaterW  ÚWORD_EXTRACTOR_KWARGSr”  rR  ÚTEXTMAP_KWARGS)rÈ   r›  Ú	extractorÚwordmapÚtextmaps    `   r+   Úchars_to_textmapr¨  ž  sœ   ø€ Ø
‡M‚M�; Ð%Ñ&Ô&Ð&åð ð Ø
FÐ
FÐ
FÐ
FÕ!6Ð
FÑ
FÔ
Fðð €Ið ×'Ò'¨Ñ.Ô.€GØ ˆgÔ ð ð Ø
?Ð
?Ð
?Ð
?¥Ð
?Ñ
?Ô
?ðð €Gð €Nr-   c                 ó0  ‡— t          | ¦  «        } t          | ¦  «        dk    rdS ‰                     d¦  «        rt          | fi ‰¤Žj        S ‰                     dt
          ¦  «        }t          di ˆfd„t          D ¦   «         ¤Ž}|                     | ¦  «        }|r|d         d         }nd}|dk    r7| 	                    d„ ¬	¦  «         d
 
                    d„ |D ¦   «         ¦  «        }n¬|dk    r7| 	                    d„ ¬	¦  «         d
 
                    d„ |D ¦   «         ¦  «        }not          |t          d¦  «        |¦  «        }d 
                    d„ |D ¦   «         ¦  «        }|dk    r,d 
                    d„ t          |¦  «        D ¦   «         ¦  «        }|S )Nr   rÁ   r'  r?  c                 ó*   •— i | ]}|‰v ¯|‰|         “ŒS ra   ra   rž  s     €r+   r   z extract_text.<locals>.<dictcomp>¶  s$   ø€ ÐJÐJÐJ ¸aÀ6¸k¸kˆq�&˜”)¸k¸k¸kr-   rk  rg  c                 ó$   — | d         | d          fS ©Nrp   rú   ra   ©Úws    r+   rœ   zextract_text.<locals>.<lambda>¿  s   €  a¨¤g°°%´¨yÐ%9€ r-   rž   rÉ   c                 ó   — g | ]
}|d          ‘ŒS ©rÙ   ra   ©r)   r®  s     r+   r,   z extract_text.<locals>.<listcomp>À  ó   € Ð7Ð7Ð7¨A˜a œiÐ7Ð7Ð7r-   re  c                 ó$   — | d          | d         fS r¬  ra   r­  s    r+   rœ   zextract_text.<locals>.<lambda>Â  s   €  q¨¤w h°°%´Ð%9€ r-   c                 ó   — g | ]
}|d          ‘ŒS r°  ra   r±  s     r+   r,   z extract_text.<locals>.<listcomp>Ã  r²  r-   r0  rÅ   c              3   óT   K  — | ]#}d                       d„ |D ¦   «         ¦  «        V — Œ$dS )rÉ   c              3   ó&   K  — | ]}|d          V — ŒdS ri  ra   )r)   rL  s     r+   rt   z)extract_text.<locals>.<genexpr>.<genexpr>Æ  s&   è è € Ð&EÐ&E¸ t¨F¤|Ð&EÐ&EÐ&EÐ&EÐ&EÐ&Er-   N)r  )r)   rÛ   s     r+   rt   zextract_text.<locals>.<genexpr>Æ  s=   è è € ÐXÐXÈ$˜cŸhšhÐ&EÐ&EÀÐ&EÑ&EÔ&EÑEÔEÐXÐXÐXÐXÐXÐXr-   rf  c                 ó"   — g | ]}|d k    r|nd‘ŒS )rÅ   rÉ   ra   ©r)   rs   s     r+   r,   z extract_text.<locals>.<listcomp>È  s$   € Ð TÐ TÐ T¸q q¨D¢y y ! !°cÐ TÐ TÐ Tr-   ra   )r
  rX   rA   r¨  r  rU  rW  r£  r˜  Úsortr  r8  r   rl  )rÈ   r›  r?  r¥  r—  rk  rÃ   s    `     r+   Úextract_textrº  ¬  sº  ø€ Ý�E‰NŒN€EÝ
ˆ5�z„z�Q‚€Øˆrà‡z‚z�(ÑÔð Ý Ð0Ð0¨Ð0Ð0Ô:Ð:à—j’j Õ0CÑDÔDˆÝ!ð 
ð 
ØJÐJÐJÐJÕ%:ÐJÑJÔJð
ð 
ˆ	ð ×'Ò'¨Ñ.Ô.ˆØð 	Ø˜Q”x 
Ô+ˆHˆHàˆHà�rŠ>ˆ>Ø�JŠJÐ9Ð9ˆJÑ:Ô:Ð:Ø—H’HÐ7Ð7°Ð7Ñ7Ô7Ñ8Ô8ˆEˆEØ˜Š_ˆ_Ø�JŠJÐ9Ð9ˆJÑ:Ô:Ð:Ø—H’HÐ7Ð7°Ð7Ñ7Ô7Ñ8Ô8ˆEˆEå# E­:°hÑ+?Ô+?ÀÑMÔMˆEØ—I’IÐXÐXÐRWÐXÑXÔXÑXÔXˆEØ˜3ŠˆØŸšÐ TÐ TÅHÈUÁOÄOÐ TÑ TÔ TÑUÔU�àˆr-   Ú
line_charsc                 ó¢   — d}d }t          | t          d¦  «        ¬¦  «        D ]+}|�|d         ||z   k    r|dz  }|d         }||d         z  }Œ,|S )NrÁ   ro   rž   rÉ   rp   rÙ   )r°   r   )r»  Ú	toleranceÚcollÚlast_x1rá   s        r+   Úcollate_linerÀ  Í  sr   € ð €DØ€GÝ�z¥z°$Ñ'7Ô'7Ð8Ñ8Ô8ð ð ˆØÐ d¨4¤j°G¸iÑ4GÒ&HÐ&HØ�C‰KˆDØ�t”*ˆØ��V”ÑˆˆØ€Kr-   c                 ó¬   ‡‡‡— t          dddd¦  «        Št          dd¦  «        Šdt          fˆˆˆfd„} || ¦  «        }t          || j        ¬	¦  «        S )
uœ   
    Removes duplicate chars â€”Â those sharing the same text, fontname, size,
    and positioning (within `tolerance`) as other characters in the set.
    ÚfontnameÚsizerc  rÙ   r0  ro   rÈ   c              3   ó6  •K  — t          | ‰¬¦  «        }t          j        |‰¬¦  «        D ]m\  }}t          t	          |¦  «        t          d¦  «        ‰¦  «        D ]<}t          |t          d¦  «        ‰¦  «        D ]}t          |‰¬¦  «        d         V — ŒŒ=Œnd S )Nrž   r0  ro   r   )r°   r‹  rŒ  r8  r  r   )	rÈ   Úsorted_charsÚgrpÚ	grp_charsÚ	y_clusterÚ	x_clusterr[   Úpos_keyr½  s	         €€€r+   Úyield_unique_charsz(dedupe_chars.<locals>.yield_unique_charsã  sË   øè è € Ý˜e¨Ð-Ñ-Ô-ˆÝ'Ô/°À#ÐFÑFÔFð 	<ð 	<‰NˆC�Ý,Ý�Y‘”¥¨HÑ!5Ô!5°yñô ð <ð <�	õ "1Ø�z¨$Ñ/Ô/°ñ"ô "ð <ð <�Iõ ! °Ð8Ñ8Ô8¸Ô;Ð;Ð;Ð;Ð;ð<ð<ð	<ð 	<r-   rž   )r   r  r°   Úindex)rÈ   r½  rË  Údedupedr[   rÊ  s    `  @@r+   Údedupe_charsrÎ  Û  s   øøø€ õ
 �Z ¨°FÑ
;Ô
;€CÝ˜ 4Ñ(Ô(€Gð	<¥$ð 	<ð 	<ð 	<ð 	<ð 	<ð 	<ð 	<ð 	<ð !Ð  Ñ'Ô'€GÝ�'˜uœ{Ð+Ñ+Ô+Ð+r-   c                 óV   — t          | ¦  «        }| d         | d         k    rdnd|d<   |S )Nrú   rû   ÚhÚvÚorientation©r/   )rÛ   Úedges     r+   Úline_to_edgerÕ  ò  s2   € Ý�‰:Œ:€DØ"& u¤+°°h´Ò"?Ð"?˜#˜#Àc€DˆÑØ€Kr-   c           	      óž  ‡ — ˆ fd„t          d¦  «        D ¦   «         \  }}}}|                     dd‰ d         ‰ d         ddœ¦  «         |                     dd‰ d	         ‰ d         ‰ d
         z   ‰ d         ‰ d
         z   ddœ¦  «         |                     dd‰ d         ddœ¦  «         |                     dd‰ d         ddœ¦  «         ||||gS )Nc                 ó.   •— g | ]}t          ‰¦  «        ‘ŒS ra   rÓ  )r)   r›   r!   s     €r+   r,   z!rect_to_edges.<locals>.<listcomp>ù  s   ø€ Ð=Ð=Ð=¨q¥ T¡
¤
Ð=Ð=Ð=r-   é   Ú	rect_edger   rr   rú   rÐ  )Úobject_typeÚheightrq   rû   rÒ  rq   rÛ  r0  )rÚ  rÛ  rr   rú   r0  rÒ  ro   rÑ  )rÚ  Úwidthrp   rÒ  rp   )rÚ  rÜ  ro   rÒ  )r²   r¢  )r!   rú   rû   ÚleftÚrights   `    r+   Úrect_to_edgesrß  ø  s)  ø€ Ø=Ð=Ð=Ð=µE¸!±H´HÐ=Ñ=Ô=Ñ€Cˆ��uØ‡J‚Jà&ØØ�t”*Ø˜5”kØð	
ð 	
ñô ð ð ‡M‚Mà&ØØ�t”*Ø˜”;  h¤Ñ/Ø˜8”n t¨H¤~Ñ5Øð	
ð 	
ñ	ô 	ð 	ð 	‡K‚Kà&ØØ�t”*Øð		
ð 	
ñô ð ð 
‡L‚Là&ØØ�t”*Øð		
ð 	
ñô ð ð �˜˜uÐ%Ð%r-   c                 óh   ‡ — t          ‰ d         ‰ d         dd …         ¦  «        }ˆ fd„|D ¦   «         S )NÚptsr$   c                 ó  •— g | �]\  }}d t          |d         |d         ¦  «        t          |d         |d         ¦  «        t          |d         |d         ¦  «        t          |d         |d         ¦  «        ‰d         ‰d         z
  z   t          |d         |d         ¦  «        t          |d         |d         z
  ¦  «        t          |d         |d         z
  ¦  «        |d         |d         k    rdn|d         |d         k    rdnddœ	‘�ŒS )	Ú
curve_edger   r$   r0  rú   rÑ  rÐ  N)	rÚ  ro   rp   rú   r0  rû   rÜ  rÛ  rÒ  )r|   r{   rÏ   )r)   Úp0Úp1Úcurves      €r+   r,   z"curve_to_edges.<locals>.<listcomp>"  s  ø€ ð ð ñ ñ ˆB�ð (Ý�b˜”e˜R œUÑ#Ô#Ý�b˜”e˜R œUÑ#Ô#Ý�r˜!”u˜b œeÑ$Ô$Ý˜"˜Qœ%  A¤Ñ'Ô'¨5°¬?¸UÀ5¼\Ñ+IÑJÝ˜"˜Qœ%  A¤Ñ'Ô'Ý˜˜Aœ  A¤™Ñ'Ô'Ý˜"˜Qœ% " Q¤%™-Ñ(Ô(Ø"$ Q¤%¨2¨a¬5¢. .˜3˜3¸bÀ¼eÀrÈ!Äuºn¸n°s°sÐRVð
	
ð 
	
ðñ ð r-   )Úzip)ræ  Úpoint_pairss   ` r+   Úcurve_to_edgesré     sP   ø€ Ý�e˜E”l E¨%¤L°°°Ô$4Ñ5Ô5€Kðð ð ð ð "ðñ ô ð r-   c                 ó†   — | d         }d|v r| gS |dk    rt          | ¦  «        gS t          t          dœ|         | ¦  «        S )NrÚ  Ú_edgerÛ   )r!   ræ  )rÕ  rß  ré  )ÚobjÚts     r+   Úobj_to_edgesrî  2  sQ   € ØˆMÔ€AØ�!€|€|ØˆuˆØ	
ˆfŠˆÝ˜SÑ!Ô!Ð"Ð"å%µÐ?Ð?ÀÔBÀ3ÑGÔGÐGr-   c                 ó†   ‡‡‡— ‰dvrt          d¦  «        ‚dt          fˆˆˆfd„}t          t          || ¦  «        ¦  «        S )N)rÑ  rÐ  NúOrientation must be 'v' or 'h'r…   c                 óž   •— | d         dk    rdnd}‰�| d         ‰k    nd}‰d u p| d         ‰k    }t          |o|o| |         ‰k    ¦  «        S )NrÒ  rÑ  rÛ  rÜ  rÚ  T©rN   )ÚeÚdimÚ
et_correctÚorient_correctÚ	edge_typeÚ
min_lengthrÒ  s       €€€r+   Útestzfilter_edges.<locals>.testE  so   ø€ Ø˜MÔ*¨cÒ1Ð1ˆhˆh°wˆØ6?Ð6K�Q�}Ô%¨Ò2Ð2ÐQUˆ
Ø$¨Ð,ÐO°°-Ô0@ÀKÒ0OˆÝ�JÐL >ÐL°q¸´vÀÒ7KÑMÔMÐMr-   )r6  rN   r  Úfilter)ÚedgesrÒ  r÷  rø  rù  s    ``` r+   Úfilter_edgesrü  <  st   øøø€ ð Ð*Ð*Ð*ÝÐ9Ñ:Ô:Ð:ðN•4ð Nð Nð Nð Nð Nð Nð Nð Nõ •�t˜UÑ#Ô#Ñ$Ô$Ð$r-   c                 ó°  — |dk    rd„ t          | ¦  «        D ¦   «         S t          | ¦  «        dk     rd„ t          | ¦  «        D ¦   «         S g }t          t          | ¦  «        ¦  «        } | d         g}| d         }| dd …         D ];}|||z   k    r|                     |¦  «         n|                     |¦  «         |g}|}Œ<|                     |¦  «         |S )Nr   c                 ó   — g | ]}|g‘ŒS ra   ra   ©r)   r›   s     r+   r,   z cluster_list.<locals>.<listcomp>P  ó   € Ð(Ð(Ð(˜��Ð(Ð(Ð(r-   r%   c                 ó   — g | ]}|g‘ŒS ra   ra   rÿ  s     r+   r,   z cluster_list.<locals>.<listcomp>R  r   r-   r$   )r°   rX   r  r3   )Úxsr½  r  Úcurrent_groupÚlastr›   s         r+   Úcluster_listr  N  sï   € Ø�A‚~€~Ø(Ð(�V B™ZœZÐ(Ñ(Ô(Ð(Ý
ˆ2�w„w�‚{€{Ø(Ð(�V B™ZœZÐ(Ñ(Ô(Ð(Ø€FÝ	�f�R‰jŒjÑ	Ô	€BØ˜”U�G€MØˆaŒ5€DØ���ŒVð ð ˆØ�˜	Ñ!Ò"Ð"Ø× Ò  Ñ#Ô#Ð#Ð#à�MŠM˜-Ñ(Ô(Ð(Ø˜CˆMØˆˆØ
‡M‚M�-Ñ Ô Ð Ø€Mr-   c                 ó¾   — t          t          t          | ¦  «        ¦  «        |¦  «        }d„ t          |¦  «        D ¦   «         }t	          t          j        |Ž ¦  «        S )Nc                 ó2   ‡— g | ]\  Š}ˆfd „|D ¦   «         ‘ŒS )c                 ó   •— g | ]}|‰f‘ŒS ra   ra   )r)   Úvalr»   s     €r+   r,   z0make_cluster_dict.<locals>.<listcomp>.<listcomp>f  s   ø€ Ð+Ð+Ð+�cˆ#ˆqˆÐ+Ð+Ð+r-   ra   )r)   Úvalue_clusterr»   s     @r+   r,   z%make_cluster_dict.<locals>.<listcomp>e  s?   ø€ ð ð ð Ù0@°°=Ð+Ð+Ð+Ð+˜]Ð+Ñ+Ô+ðð ð r-   )r  r  rB   r7  r/   r‹  Úchain)Úvaluesr½  ÚclustersÚnested_tupless       r+   Úmake_cluster_dictr  b  s\   € Ý�D¥ V¡¤Ñ-Ô-¨yÑ9Ô9€Hðð ÝDMÈhÑDWÔDWðñ ô €Mõ •	” Ð/Ñ0Ô0Ð0r-   c                 óF  ‡‡‡— t          ‰¦  «        st          ‰¦  «        Št          ‰| ¦  «        }t          ||¦  «        Št          d¦  «        t          d¦  «        cŠ}t	          ˆˆfd„| D ¦   «         |¬¦  «        }t          j        ||¬¦  «        }ˆfd„|D ¦   «         S )Nr   r$   c              3   óX   •K  — | ]$}|‰                       ‰|¦  «        ¦  «        fV — Œ%d S r;   ©rA   )r)   r›   Úcluster_dictÚkey_fns     €€r+   rt   z"cluster_objects.<locals>.<genexpr>u  s>   øè è € ÐJÐJÀ!˜a ×!1Ò!1°&°&¸±)´)Ñ!<Ô!<Ð=ÐJÐJÐJÐJÐJÐJr-   rž   c                 óP   •— g | ]"\  }}t          t          ‰|¦  «        ¦  «        ‘Œ#S ra   )r  r  )r)   rŸ  rÑ  Úget_0s      €r+   r,   z#cluster_objects.<locals>.<listcomp>y  s-   ø€ Ð4Ð4Ð4¡D A q�D•�U˜A‘”ÑÔÐ4Ð4Ð4r-   )Úcallabler   r  r  r°   r‹  rŒ  )	r  r  r½  r  Úget_1Úcluster_tuplesÚgroupedr  r  s	    `     @@r+   r8  r8  l  s¯   øøø€ Ý�FÑÔð $Ý˜FÑ#Ô#ˆå�˜‰_Œ_€FÝ$ V¨YÑ7Ô7€Lå˜a‘=”=¥*¨Q¡-¤-€L€Eˆ5åÐJÐJÐJÐJÐJÀrÐJÑJÔJÐPUÐVÑVÔV€NåÔ °EÐ:Ñ:Ô:€Gà4Ð4Ð4Ð4¨GÐ4Ñ4Ô4Ð4r-   Úaxisc                 ó‚  — |dv sJ ‚|dk    rd| d         |z   fd| d         |z   fg}|dk    rPd| d         |z   fd| d         |z   fg}d| v r|d| d         |z   fgz  }d	| v r|d	| d	         |z
  fd
| d
         |z
  fgz  }|                       t          |                      ¦   «         ¦  «        t          |¦  «        z   ¦  «        S )N)rÐ  rÑ  rÐ  ro   rp   rÑ  rú   rû   r0  rq   rr   )Ú	__class__r´   r.   )rì  r  rD   Ú	new_itemss       r+   Úmove_objectr  |  s
  € Ø�:ÐÐÐÐØˆs‚{€{à�3�t”9˜uÑ$Ð%Ø�3�t”9˜uÑ$Ð%ð
ˆ	ð ˆs‚{€{à�C˜”J Ñ&Ð'Ø�s˜8”} uÑ,Ð-ð
ˆ	ð �sˆ?ˆ?Ø˜8 S¨¤]°UÑ%:Ð;Ð<Ñ<ˆIØ�3ˆ;ˆ;ØØ�s˜4”y 5Ñ(Ð)Ø�s˜4”y 5Ñ(Ð)ðñ ˆIð �=Š=�˜sŸyšy™{œ{Ñ+Ô+­e°IÑ.>Ô.>Ñ>Ñ?Ô?Ð?r-   Úattrc                 ó  ‡‡— dddddœ‰         Št          | ¦  «        }t          |t          ‰¦  «        |¦  «        }ˆfd„|D ¦   «         }ˆˆfd„t          ||¦  «        D ¦   «         }t          t	          j        |Ž ¦  «        S )NrÐ  rÑ  ©ro   rp   rú   rû   c           	      ó„   •— g | ]<}t          t          t          ‰¦  «        |¦  «        ¦  «        t          |¦  «        z  ‘Œ=S ra   )Úsumr  r   rX   )r)   Úclusterr   s     €r+   r,   z snap_objects.<locals>.<listcomp>–  s>   ø€ ÐWÐWÐWÀ7�C••J˜tÑ$Ô$ gÑ.Ô.Ñ/Ô/µ#°g±,´,Ñ>ÐWÐWÐWr-   c                 ó8   •‡— g | ]\  }Šˆˆˆfd „|D ¦   «         ‘ŒS )c           	      óD   •— g | ]}t          |‰‰|‰         z
  ¦  «        ‘ŒS ra   )r  )r)   rì  r   Úavgr  s     €€€r+   r,   z+snap_objects.<locals>.<listcomp>.<listcomp>˜  s-   ø€ ÐDÐDÐD°S��S˜$  c¨$¤i¡Ñ	0Ô	0ÐDÐDÐDr-   ra   )r)   r%  r(  r   r  s     @€€r+   r,   z snap_objects.<locals>.<listcomp>—  sI   øø€ ð ð ð áˆG�Sð 	EÐDÐDÐDÐDÐD¸GÐDÑDÔDðð ð r-   )r  r8  r   rç  r‹  r  )Úobjsr   r½  Ú	list_objsr  ÚavgsÚsnapped_clustersr  s    `     @r+   Úsnap_objectsr-  ’  s§   øø€ Ø˜S¨¸Ð<Ð<¸TÔB€DÝ�T‘
”
€IÝ˜y­*°TÑ*:Ô*:¸IÑFÔF€HØWÐWÐWÐWÈhÐWÑWÔW€Dðð ð ð ð å ¨$Ñ/Ô/ðñ ô Ðõ •	”Ð!1Ð2Ñ3Ô3Ð3r-   c                 ó¾   — g g dœ}| D ]#}||d                                        |¦  «         Œ$t          |d         d|¦  «        }t          |d         d|¦  «        }||z   S )zs
    Given a list of edges, snap any within `tolerance` pixels of one another
    to their positional average.
    ©rÑ  rÐ  rÒ  rÑ  ro   rÐ  rú   )r3   r-  )rû  rZ  r?  Úby_orientationró  Ú	snapped_vÚ	snapped_hs          r+   Ú
snap_edgesr3  ž  sx   € ð  BÐ'Ð'€NØð 3ð 3ˆØ�q˜Ô'Ô(×/Ò/°Ñ2Ô2Ð2Ð2å˜^¨CÔ0°$¸ÑDÔD€IÝ˜^¨CÔ0°%¸ÑEÔE€IØ�yÑ Ð r-   r[   c                 ó2  — |dv sJ ‚| |         }||z
  }||fg}|dk    r0|| d         k    sJ ‚|                      d| d         |z
  f¦  «         �n|dk    r/|| d         k    sJ ‚|                      d|| d         z
  f¦  «         nÑ|dk    rs|| d         k    sJ ‚|                      d| d         |z   f¦  «         |                      d| d         |z
  f¦  «         d	| v r |                      d	| d	         |z
  f¦  «         nX|dk    rR|| d         k    sJ ‚|                      d| d         |z   f¦  «         d
| v r |                      d
| d
         |z
  f¦  «         |                      t          |                      ¦   «         ¦  «        t          |¦  «        z   ¦  «        S )Nr"  ro   rp   rÜ  rú   rû   r0  rÛ  rr   rq   )r3   r  r´   r.   )rì  r[   rD   Ú	old_valueÚdiffr  s         r+   Úresize_objectr7  °  så  € ØÐ/Ð/Ð/Ð/Ð/Ø�C”€IØ�9Ñ€Dà	ˆeˆð€Ið ˆd‚{€{Ø˜˜Dœ	Ò!Ð!Ð!Ð!Ø×Ò˜' 3 t¤9¨uÑ#4Ð5Ñ6Ô6Ð6Ñ6Ø	�ŠˆØ˜˜Dœ	Ò!Ð!Ð!Ð!Ø×Ò˜' 5¨3¨t¬9Ñ#4Ð5Ñ6Ô6Ð6Ð6Ø	�ŠˆØ˜˜HœÒ%Ð%Ð%Ð%Ø×Ò˜( C¨¤M°DÑ$8Ð9Ñ:Ô:Ð:Ø×Ò˜( C¨¤M°DÑ$8Ð9Ñ:Ô:Ð:Ø�3ˆ;ˆ;Ø×Ò˜d C¨¤I°Ñ$4Ð5Ñ6Ô6Ð6øØ	�ŠˆØ˜˜Eœ
Ò"Ð"Ð"Ð"Ø×Ò˜( C¨¤M°DÑ$8Ð9Ñ:Ô:Ð:Ø�3ˆ;ˆ;Ø×Ò˜d C¨¤I°Ñ$4Ð5Ñ6Ô6Ð6Ø�=Š=�˜sŸyšy™{œ{Ñ+Ô+­e°IÑ.>Ô.>Ñ>Ñ?Ô?Ð?r-   rÒ  c                 ó”  — |dk    rd\  }}n|dk    rd\  }}nt          d¦  «        ‚t          t          | t          |¦  «        ¬¦  «        ¦  «        }|d         g}|dd	…         D ]a}|d
         }||         ||         |z   k    r-||         ||         k    rt	          ||||         ¦  «        |d
<   ŒL|                     |¦  «         Œb|S )z
    Given a list of edges along the same infinite line, join those that
    are within `tolerance` pixels of one another.
    rÐ  r­   rÑ  )rú   rû   rð  rž   r   r$   Nr¢   )r6  r  r°   r   r7  r3   )	rû  rÒ  r½  Úmin_propÚmax_propÚsorted_edgesÚjoinedró  r  s	            r+   Újoin_edge_groupr=  Ë  sñ   € ð
 �cÒÐØ'Ñˆ�(�(Ø	˜Ò	Ð	Ø,Ñˆ�(�(åÐ9Ñ:Ô:Ð:å�˜u­*°XÑ*>Ô*>Ð?Ñ?Ô?Ñ@Ô@€LØ˜1ŒoÐ€FØ˜!˜"˜"Ôð ð ˆØ�bŒzˆØˆXŒ;˜4 œ>¨IÑ5Ò6Ð6Ø�Œ{˜T (œ^Ò+Ð+å*¨4°¸1¸X¼;ÑGÔG��r‘
øð �MŠM˜!ÑÔÐÐà€Mr-   c                 óì   ‡‡— 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.
    c                 óB   — | d         dk    r
d| d         fS d| d         fS )NrÒ  rÐ  rú   rÑ  ro   ra   )rÔ  s    r+   Ú	get_groupzmerge_edges.<locals>.get_groupò  s0   € Ø�Ô #Ò%Ð%Ø˜˜eœÐ%Ð%à˜˜dœÐ$Ð$r-   r   rž   c              3   óh   •K  — | ],\  }}t          ||d          |d          dk    r‰n‰¦  «        V — Œ-dS )r   rÐ  N)r=  )r)   rŸ  r.   rï   rð   s      €€r+   rt   zmerge_edges.<locals>.<genexpr>ý  se   øè è € ð ð ñ ˆAˆuõ 	Ø�1�Q”4¨a°¬d°cªk¨kÐ*Ð*Ð?Oñ	
ô 	
ðð ð ð ð ð r-   )r3  r°   r‹  rŒ  r  r  )	rû  rì   rí   rï   rð   r@  Ú_sortedÚedge_groupsÚedge_gens	      ``    r+   Úmerge_edgesrE  æ  s¯   øø€ ð%ð %ð %ð ˜!ÒÐÐ/°!Ò3Ð3Ý˜5Ð"2Ð4DÑEÔEˆå�U 	Ð*Ñ*Ô*€GÝÔ# G°Ð;Ñ;Ô;€Kðð ð ð ð ð $ð	ñ ô €Hõ •” (Ð+Ñ,Ô,€EØ€Lr-   c                 ó@   — | d         | d         | d         | d         dœS )zd
    Return the rectangle (i.e a dict with keys "x0", "top", "x1",
    "bottom") for an object.
    r   r$   r%   ri   )ro   rú   rp   rû   ra   ©r‰   s    r+   Úbbox_to_rectrH    s&   € ð
 �q”' $ q¤'°°a´ÀDÈÄGÐLÐLÐLr-   c                 ó:   — t          t          | ¦  «        ¦  «        S )z�
    Given an iterable of objects, return the smallest rectangle (i.e. a
    dict with "x0", "top", "x1", and "bottom" keys) that contains them
    all.
    )rH  r  ©Úobjectss    r+   Úobjects_to_rectrL    s   € õ �¨Ñ0Ô0Ñ1Ô1Ð1r-   c                 ó’   — t          | Ž \  }}}}t          |¦  «        t          |¦  «        t          |¦  «        t          |¦  «        fS )zk
    Given an iterable of bounding boxes, return the smallest bounding box
    that contains them all.
    )rç  r|   r{   )Úbboxesro   rú   rp   rû   s        r+   Úmerge_bboxesrO    s=   € õ
 ˜v˜,Ñ€BˆˆR�Ý�‰GŒG•S˜‘X”X�s 2™wœw­¨F©¬Ð4Ð4r-   c                 óF   — t          t          t          | ¦  «        ¦  «        S )zd
    Given an iterable of objects, return the smallest bounding box that
    contains them all.
    )rO  r  Úbbox_getterrJ  s    r+   r  r  !  s   € õ
 ��K¨Ñ1Ô1Ñ2Ô2Ð2r-   Úword_thresholdc           
      óô  ‡— t          | t          d¦  «        d¦  «        }t          ˆfd„|¦  «        }t          t	          t
          |¦  «        ¦  «        }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 r;   ©rX   ©r›   rR  s    €r+   rœ   z"words_to_edges_h.<locals>.<lambda>/  ó   ø€ ¥c¨!¡f¤f°Ò&>€ r-   r   ro   rp   rÐ  )ro   rp   rú   rû   rÜ  rÒ  rû   )	r8  r   rú  r  r  rL  rX   r|   r{   )	r—  rR  Úby_topÚlarge_clustersÚrectsÚmin_x0Úmax_x1rû  rˆ   s	    `       r+   Úwords_to_edges_hr]  )  s   ø€ õ
 ˜U¥J¨uÑ$5Ô$5°qÑ9Ô9€FÝÐ>Ð>Ð>Ð>ÀÑGÔG€NÝ••_ nÑ5Ô5Ñ6Ô6€EÝ
ˆ5�z„z�Q‚€Øˆ	Ý••Z Ñ%Ô% uÑ-Ô-Ñ.Ô.€FÝ••Z Ñ%Ô% uÑ-Ô-Ñ.Ô.€Fà€EØð 
ð 
ˆØð ØØ˜”xØ˜Eœ(Ø &™Ø"ðð ð ØØ˜”{Ø˜Hœ+Ø &™Ø"ðð ð
ñ 	
ˆˆð. €Lr-   c                 óì   — | \  }}}}|\  }}}}	t          ||¦  «        }
t          ||¦  «        }t          ||	¦  «        }t          ||¦  «        }||
z
  }||z
  }|dk    r|dk    r||z   dk    r|
|||fS d S r™   rz   )ÚaÚbÚa_leftÚa_topÚa_rightÚa_bottomÚb_leftÚb_topÚb_rightÚb_bottomÚo_leftÚo_rightÚo_bottomÚo_topÚo_widthÚo_heights                   r+   Úget_bbox_overlapro  R  s¢   € Ø'(Ñ$€FˆE�7˜HØ'(Ñ$€FˆE�7˜HÝ�˜Ñ Ô €FÝ�'˜7Ñ#Ô#€GÝ�8˜XÑ&Ô&€HÝ��uÑÔ€EØ˜Ñ€GØ˜%Ñ€HØ�1‚}€}˜ Aš˜¨(°WÑ*<¸qÒ*@Ð*@Ø˜˜w¨Ð1Ð1àˆtr-   c                 óx  ‡‡‡‡— t          | t          d¦  «        d¦  «        }t          | t          d¦  «        d¦  «        }d„ }t          | |d¦  «        }||z   |z   }t          |d„ ¬¦  «        }t          ˆfd„|¦  «        }t	          t          t          |¦  «        ¦  «        }	g }
|	D ]4Št          ˆfd„|
D ¦   «         ¦  «        }|s|
                     ‰¦  «         Œ5|
sg S t          t          |
¦  «        }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.
    ro   r$   rp   c                 óD   — t          | d         | d         z   ¦  «        dz  S )Nro   rp   r%   r1  )rL  s    r+   Ú
get_centerz$words_to_edges_v.<locals>.get_centerj  s"   € Ý�T˜$”Z $ t¤*Ñ,Ñ-Ô-°Ñ1Ð1r-   c                 ó"   — t          | ¦  «         S r;   rU  rš   s    r+   rœ   z"words_to_edges_v.<locals>.<lambda>q  s   € µc¸!±f´f°W€ r-   rž   c                 ó*   •— t          | ¦  «        ‰k    S r;   rU  rV  s    €r+   rœ   z"words_to_edges_v.<locals>.<lambda>r  rW  r-   c              3   ó8   •K  — | ]}t          ‰|¦  «        V — Œd S r;   )ro  ©r)   rs   r‰   s     €r+   rt   z#words_to_edges_v.<locals>.<genexpr>z  s.   øè è € ÐJÐJ°AÕ& t¨QÑ/Ô/ÐJÐJÐJÐJÐJÐJr-   rú   rû   c           	      ó@   •— g | ]}|d          |d          ‰‰‰‰z
  ddœ‘ŒS )ro   rÑ  ©ro   rp   rú   rû   rÛ  rÒ  ra   )r)   r`  Ú
max_bottomÚmin_tops     €€r+   r,   z$words_to_edges_v.<locals>.<listcomp>ˆ  sQ   ø€ ð 
ð 
ð 
ð ð �D”'Ø�D”'ØØ Ø  7Ñ*Øð	
ð 	
ð
ð 
ð 
r-   rÑ  rx  )r8  r   r°   rú  r  r  r  rv   r3   rH  r{   r|   )r—  rR  Úby_x0Úby_x1rr  Ú	by_centerr  Úsorted_clustersrY  rN  Úcondensed_bboxesÚoverlapÚcondensed_rectsÚsorted_rectsr\  r‰   ry  rz  s    `             @@@r+   Úwords_to_edges_vrƒ  a  s  øøøø€ õ ˜E¥:¨dÑ#3Ô#3°QÑ7Ô7€EÝ˜E¥:¨dÑ#3Ô#3°QÑ7Ô7€Eð2ð 2ð 2õ    z°1Ñ5Ô5€IØ�u‰}˜yÑ(€Hõ ˜XÐ+<Ð+<Ð=Ñ=Ô=€OÝÐ>Ð>Ð>Ð>ÀÑPÔP€Nõ •#•o ~Ñ6Ô6Ñ7Ô7€Fð ÐØð *ð *ˆÝÐJÐJÐJÐJÐ9IÐJÑJÔJÑJÔJˆØð 	*Ø×#Ò# DÑ)Ô)Ð)øàð Øˆ	å�,Ð(8Ñ9Ô9€OÝ�˜µJ¸tÑ4DÔ4DÐEÑEÔEÑFÔF€Lå••Z Ñ%Ô% |Ñ4Ô4Ñ5Ô5€FÝ•#•j Ñ'Ô'¨Ñ6Ô6Ñ7Ô7€GÝ•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Ò  ra   )r›   Úos    €r+   rœ   z3edges_to_intersections.<locals>.<listcomp>.<lambda>¥  s   ø€ ˜a Ô.°!Ò3€ r-   )r  rú  )r)   r‡  rû  s    @€r+   r,   z*edges_to_intersections.<locals>.<listcomp>¤  sC   øø€ ð ð ð ØAB��VÐ3Ð3Ð3Ð3°UÑ;Ô;Ñ<Ô<ðð ð r-   r/  ro   rú   rž   rû   rp   rÑ  rÐ  )r°   r   r3   )	rû  rZ  r?  ÚintersectionsÚv_edgesÚh_edgesrÑ  rÐ  Úvertexs	   `        r+   Úedges_to_intersectionsrŒ  ž  s^  ø€ ð
 €Mðð ð ð ØFPðñ ô Ñ€GˆWõ �G¥¨D°%Ñ!8Ô!8Ð9Ñ9Ô9ð 5ð 5ˆÝ˜¥Z°°tÑ%<Ô%<Ð=Ñ=Ô=ð 	5ð 	5ˆAà�5”˜a œh¨Ñ4Ò5Ð5Ø�x”[ Q u¤X°Ñ%;Ò<Ð<Ø�t”W  4¤¨;Ñ!6Ò7Ð7Ø�t”W  4¤¨;Ñ!6Ò7Ð7à˜Dœ' 1 U¤8Ð,�Ø Ð.Ð.Ø24¸2Ð,>Ð,>�M &Ñ)Ø˜fÔ% cÔ*×1Ò1°!Ñ4Ô4Ð4Ø˜fÔ% cÔ*×1Ò1°!Ñ4Ô4Ð4øð	5ð Ðr-   c                 ó    — t          | ¦  «        S )z0
    Return the bounding box for an object.
    )rQ  )rì  s    r+   Úobj_to_bboxrŽ  ·  s   € õ �sÑÔÐr-   c                 óJ  ‡ ‡‡‡‡— dt           fˆ fd„Št          t          ‰                      ¦   «         ¦  «        ¦  «        Št	          ‰¦  «        Šd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.
    r…   c                 ó–  •— d„ }| d         |d         k    rP |‰|          d         ¦  «                               |‰|         d         ¦  «        ¦  «        }t          |¦  «        rdS | d         |d         k    rP |‰|          d         ¦  «                               |‰|         d         ¦  «        ¦  «        }t          |¦  «        rdS dS )Nc                 óF   — t          t          t          | ¦  «        ¦  «        S r;   )rB   r  rŽ  )rû  s    r+   Úedges_to_setzCintersections_to_cells.<locals>.edge_connects.<locals>.edges_to_setÉ  s   € Ý•s�;¨Ñ.Ô.Ñ/Ô/Ð/r-   r   rÑ  Tr$   rÐ  F)r�   rX   )rå  Úp2r’  Úcommonrˆ  s       €r+   Úedge_connectsz-intersections_to_cells.<locals>.edge_connectsÈ  så   ø€ ð	0ð 	0ð 	0ð ˆaŒ5�B�q”EŠ>ˆ>Ø!�\ -°Ô"3°CÔ"8Ñ9Ô9×FÒFØ�˜]¨2Ô.¨sÔ3Ñ4Ô4ñô ˆFõ �6‰{Œ{ð Ø�tàˆaŒ5�B�q”EŠ>ˆ>Ø!�\ -°Ô"3°CÔ"8Ñ9Ô9×FÒFØ�˜]¨2Ô.¨sÔ3Ñ4Ô4ñô ˆFõ �6‰{Œ{ð Ø�tØˆur-   r»   c                 ó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   ra   ©r)   r›   Úpts     €r+   r,   zFintersections_to_cells.<locals>.find_smallest_cell.<locals>.<listcomp>ä  ó&   ø€ Ð2Ð2Ð2�q A a¤D¨B¨q¬E¢M M� M M Mr-   c                 ó8   •— g | ]}|d          ‰d          k    ¯|‘ŒS ©r$   ra   r™  s     €r+   r,   zFintersections_to_cells.<locals>.find_smallest_cell.<locals>.<listcomp>å  r›  r-   r   ra   )Úpointsr»   ÚrestÚbelowrÞ  Úbelow_ptÚright_ptÚbottom_rightrš  r•  rˆ  Ún_pointss           @€€€r+   Úfind_smallest_cellz2intersections_to_cells.<locals>.find_smallest_cellÞ  s6  øø€ Ø�˜1‘ÒÐØ�4Ø�AŒYˆØ�a˜!‘e�g�gŒˆà2Ð2Ð2Ð2˜DÐ2Ñ2Ô2ˆØ2Ð2Ð2Ð2˜DÐ2Ñ2Ô2ˆØð 	Lð 	LˆHØ �=  XÑ.Ô.ð Øà!ð Lð L�Ø$�} R¨Ñ2Ô2ð Øà (¨¤¨X°a¬[Ð9�ð " ]Ð2Ð2Ø%˜ l°HÑ=Ô=ð 3à%˜ l°HÑ=Ô=ð 3ð ˜qœE 2 a¤5¨,°q¬/¸<È¼?ÐKÐKÐKÐKÐKÐKøðLð ˆtr-   c              3   ó0   •K  — | ]} ‰‰|¦  «        V — Œd S r;   ra   )r)   r»   r¥  rž  s     €€r+   rt   z)intersections_to_cells.<locals>.<genexpr>ø  s1   øè è € ÐJÐJ°!Ð"Ð" 6¨1Ñ-Ô-ÐJÐJÐJÐJÐJÐJr-   N)rN   r  r°   ÚkeysrX   r#  r²   rú  )rˆ  Úcell_genr•  r¥  r¤  rž  s   ` @@@@r+   Úintersections_to_cellsr©  ¾  sÎ   øøøøø€ ð¥ð ð ð ð ð ð õ& •&˜×+Ò+Ñ-Ô-Ñ.Ô.Ñ/Ô/€FÝ�6‰{Œ{€Hð¥cð ð ð ð ð ð ð ð ð4 KÐJÐJÐJÐJµu½SÀ¹[¼[Ñ7IÔ7IÐJÑJÔJ€HÝ•�t˜XÑ&Ô&Ñ'Ô'Ð'r-   c                 ó<  ‡‡— dt           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          |¦  «        ¦  «         dŠˆfd„}
t          t          |¦  «        dz
  dd¦  «        D ]«}t          j
        ¦   «         }t          ¦   «         }t          ¦   «         }||         D ]=}||z  }|                     |d	         ¦  «         |                     |d         ¦  «         Œ>t          |¦  «        d	k     st          |¦  «        d	k     s |
|¦  «        s||= Œ¬t          |d
„ ¬¦  «        }|S )z…
    Given a list of bounding boxes (`cells`), return a list of tables that
    hold those cells most simply (and contiguously).
    r…   c                 ó,   — | \  }}}}||f||f||f||ffS r;   ra   )r‰   ro   rú   rp   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 r;   ra   )r)   rs   Úcurrent_cornerss     €r+   rt   z"cells_to_tables.<locals>.<genexpr>  s(   øè è € Ð"NÐ"N¸A 1¨Ð#7Ð"NÐ"NÐ"NÐ"NÐ"NÐ"Nr-   Nc                 ó†   •— ‰	€d„ t           D ¦   «         Š	| \  }}}}‰	D ]"\  }}}}||k     r||k    r||k     r	||k    r dS Œ#dS )Nc                 óh   — g | ]/}|d          t           v¯|d         |d         |d         |d         f‘Œ0S r  )rÐ   r¸  s     r+   r,   z5cells_to_tables.<locals>.has_text.<locals>.<listcomp>>  sJ   € ð ð ð àØ�V”9¥LÐ0Ð0ð �4”˜!˜Eœ( A d¤G¨Q¨x¬[Ð9à0Ð0Ð0r-   TF)rw   )
rˆ   Úrx0ÚrtopÚrx1Úrbottomro   rú   rp   rû   Útext_bboxess
            €r+   Úhas_textz!cells_to_tables.<locals>.has_text;  s}   ø€ àÐðð åðñ ô ˆKð
 #$ÑˆˆT�3˜Ø#.ð 	ð 	ÑˆB��R˜Ø�CŠxˆx˜B šH˜H¨¨wª¨¸6ÀDº=¸=Ø�t�tøØˆur-   r$   r¢   r%   c                 ó4   — t          d„ | D ¦   «         ¦  «        S )Nc              3   ó6   K  — | ]}|d          |d         fV — ŒdS )r$   r   Nra   r¸  s     r+   rt   z4cells_to_tables.<locals>.<lambda>.<locals>.<genexpr>Z  s.   è è € Ð.GÐ.GÀ°°!´°a¸´d¨|Ð.GÐ.GÐ.GÐ.GÐ.GÐ.Gr-   )r|   )rí  s    r+   rœ   z!cells_to_tables.<locals>.<lambda>Z  s   € ­3Ð.GÐ.GÀQÐ.GÑ.GÔ.GÑ+GÔ+G€ r-   rž   )r´   r  rB   rX   r3   Úremover$  rI   r²   r'   Ú
EMPTY_RECTÚaddr°   )r4   rµ   r¬  Úremaining_cellsÚcurrent_cellsÚtablesÚinitial_cell_countr¾   Úcell_cornersÚcorner_countr¶  r»   rˆ   Úx1_valsÚx0_valsrs   rB  r®  rµ  s                    @@r+   Úcells_to_tablesrÄ  ü  sã  øø€ ðB¥ð Bð Bð Bð Bõ ˜5‘k”k€Oõ
 ‘e”e€OØ€Mà€FÝ
ˆoÑ
Ô
ñ "Ý  Ñ/Ô/ÐÝ˜Ñ)Ô)ð 	1ð 	1ˆDØ*˜?¨4Ñ0Ô0ˆLå�=Ñ!Ô! QÒ&Ð&à¥3 |Ñ#4Ô#4Ñ4�Ø×$Ò$ TÑ*Ô*Ð*Ø×&Ò& tÑ,Ô,Ð,Ð,õ  #Ð"NÐ"NÐ"NÐ"NÀÐ"NÑ"NÔ"NÑNÔN�ð   !Ò#Ð#à#¥s¨<Ñ'8Ô'8Ñ8�OØ!×(Ò(¨Ñ.Ô.Ð.Ø#×*Ò*¨4Ñ0Ô0Ð0øõ ˆ}ÑÔÐ!3Ò3Ð3à�MŠM�$˜}Ñ-Ô-Ñ.Ô.Ð.Ø×!Ò!Ñ#Ô#Ð#Ø×ÒÑ!Ô!Ð!õ5 ˆoÑ
Ô
ñ "õ> ˆ=ÑÔð +à�Š•d˜=Ñ)Ô)Ñ*Ô*Ð*ð €Kðð ð ð ð õ •3�v‘;”; ‘? B¨Ñ+Ô+ð ð ˆÝÔÑ Ô ˆÝ‘%”%ˆÝ‘%”%ˆØ˜”ð 	ð 	ˆAØ�‰FˆAØ�KŠK˜˜!œÑÔÐØ�KŠK˜˜!œÑÔÐÐå�‰LŒL˜1ÒÐÝ�7‰|Œ|˜aÒÐØ�8˜A‘;”;ð  ð �q�	øõ �VÐ!GÐ!GÐHÑHÔH€GØ€Nr-   c                   ó   — e Zd Zd„ ZdS )Ú	CellGroupc                 óÚ  — || _         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$   r%   ri   )rµ   r|   r  r   rú  r{   r‰   )r=   rµ   s     r+   r?   zCellGroup.__init___  sª   € ØˆŒ
å••J˜q‘M”M¥6¨$°Ñ#6Ô#6Ñ7Ô7Ñ8Ô8Ý••J˜q‘M”M¥6¨$°Ñ#6Ô#6Ñ7Ô7Ñ8Ô8Ý••J˜q‘M”M¥6¨$°Ñ#6Ô#6Ñ7Ô7Ñ8Ô8Ý••J˜q‘M”M¥6¨$°Ñ#6Ô#6Ñ7Ô7Ñ8Ô8ð	
ˆŒ	ˆ	ˆ	r-   N)r]   r^   r_   r?   ra   r-   r+   rÆ  rÆ  ^  s#   € € € € € ð
ð 
ð 
ð 
ð 
r-   rÆ  c                   ó   — e Zd ZdS )ÚTableRowNré   ra   r-   r+   rÊ  rÊ  i  rê   r-   rÊ  c                   ó   — e Zd ZdZd„ ZdS )ÚTableHeaderz9PyMuPDF extension containing the identified table header.c                 ó>   — || _         || _        || _        || _        d S r;   )r‰   rµ   ÚnamesÚexternal)r=   r‰   rµ   rÎ  Úaboves        r+   r?   zTableHeader.__init__p  s"   € ØˆŒ	ØˆŒ
ØˆŒ
ØˆŒˆˆr-   N)r]   r^   r_   r`   r?   ra   r-   r+   rÌ  rÌ  m  s)   € € € € € ØCÐCðð ð ð ð r-   rÌ  c                 óš  ‡— t          | t          dd¦  «        ¬¦  «        }t          t          t          t	          t          d¦  «        | ¦  «        ¦  «        ¦  «        ¦  «        }g }t          j        |t          d¦  «        ¦  «        D ]A\  }}d„ |D ¦   «         Št          ˆfd„|D ¦   «         ¦  «        }|                     |¦  «         ŒB|S )a  Canonical row order and None gap slots for a flat cell list.

    Each row holds one slot per distinct cell x0 on the table, so a gap and a
    span both appear as None. Shared by Table.rows and the union stage, which
    needs the same grid before a Table exists.r$   r   rž   c                 ó    — i | ]}|d          |“ŒS r˜  ra   ©r)   r¾   s     r+   r   z"_cells_to_rows.<locals>.<dictcomp>�  s   € Ð5Ð5Ð5 4��a”˜$Ð5Ð5Ð5r-   c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS ra   r  )r)   r›   Úxdicts     €r+   r,   z"_cells_to_rows.<locals>.<listcomp>‚  s#   ø€ Ð1Ð1Ð1¨˜Ÿ	š	 !™œÐ1Ð1Ð1r-   )	r°   r   r  rB   r  r‹  rŒ  rÊ  r3   )rµ   rB  r  ÚrowsrŠ   Ú	row_cellsÚrowrÕ  s          @r+   Ú_cells_to_rowsrÙ  w  sÈ   ø€ õ �U¥
¨1¨aÑ 0Ô 0Ð1Ñ1Ô1€GÝ	�f•S��Z¨™]œ]¨EÑ2Ô2Ñ3Ô3Ñ4Ô4Ñ	5Ô	5€BØ€DÝ!Ô)¨'µ:¸a±=´=ÑAÔAð ð ‰ˆˆ9Ø5Ð5¨9Ð5Ñ5Ô5ˆÝÐ1Ð1Ð1Ð1¨bÐ1Ñ1Ô1Ñ2Ô2ˆØ�Š�CÑÔÐÐØ€Kr-   c                   óÞ   — e Zd Zdd„Zed„ ¦   «         Zed„ ¦   «         Zej        d„ ¦   «         Zedefd„¦   «         Z	ede
fd„¦   «         Zede
fd	„¦   «         Zdefd
„Zdd„Zd„ Zd„ Zdd„ZdS )ÚTableNc                 óD  — || _         d | _        d | _        || _        || _        t
          | _        t          t          j	         
                    ¦   «         ¦  «        t          t          j	                             ¦   «         ¦  «        f| _        d | _        d| _        d| _        d S )Nr   ra   )r4   r’   Ú_charsrµ   Ú_bboxÚ_NO_HEADER_YETÚ_headerrN   r'   ÚTOOLSÚset_small_glyph_heightsÚunset_quad_correctionsÚ_header_flagsÚ
placementsÚheader_rowsÚsection_rows)r=   r4   rµ   r‰   s       r+   r?   zTable.__init__‹  s‹   € ØˆŒ	ØˆŒØˆŒØˆŒ
ð ˆŒ
Ý%ˆŒõ
 •”×6Ò6Ñ8Ô8Ñ9Ô9Ý•”×5Ò5Ñ7Ô7Ñ8Ô8ð
ˆÔð ˆŒØˆÔØˆÔÐÐr-   c           
      ó’  — | j         �t          | j         ¦  «        S | j        }t          t	          t          d¦  «        |¦  «        ¦  «        t          t	          t          d¦  «        |¦  «        ¦  «        t          t	          t          d¦  «        |¦  «        ¦  «        t          t	          t          d¦  «        |¦  «        ¦  «        fS rÈ  )rÞ  r´   rµ   r|   r  r   r{   )r=   rs   s     r+   r‰   z
Table.bbox£  s—   € àŒ:Ð!Ý˜œÑ$Ô$Ð$ØŒJˆå••J˜q‘M”M 1Ñ%Ô%Ñ&Ô&Ý••J˜q‘M”M 1Ñ%Ô%Ñ&Ô&Ý••J˜q‘M”M 1Ñ%Ô%Ñ&Ô&Ý••J˜q‘M”M 1Ñ%Ô%Ñ&Ô&ð	
ð 	
r-   c                 ó¢  — | j         t          u �r:| j        \  }}t          t          j                             ¦   «         ¦  «        }t          t          j                             ¦   «         ¦  «        }t          j                             |¦  «         t          j                             |¦  «         	 |                      ¦   «         | _         t          j                             |¦  «         t          j                             |¦  «         nC# t          j                             |¦  «         t          j                             |¦  «         w xY w| j         S )a  The identified table header, computed on first access.

        Identifying it renders the top row twice, so tables whose header is never
        read -- every table serialized through placements, and every candidate a
        later stage discards -- must not pay for it at construction time. The
        header rules re-read the page, so the two global text-extraction toggles
        of the detecting call are restored for the duration (see __init__): the
        result is then the one an eager computation would have produced.)	rà  rß  rä  rN   r'   rá  râ  rã  Ú_get_header)r=   ÚsmallÚquadsÚ	old_smallÚ	old_quadss        r+   ÚheaderzTable.header¯  s  € ð Œ<�>Ð)Ñ)ØÔ-‰LˆE�5Ý�Wœ]×BÒBÑDÔDÑEÔEˆIÝ�Wœ]×AÒAÑCÔCÑDÔDˆIÝŒM×1Ò1°%Ñ8Ô8Ð8ÝŒM×0Ò0°Ñ7Ô7Ð7ð@Ø#×/Ò/Ñ1Ô1�”å”×5Ò5°iÑ@Ô@Ð@Ý”×4Ò4°YÑ?Ô?Ð?Ð?øõ ”×5Ò5°iÑ@Ô@Ð@Ý”×4Ò4°YÑ?Ô?Ð?Ð?øøøØŒ|Ðs   Â/D ÄA Ec                 ó   — || _         d S r;   )rà  rC   s     r+   rï  zTable.headerÆ  s   € àˆŒˆˆr-   r…   c                 ó*   — t          | j        ¦  «        S r;   )rÙ  rµ   rJ   s    r+   rÖ  z
Table.rowsÊ  s   € å˜dœjÑ)Ô)Ð)r-   c                 ó*   — t          | j        ¦  «        S r;   )rX   rÖ  rJ   s    r+   Ú	row_countzTable.row_countÎ  s   € å�4”9‰~Œ~Ðr-   c                 ó>   — t          d„ | j        D ¦   «         ¦  «        S )Nc                 ó6   — g | ]}t          |j        ¦  «        ‘ŒS ra   )rX   rµ   ©r)   rˆ   s     r+   r,   z#Table.col_count.<locals>.<listcomp>Ô  s    € Ð4Ð4Ð4 Q•C˜œ‘L”LÐ4Ð4Ð4r-   )r{   rÖ  rJ   s    r+   Ú	col_countzTable.col_countÒ  s!   € åÐ4Ð4¨$¬)Ð4Ñ4Ô4Ñ5Ô5Ð5r-   c                 óØ  ‡‡	‡
— | j         �| j         nt          }g }dt          fd„Š	| j        D ]¼Š
g }ˆ	ˆ
fd„|D ¦   «         }‰
j        D ]ŒŠ‰€d }npˆˆ	fd„|D ¦   «         }t          |¦  «        rP‰d         |d<   ‰d         |d<   d	|v r(‰d
         ‰d         z
  |d<   ‰d         ‰d         z
  |d<   t          |fi |¤Ž}nd}|                     |¦  «         Œ�|                     |¦  «         Œ½|S )Nr…   c                 óª   — | d         | d         z   dz  }| d         | d         z   dz  }|\  }}}}t          ||k    o||k     o||k    o||k     ¦  «        S )Nrú   rû   r%   ro   rp   rò  )rá   r‰   Úv_midÚh_midro   rú   rp   rû   s           r+   Úchar_in_bboxz#Table.extract.<locals>.char_in_bboxÚ  sr   € Ø˜%”[ 4¨¤>Ñ1°QÑ6ˆEØ˜$”Z $ t¤*Ñ,°Ñ1ˆEØ"&ÑˆB��R˜ÝØ˜"’ÐV 5¨2¢:ÐV°E¸S²LÐVÀuÈvÂ~ñô ð r-   c                 ó6   •— g | ]} ‰|‰j         ¦  «        ¯|‘ŒS ra   rG  )r)   rá   rü  rØ  s     €€r+   r,   z!Table.extract.<locals>.<listcomp>ä  s,   ø€ ÐPÐPÐP $°<°<ÀÀcÄhÑ3OÔ3OÐP˜ÐPÐPÐPr-   c                 ó,   •— g | ]} ‰|‰¦  «        ¯|‘ŒS ra   ra   )r)   rá   r¾   rü  s     €€r+   r,   z!Table.extract.<locals>.<listcomp>ê  s:   ø€ ð "ð "ð "Ø!%°l°lÀ4ÈÑ6NÔ6Nð"Øð"ð "ð "r-   r   r=  r$   r>  r'  r%   r9  ri   r:  rÁ   )rÝ  rw   rN   rÖ  rµ   rX   rº  r3   )r=   r›  rÈ   Ú	table_arrÚarrÚ	row_charsÚ	cell_textÚ
cell_charsr¾   rü  rØ  s           @@@r+   ÚextractzTable.extractÖ  sh  øøø€ Ø#œ{Ð6�”�½EˆØˆ	ð	­ð 	ð 	ð 	ð 	ð ”9ð 	"ð 	"ˆCØˆCØPÐPÐPÐPÐP¨%ÐPÑPÔPˆIàœ	ð &ð &�Ø�<Ø $�I�Ið"ð "ð "ð "ð "Ø)2ð"ñ "ô "�Jõ ˜:‘”ð 'Ø,0°¬G˜˜yÑ)Ø,0°¬G˜˜yÑ)Ø# vÐ-Ð-Ø59¸!´W¸tÀA¼wÑ5F˜F >Ñ2Ø6:¸1´gÀÀQÄÑ6G˜F ?Ñ3Ý$0°Ð$FÐ$F¸vÐ$FÐ$F˜	˜	à$&˜	Ø—
’
˜9Ñ%Ô%Ð%Ð%Ø×Ò˜SÑ!Ô!Ð!Ð!àÐr-   FTc                 óÊ  ‡— d}| j         }| j        Šd„ | j        D ¦   «         }ˆfd„t          |¦  «        D ¦   «         }t	          |¦  «        D ]H\  }}t	          |¦  «        D ]3\  }	}
|
�,t          | j        ||         |	         d¬¦  «        ||         |	<   Œ4ŒI|r¤t          |¦  «        D ]B}	t          ‰dz
  ¦  «        D ]-}||	         |dz            €||	         |         ||	         |dz   <   Œ.ŒCt          ‰¦  «        D ]B}t          |dz
  ¦  «        D ]-}	||	dz            |         €||	         |         ||	dz            |<   Œ.ŒCt	          | j        j        ¦  «        D ]W\  }}|sd|dz   › �}| 	                    d	d
¦  «        }|r(t          j        | 	                    dd¦  «        ¦  «        }||dz   z  }ŒX|d	z  }|dd                     d„ t          | j        ¦  «        D ¦   «         ¦  «        z   dz   z  }| j        j        rdnd}	||	d…         D ]Y}d}t	          |¦  «        D ];\  }}
|
€d}
|r(t          j        |
 	                    dd¦  «        ¦  «        }
||
dz   z  }Œ<|d	z  }||z  }ŒZ|d	z   S )a7  Output table content as a string in Github-markdown format.

        If "clean" then markdown syntax is removed from cell content.
        If "fill_empty" then cell content None is replaced by the values
        above (columns) or left (rows) in an effort to approximate row and
        columns spans.

        ú|c                 ó0   — g | ]}d „ |j         D ¦   «         ‘ŒS )c                 ó   — g | ]}|‘ŒS ra   ra   r¸  s     r+   r,   z0Table.to_markdown.<locals>.<listcomp>.<listcomp>
  s   € Ð*Ð*Ð*˜Q�qÐ*Ð*Ð*r-   )rµ   rö  s     r+   r,   z%Table.to_markdown.<locals>.<listcomp>
  s)   € Ð>Ð>Ð>¨qÐ*Ð* !¤'Ð*Ñ*Ô*Ð>Ð>Ð>r-   c                 óB   •— g | ]}d „ t          ‰¦  «        D ¦   «         ‘ŒS )c                 ó   — g | ]}d ‘ŒS r;   ra   ©r)   r»   s     r+   r,   z0Table.to_markdown.<locals>.<listcomp>.<listcomp>  s   € Ð,Ð,Ð,˜1�$Ð,Ð,Ð,r-   )r²   )r)   r½   Úcolss     €r+   r,   z%Table.to_markdown.<locals>.<listcomp>  s.   ø€ ÐBÐBÐB°Ð,Ð,¥ d¡¤Ð,Ñ,Ô,ÐBÐBÐBr-   NT)rØ   r$   ÚColrÅ   rÄ   ú-z&#45;c              3   ó   K  — | ]}d V — ŒdS )z---Nra   r  s     r+   rt   z$Table.to_markdown.<locals>.<genexpr>.  s"   è è € Ð FÐ F¨1 Ð FÐ FÐ FÐ FÐ FÐ Fr-   z|
r   rÁ   )ró  r÷  rÖ  r²   r7  ræ   r’   rï  rÎ  ÚreplaceÚhtmlÚescaper  rÏ  )r=   ÚcleanÚ
fill_emptyÚoutputrÖ  Ú
cell_boxesrµ   r»   rØ  r½   r¾   ÚnamerÛ   r  s                @r+   Úto_markdownzTable.to_markdownü  sú  ø€ ð ˆØŒ~ˆØŒ~ˆð ?Ð>°D´IÐ>Ñ>Ô>ˆ
ð CÐBÐBÐBµe¸D±k´kÐBÑBÔBˆÝ 
Ñ+Ô+ð 	ð 	‰FˆAˆsÝ$ S™>œ>ð ð ‘��4ØÐ#Ý"/Øœ z°!¤}°QÔ'7À$ð#ñ #ô #�E˜!”H˜Q‘Køðð ð 	6õ ˜4‘[”[ð 6ð 6�Ý˜t a™x™œð 6ð 6�AØ˜Q”x  A¡”Ð.Ø*/°¬(°1¬+˜˜aœ  Q¡™øð6õ
 ˜4‘[”[ð 6ð 6�Ý˜t a™x™œð 6ð 6�AØ˜Q ™U”| A”Ð.Ø*/°¬(°1¬+˜˜a !™eœ Q™øð6õ
 ! ¤Ô!2Ñ3Ô3ð 	!ð 	!‰GˆAˆtØð #Ø"˜Q˜q™S�{�{�Ø—<’<  fÑ-Ô-ˆDØð ?Ý”{ 4§<¢<°°WÑ#=Ô#=Ñ>Ô>�Ø�d˜S‘jÑ ˆFˆFà�$‰ˆà�#˜ŸšÐ FÐ Fµ°d´nÑ0EÔ0EÐ FÑ FÔ FÑFÔFÑFÈÑNÑNˆð ”Ô%Ð,ˆAˆA¨1ˆð ˜˜˜”9ð 	ð 	ˆCØˆDÝ$ S™>œ>ð #ð #‘��4ð �<Ø�DØð CÝœ; t§|¢|°C¸Ñ'AÔ'AÑBÔB�DØ˜˜s™
Ñ"��Ø�D‰LˆDØ�d‰NˆFˆFØ˜‰}Ðr-   c                 óž   — | j         �t          | j         | j        ¦  «        S d„ |                      ¦   «         D ¦   «         }t          |¦  «        S )aH  Output the table as an HTML ``<table>`` string.

        With span placements (from ``find_tables(refine=True)``) each
        placement's colspan/rowspan and th/td tag are honoured and a
        section-label row collapses to one spanning ``<th>``. Otherwise a flat
        td-only table is built from :meth:`extract`.
        Nc                 ó&   — g | ]}d „ |D ¦   «         ‘ŒS )c                 ó8   — g | ]}t          d |pddd¬¦  «        ‘ŒS )NrÁ   r$   ©r‰   rÙ   ÚcolspanÚrowspan)r   rÓ  s     r+   r,   z,Table.to_html.<locals>.<listcomp>.<listcomp>N  s=   € ð ð ð àõ ˜d¨$¨*°"¸qÈ!ÐLÑLÔLðð ð r-   ra   ©r)   rØ  s     r+   r,   z!Table.to_html.<locals>.<listcomp>M  sA   € ð 
ð 
ð 
ð
 ð	ð àðñ ô ð
ð 
ð 
r-   )rå  r   rç  r  )r=   rÖ  s     r+   Úto_htmlzTable.to_htmlB  sY   € ð Œ?Ð&Ý$ T¤_°dÔ6GÑHÔHÐHð
ð 
ð
 —|’|‘~”~ð
ñ 
ô 
ˆõ ! Ñ&Ô&Ð&r-   c                 ó´  — 	 ddl }n## t          $ r t          j        d¦  «         ‚ w xY wi }|                      ¦   «         }| j        }| j        j        }t          |¦  «        }t          |¦  «        D ]}||         }	|	sd|› �||<   Œ|t          t          |¦  «        ¦  «        k    r-t          |¦  «        D ]}||         }	|	d|› �k    r
|› d|	› �||<   Œ|j
        s
|dd…         }t          |¦  «        D ]Q}||         }
g }t          t          |¦  «        ¦  «        D ]#}|                     ||         |         ¦  «         Œ$|||
<   ŒR|                     |¦  «        S )z/Return a pandas DataFrame version of the table.r   Nz!Package 'pandas' is not installedr  r  r$   )ÚpandasÚModuleNotFoundErrorr'   Úmessager  rï  rÎ  rX   r²   rB   rÏ  r3   Ú	DataFrame)r=   r›  ÚpdÚpd_dictr  ÚhdrrÎ  Úhdr_lenr»   r  r[   rD   r½   s                r+   Ú	to_pandaszTable.to_pandasV  s–  € ð	ØÐÐÐÐøÝ"ð 	ð 	ð 	ÝŒOÐ?Ñ@Ô@Ð@Øð	øøøð ˆØ—,’,‘.”.ˆØŒkˆØ”Ô!ˆÝ�e‘*”*ˆå�w‘”ð 	%ð 	%ˆAØ˜”8ˆDØð %Ø$ ˜9˜9��a‘øØ•c�#˜e™*œ*‘o”oÒ%Ð%Ý˜7‘^”^ð -ð -�Ø˜Q”x�Ø˜9 ˜9˜9Ò$Ð$Ø"#˜}˜} d˜}˜}�E˜!‘HøàŒ|ð 	"Ø˜a˜b˜b”kˆGå�w‘”ð 	!ð 	!ˆAØ˜”(ˆCØˆEÝ�3˜w™<œ<Ñ(Ô(ð ,ð ,�Ø—’˜W QœZ¨œ]Ñ+Ô+Ð+Ð+Ø ˆG�C‰LˆLà�|Š|˜GÑ$Ô$Ð$s   ‚ ‡ 'ri   c                 ó	  ‡ ‡‡‡ ‡!‡"— ‰ j         Š|}ˆfd„}ˆ fd„}	 ‰ j        d         }|j        }t          j        |j        ¦  «        }n# t          $ r Y dS w xY wt          ||‰                      ¦   «         d         d¦  «        }t          ‰ j        ¦  «        dk     r|S t          |¦  «        dk     r|S ‰ j        d         }	t          d„ |	j        D ¦   «         ¦  «        r|S  ||¦  «        }
|
r ||	j        ¦  «        s|S  |‰ ¦  «        r|S d	„ |dd
…         D ¦   «         }|
 }d|_        |j        |_        ‰                     d|t          j        ¬¦  «        d         }t          d„ |D ¦   «         d„ d¬¦  «        }g Š g }g }t!          t          |¦  «        ¦  «        D �]c}||         }|d         d         }||d         d         z
  }|d         t          j        z  }|dk    r@‰                      |¦  «         |                     |¦  «         |                     |¦  «         Œ…‰ d
         }|d
         }|d
         }||z
  |k    s%t'          ||z
  |d         d         z
  ¦  «        |k    rE|d         d         ||z
  |d         d         |f|d<   |||<   t)          ||¦  «        |d
<   |r||d
<   �Œ|r|s nO||z
  d|z  k    r nA‰                      |¦  «         |                     |¦  «         |                     |¦  «         �Œe‰ g k    r|S ‰ dd…         Š |j        ‰ d         z
  |d         k    r|S |
r
|d         s|S |g k    r|S t          j        ¦   «         }ˆ fd„|D ¦   «         D ]}||d         z  }Œ|j        s|}|j        |_        d„ ‰                     d|¬¦  «        D ¦   «         Š"t          t/          t1          d„ ‰"D ¦   «         ¦  «        ¦  «        d¬¦  «        }g Š |D ]-Š!ˆ!ˆ"fd„|D ¦   «         }|g k    r‰                      ‰!¦  «         Œ- ‰ g k    r|S |
 Š‰ d
         ‰_        ˆfd„|D ¦   «         }‰ j        d         ‰_        ‰ j        d         ‰_        ˆfd„|D ¦   «         }t          t7          ‰¦  «        ||d¦  «        S ) aj  Identify the table header.

        *** PyMuPDF extension. ***

        Starting from the first line above the table upwards, check if it
        qualifies to be part of the table header.

        Criteria include:
        * A one-line table never has an extra header.
        * Column borders must not intersect any word. If this happens, all
          text of this line and above of it is ignored.
        * No excess inter-line distance: If a line further up has a distance
          of more than 1.5 times of its font size, it will be ignored and
          all lines above of it.
        * Must have same text properties.
        * Starting with the top table line, a bold text property cannot change
          back to non-bold.

        If not all criteria are met (or there is no text above the table),
        the first table row is assumed to be the header.
        c                 óB  •— t          j        | j        d         j        ¦  «        }|d|j         d|j         fz   }‰                     |¬¦  «                             ¦   «         d         }‰                     |¬¦  «                             ¦   «         d         }||k    rdS dS )zÓ
            Compare top row background color with color of same-sized bbox
            above. If different, return True indicating that the original
            table top row is already the header.
            r   ©Úclipr$   TF)r'   r(   rÖ  r‰   rÛ  Ú
get_pixmapÚcolor_topusage)r=   Úbbox0ÚbboxtÚ
top_color0Ú
top_colortr4   s        €r+   Útop_row_bg_colorz+Table._get_header.<locals>.top_row_bg_color“  s•   ø€ õ ”L ¤¨1¤Ô!2Ñ3Ô3ˆEØ˜Q ¤ ¨q°5´<°-Ð@Ñ@ˆEØŸš¨e˜Ñ4Ô4×CÒCÑEÔEÀaÔHˆJØŸš¨e˜Ñ4Ô4×CÒCÑEÔEÀaÔHˆJØ˜ZÒ'Ð'Ø�tØ�5r-   c                 óf   •‡ — ‰j         �‰j         nt          }t          ˆ fd„|D ¦   «         ¦  «        S )at  Check if a row contains some bold text.

            If e.g. true for the top row, then it will be used as (internal)
            column header row if any of the following is true:
            * the previous (above) text line has no bold span
            * the second table row text has no bold span

            Returns True if any spans are bold else False.
            Nc              3   ó€   •K  — | ]8}t          |d          |d         |d         |d         f‰¦  «        ¯.|d         V — Œ9dS )ro   rq   rp   rr   ÚboldNr§   rv  s     €r+   rt   z:Table._get_header.<locals>.row_has_bold.<locals>.<genexpr>®  sd   øè è € ð ð àÝ  4¤¨!¨D¬'°1°T´7¸A¸d¼GÐ DÀdÑKÔKðØ�&”	ðð ð ð ð ð r-   )rÝ  rw   rv   )r‰   rÈ   r=   s   ` €r+   Úrow_has_boldz'Table._get_header.<locals>.row_has_bold¡  sP   øø€ ð $(¤;Ð#:�D”K�KÅˆEÝð ð ð ð àðñ ô ñ ô ð r-   r   NFr%   r$   c              3   ó   K  — | ]}|d u V — Œ	d S r;   ra   r¸  s     r+   rt   z$Table._get_header.<locals>.<genexpr>È  s&   è è € Ð-Ð-˜Qˆq�DˆyÐ-Ð-Ð-Ð-Ð-Ð-r-   c                 ó&   — g | ]}|�|d         nd ‘ŒS )Nr%   ra   r¸  s     r+   r,   z%Table._get_header.<locals>.<listcomp>Ù  s$   € ÐEÐEÐE°Q˜˜��1”�¨DÐEÐEÐEr-   r¢   r/   ©r.  rË   rÂ   c                 ó¨   — g | ]O}|d          D ]D}|d         D ]9}t                                |d         ¦  «        °"|d         t          j        z  °7|‘Œ:ŒEŒPS )rÃ   rÇ   rÙ   rË   )rÐ   Ú
issupersetr'   ÚTEXT_FONT_SUPERSCRIPT)r)   r`  ÚlÚss       r+   r,   z%Table._get_header.<locals>.<listcomp>æ  sŒ   € ð 	ð 	ð 	àØ˜7œð	ð 	ð Ø˜7œð		ð 	ð å ×+Ò+¨A¨f¬IÑ6Ô6ð	ð ˜”z¥GÔ$AÑAð	Øð	ð 	ð 	ð 	ð 	r-   c                 ó   — | d         d         S )Nr‰   ri   ra   ©rA  s    r+   rœ   z#Table._get_header.<locals>.<lambda>ð  s   € ˜!˜Fœ) Aœ,€ r-   T)r[   Úreverser‰   ri   rË   g      ø?é   c                 óD   •— g | ]}|d          d         ‰d         k    ¯|‘ŒS )r‰   ri   r¢   ra   )r)   rA  Úselects     €r+   r,   z%Table._get_header.<locals>.<listcomp>-  s/   ø€ ÐAÐAÐA˜ a¨¤i°¤l°f¸R´jÒ&@Ð&@�!Ð&@Ð&@Ð&@r-   c                 óF   — g | ]}t          j        |d d…         ¦  «        ‘ŒS ©NrØ  r&   r±  s     r+   r,   z%Table._get_header.<locals>.<listcomp>5  s*   € ÐUÐUÐU¨a•g”l 1 R a R¤5Ñ)Ô)ÐUÐUÐUr-   r—  r-  c                 ó   — g | ]
}|d          ‘ŒS r�  ra   rö  s     r+   r,   z%Table._get_header.<locals>.<listcomp>6  s   € Ð$>Ð$>Ð$>¨a Q q¤TÐ$>Ð$>Ð$>r-   )rD  c                 ón   •— g | ]1}|�-‰D ]*}|d         ‰k    ¯|d         |k     ¯|d         |k    ¯&||f‘Œ+Œ2S )Nr$   r   r%   ra   )r)   r›   rˆ   rú   r‹   s      €€r+   r,   z%Table._get_header.<locals>.<listcomp><  s`   ø€ ð ð ð àØ�=Ø#ð !�=ØØ�Q”4˜3’;�; 1 Q¤4¨!¢8 8°°!´°q²°ð	 �A�ð 19°°°r-   c                 óP   •— g | ]"}|�|d         ‰j         |d         ‰j        fnd ‘Œ#S )Nr   r%   )rq   rr   )r)   rs   Úhdr_bboxs     €r+   r,   z%Table._get_header.<locals>.<listcomp>M  sG   ø€ ð 
ð 
ð 
àð 78°mˆQˆqŒT�8”;  !¤ h¤kÐ2Ð2Èð
ð 
ð 
r-   c                 ó¶   •— g | ]U}|�O‰                      |¦  «                             dd¦  «                             dd¦  «                             ¦   «         nd‘ŒVS )NrÅ   rÉ   z  rÁ   )Úget_textboxr  r×   )r)   rs   r4   s     €r+   r,   z%Table._get_header.<locals>.<listcomp>W  sr   ø€ ð 
ð 
ð 
ð ð �=ð × Ò  Ñ#Ô#×+Ò+¨D°#Ñ6Ô6×>Ò>¸tÀSÑIÔI×OÒOÑQÔQÐQàð	
ð 
ð 
r-   )r4   rÖ  rµ   r'   r(   r‰   Ú
IndexErrorrÌ  r  rX   Úallrq   rr   Úget_textÚTEXTFLAGS_TEXTr°   r²   ÚTEXT_FONT_BOLDr3   rÏ   r|   rº  r³   r  rB   ro   rp   r´   )#r=   r?  Úy_deltar5  r9  rØ  rµ   r‰   Úheader_top_rowÚrow2Útop_row_boldÚcol_xr.  rÂ   rÇ   Úline_heightsÚ
line_boldsr»   rA  rr   rÐ  r8  rq   Úh0Úbold0ÚnclipÚ	word_topsÚintersectingÚ	hdr_cellsÚ	hdr_namesrM  r4   rG  rú   r‹   s#   `                             @@@@@r+   rê  zTable._get_headerz  sï  øøøøøø€ ð, ŒyˆØˆð	ð 	ð 	ð 	ð 	ð	ð 	ð 	ð 	ð 	ð&	Ø”)˜A”,ˆCØ”IˆEÝ”< ¤Ñ)Ô)ˆDˆDøÝð 	ð 	ð 	Ø�4�4ð	øøøõ % T¨5°$·,²,±.´.ÀÔ2CÀUÑKÔKˆõ ˆtŒy‰>Œ>˜AÒÐØ!Ð!õ ˆu‰:Œ:˜Š>ˆ>Ø!Ð!ð Œy˜Œ|ˆÝÐ-Ð- $¤*Ð-Ñ-Ô-Ñ-Ô-ð 	"Ø!Ð!ð $�| DÑ)Ô)ˆð ð 	"  ¨T¬YÑ 7Ô 7ð 	"Ø!Ð!àÐ˜DÑ!Ô!ð 	"ð "Ð!ð FÐE¸%ÀÀÀ¼*ÐEÑEÔEˆð ˆuˆØˆŒØ”'ˆŒà—’˜v¨D½Ô8N�ÑOÔOØô
ˆõ ð	ð 	àð	ñ 	ô 	ð 'Ð&Øð
ñ 
ô 
ˆð ˆØˆØˆ
õ •s˜5‘z”zÑ"Ô"ð  	$ñ  	$ˆAØ�a”ˆAØ�6”˜1”ˆBØ�Q�v”Y˜q”\Ñ!ˆAØ�W”:¥Ô 6Ñ6ˆDð �AŠvˆvØ—’˜bÑ!Ô!Ð!Ø×#Ò# AÑ&Ô&Ð&Ø×!Ò! $Ñ'Ô'Ð'Øð ˜”ˆBØ˜bÔ!ˆBØ˜r”NˆEð �B‰w˜'Ò!Ð!¥S¨"¨r©'°Q°v´Y¸q´\Ñ)AÑ%BÔ%BÀgÒ%MÐ%MØ˜vœY qœ\¨2°©7°A°f´I¸a´LÀ"ÐE��&‘	Ø��a‘Ý#& r¨1¡:¤:�˜RÑ Øð *Ø%)�J˜r‘NÙØð ˜Tð Ø�Ø�B‰w˜˜r™Ò!Ð!Ø�Ø�MŠM˜"ÑÔÐØ×Ò Ñ"Ô"Ð"Ø×Ò˜dÑ#Ô#Ð#Ñ#à�RŠ<ˆ<Ø!Ð!à˜˜˜”ˆð Œ7�V˜A”YÑ ,¨q¤/Ò1Ð1Ø!Ð!ð ð 	" 
¨1¤ð 	"Ø!Ð!à�BŠ;ˆ;Ø!Ð!õ Ô"Ñ$Ô$ˆØAÐAÐAÐA˜UÐAÑAÔAð 	ð 	ˆAØ�Q�v”YÑˆEˆEØŒ~ð 	ØˆDà”'ˆŒð VÐU°4·=²=ÀÈt°=Ñ3TÔ3TÐUÑUÔUˆ
Ý�4¥Ð$>Ð$>°:Ð$>Ñ$>Ô$>Ñ ?Ô ?Ñ@Ô@È$ÐOÑOÔOˆ	àˆð ð 	ð 	ˆCðð ð ð ð àðñ ô ˆLð ˜rÒ!Ð!Ø—’˜cÑ"Ô"Ð"Ð"àà�RŠ<ˆ<Ø!Ð!à�5ˆØ˜R”jˆŒð
ð 
ð 
ð 
àð
ñ 
ô 
ˆ	ð ”i ”lˆŒØ”i ”lˆŒð
ð 
ð 
ð 
ð ð
ñ 
ô 
ˆ	õ �5 ™?œ?¨I°yÀ$ÑGÔGÐGs   ›-A	 Á	
AÁAr;   )FT)ri   )r]   r^   r_   r?   Úpropertyr‰   rï  Úsetterr  rÖ  r#  ró  r÷  r  r  r   r*  rê  ra   r-   r+   rÛ  rÛ  Š  sd  € € € € € ðð ð ð ð0 ð	
ð 	
ñ „Xð	
ð ðð ñ „Xðð, „]ðð ñ „]ðð ð*�dð *ð *ð *ñ „Xð*ð ð˜3ð ð ð ñ „Xðð ð6˜3ð 6ð 6ð 6ñ „Xð6ð$ 4ð $ð $ð $ð $ðLDð Dð Dð DðL'ð 'ð 'ð("%ð "%ð "%ðHeHð eHð eHð eHð eHð eHr-   rÛ  c                   ó  — e Zd ZU dZeed<   dZeed<   dZeed<   d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<   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d<   dd„Zedd„¦   «         Z dS )ÚTableSettingsrÃ   Úvertical_strategyÚhorizontal_strategyNÚexplicit_vertical_linesÚexplicit_horizontal_linesrë   rì   rí   rî   rï   rð   ri   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)rÝ   ÚverticalÚ	_strategyz_strategy must be one of{ú,Ú}N)rZ  r?  r½  ri   ))rì   rë   )rí   rë   )rï   rî   )rð   rî   )rõ   rô   )rö   rô   )	ÚNON_NEGATIVE_SETTINGSr1   r6  ÚTABLE_STRATEGIESr  rk  rA   ÚUNSETÚsetattr)r=   ÚsettingrÒ  Ústrategyr   Úfallbacks         r+   Ú__post_init__zTableSettings.__post_init__v  s~  € õ  -ð 	Rð 	RˆGÝ˜˜gÑ&Ô&Ð+¨!¨qÒ0Ð0Ý Ð!P°7Ð!PÐ!PÐ!PÑQÔQÐQð 1ð 6ð 	ð 	ˆKÝ˜t [°;Ñ%>Ñ?Ô?ˆHØÕ/Ð/Ð/Ý Ø"ð 8ð 8ØŸšÕ"2Ñ3Ô3ð8ð 8ð 8ñô ð ð 0ð ÔÐ%Ø!#ˆDÔð 3ð 	Rð 	RˆDØ˜4Ô-Ð-Ð-Ø+/Ô+=×+AÒ+AÀ+ÈqÑ+QÔ+Q�Ô" 4Ñ(øà˜$Ô,Ð,Ð,ØÔ" ;Ð/ð
ð 		=ð 		=‰NˆD�(õ �t˜TÑ"Ô"¥eÐ+Ð+Ý˜˜d¥G¨D°(Ñ$;Ô$;Ñ<Ô<Ð<øàˆr-   c                 ó$  — |€
 | ¦   «         S t          || ¦  «        r|S t          |t          ¦  «        rLi }i }|                     ¦   «         D ]&\  }}|d d…         dk    r|||dd …         <   Œ!|||<   Œ'||d<    | di |¤ŽS t          d|› �¦  «        ‚)NrE  Útext_rk  zCannot resolve settings: ra   )r  r/   r.   r6  )ÚclsÚsettingsÚcore_settingsrk  rŸ  rÑ  s         r+   ÚresolvezTableSettings.resolve«  sÑ   € àÐØ�3‘5”5ˆLÝ˜ #Ñ&Ô&ð 	EØˆOÝ˜¥$Ñ'Ô'ð 	EØˆMØˆMØ ŸšÑ(Ô(ð )ð )‘��1Ø�R�a�R”5˜GÒ#Ð#Ø+,�M ! A B B¤%Ñ(Ð(à'(�M !Ñ$Ð$Ø-:ˆM˜/Ñ*Ø�3Ð'Ð'˜Ð'Ð'Ð'åÐC¸ÐCÐCÑDÔDÐDr-   )r…   rf  r;   )!r]   r^   r_   rg  ÚstrÚ__annotations__rh  ri  r  rj  ÚDEFAULT_SNAP_TOLERANCErë   r2  rs  rì   rí   ÚDEFAULT_JOIN_TOLERANCErî   rï   rð   rñ   ÚDEFAULT_MIN_WORDS_VERTICALrò   ÚDEFAULT_MIN_WORDS_HORIZONTALró   rô   rõ   rö   rk  r/   rx  Úclassmethodr~  ra   r-   r+   rf  rf  b  sn  € € € € € € à$Ð�sÐ$Ð$Ñ$Ø&Ð˜Ð&Ð&Ñ&Ø$(Ð˜TÐ(Ð(Ñ(Ø&*Ð˜tÐ*Ð*Ñ*Ø2€N�EÐ2Ð2Ñ2Ø#Ð�eÐ#Ð#Ñ#Ø#Ð�eÐ#Ð#Ñ#Ø2€N�EÐ2Ð2Ñ2Ø#Ð�eÐ#Ð#Ñ#Ø#Ð�eÐ#Ð#Ñ#Ø€O�UÐÐÑØ :Ð˜Ð:Ð:Ñ:Ø">Ð˜%Ð>Ð>Ñ>Ø$%Ð˜EÐ%Ð%Ñ%Ø&+Ð˜eÐ+Ð+Ñ+Ø&+Ð˜eÐ+Ð+Ñ+Ø€M�4ÐÐÑð3ð 3ð 3ð 3ðj ðEð Eð Eñ „[ðEð Eð Er-   rf  c                   ó2   — e Zd ZdZdddœd„Zdefd„Z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
    N)Úcell_group_filterc                óÈ  ‡ — t          j        |¦  «        ‰ _        d ‰ _        t                               |¦  «        ‰ _        ‰                      ¦   «         ‰ _        t          ‰ j        ‰ j        j
        ‰ j        j        ¦  «        ‰ _        t          ‰ j        ¦  «        ‰ _        t          ‰ j        ‰ j        ¦  «        }|� |‰ j        |¦  «        }ˆ fd„|D ¦   «         ‰ _        d S )Nc                 ó:   •— g | ]}t          ‰j        |¦  «        ‘ŒS ra   )rÛ  r4   )r)   r  r=   s     €r+   r,   z(TableFinder.__init__.<locals>.<listcomp>Ú  s%   ø€ ÐCÐCÐC°5•u˜TœY¨Ñ.Ô.ÐCÐCÐCr-   )ÚweakrefÚproxyr4   r’   rf  r~  r|  Ú	get_edgesrû  rŒ  rõ   rö   rˆ  r©  rµ   rÄ  r¾  )r=   r4   r|  rˆ  r  s   `    r+   r?   zTableFinder.__init__Ê  sÊ   ø€ Ý”M $Ñ'Ô'ˆŒ	ØˆŒÝ%×-Ò-¨hÑ7Ô7ˆŒØ—^’^Ñ%Ô%ˆŒ
Ý3ØŒJØŒMÔ2ØŒMÔ2ñ
ô 
ˆÔõ
 ,¨DÔ,>Ñ?Ô?ˆŒ
Ý  ¤¨D¬JÑ7Ô7ˆØÐ(ð 'Ð& t¤y°&Ñ9Ô9ˆFØCÐCÐCÐC¸FÐCÑCÔCˆŒˆˆr-   r…   c           
      ód  — | 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t          t          fi |j        pi ¤Ž}ng }g }|j	        pg D ]ª}	t          |	t          ¦  «        r4t          |	¦  «        D ]#}
|
d         dk    r|                     |
¦  «         Œ$ŒK|                     |	|	| j        j        d         | j        j        d         | j        j        d         | j        j        d         z
  ddœ¦  «         Œ«|dk    rt!          t"          d¦  «        }nF|dk    rt!          t"          dd¬¦  «        }n(|d
k    rt%          ||j        ¬¦  «        }n|dk    rg }ng }||z   }g }|j        pg D ]ª}	t          |	t          ¦  «        r4t          |	¦  «        D ]#}
|
d         dk    r|                     |
¦  «         Œ$ŒK|                     | j        j        d         | j        j        d         | j        j        d         | j        j        d         z
  |	|	ddœ¦  «         Œ«|dk    rt!          t"          d¦  «        }nF|dk    rt!          t"          dd¬¦  «        }n(|d
k    rt+          ||j        ¬¦  «        }n|dk    rg }ng }||z   }t/          |¦  «        t/          |¦  «        z   }t1          ||j        |j        |j        |j        ¬¦  «        }t!          ||j        ¬¦  «        S )N)rm  rÝ   rn  rø   Ú	explicit_Ú_linesr%   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$   ri   rx  rÃ   r÷   rÛ   )r÷  )rR  rÐ  r   )ro   rp   rÜ  rú   rû   rÒ  )rì   rí   rï   rð   )rø  )r|  r1   rX   r6  rg  rh  r˜  rw   rk  ri  r  r/   rî  r3   r4   r!   rü  ÚEDGESrƒ  rò   rj  r]  ró   r  rE  rì   rí   rï   rð   rñ   )r=   r|  rÒ  rv  rÃ   Úv_stratÚh_stratr—  Ú
v_explicitÚdescró  Úv_baserÑ  Ú
h_explicitÚh_baserÐ  rû  s                    r+   r�  zTableFinder.get_edgesÜ  sð  € Ø”=ˆà5ð 
	ð 
	ˆKÝ˜x¨°{Ñ)BÑCÔCˆHØ˜:Ò%Ð%Ý ¨+¸Ñ*CÀhÑ*NÑOÔO�Ý�u‘:”: ’>�>Ý$ð(˜kð (ð (Ø$/ð(ð (ð (ñô ð øð Ô,ˆØÔ.ˆà�fÒÐ ¨6Ò 1Ð 1Ý!¥%ÐJÐJ¨HÔ,BÐ,HÀbÐJÐJˆEˆEàˆEàˆ
ØÔ4Ð:¸ð 	ð 	ˆDÝ˜$¥Ñ%Ô%ð Ý% dÑ+Ô+ð -ð -�AØ˜Ô'¨3Ò.Ð.Ø"×)Ò)¨!Ñ,Ô,Ð,øð-ð ×!Ò!à"Ø"Ø#œyœ~¨aÔ0Ø"&¤)¤.°Ô"3Ø"&¤)¤.°Ô"3°d´i´nÀQÔ6GÑ"GØ'*ðð ñ	ô 	ð 	ð 	ð �gÒÐÝ!¥%¨Ñ-Ô-ˆFˆFØ˜Ò&Ð&Ý!¥%¨¸Ð?Ñ?Ô?ˆFˆFØ˜ÒÐÝ% e¸HÔ<WÐXÑXÔXˆFˆFØ˜
Ò"Ð"ØˆFˆFàˆFà�ZÑˆàˆ
ØÔ6Ð<¸"ð 	ð 	ˆDÝ˜$¥Ñ%Ô%ð Ý% dÑ+Ô+ð -ð -�AØ˜Ô'¨3Ò.Ð.Ø"×)Ò)¨!Ñ,Ô,Ð,øð-ð ×!Ò!à"œiœn¨QÔ/Ø"œiœn¨QÔ/Ø!%¤¤°Ô!2°T´Y´^ÀAÔ5FÑ!FØ#Ø"&Ø'*ðð ñ	ô 	ð 	ð 	ð �gÒÐÝ!¥%¨Ñ-Ô-ˆFˆFØ˜Ò&Ð&Ý!¥%¨¸Ð?Ñ?Ô?ˆFˆFØ˜ÒÐÝ%Ø hÔ&Cðñ ô ˆFˆFð ˜
Ò"Ð"ØˆFˆFàˆFà�ZÑˆå�Q‘”�$˜q™'œ'Ñ!ˆåØØ%Ô6Ø%Ô6Ø%Ô6Ø%Ô6ð
ñ 
ô 
ˆõ ˜E¨hÔ.FÐGÑGÔGÐGr-   c                 ó�   — t          | j        ¦  «        }||k    rt          d¦  «        ‚|dk     r||z  }|dk     °| j        |         S )Nztable not on pager   )rX   r¾  rP  )r=   r»   Útcounts      r+   rS   zTableFinder.__getitem__?	  sR   € Ý�T”[Ñ!Ô!ˆØ�Š;ˆ;ÝÐ0Ñ1Ô1Ð1Ø�!ŠeˆeØ�‰KˆAð �!ŠeˆeàŒ{˜1Œ~Ðr-   r;   )r]   r^   r_   r`   r?   r  r�  rS   ra   r-   r+   r‡  r‡  ¿  sy   € € € € € ðð ðDÀð Dð Dð Dð Dð Dð$aH˜4ð aHð aHð aHð aHðFð ð ð ð r-   r‡  c                 ó”  — t                                ¦   «         }| j        dz   }| j        j        }| j        }|                      |t          ¦   «         ¬¦  «        }|                      d|¬¦  «        d         }|| j        z  }|D �]C}	|	d         D �]6}
|
d         }t          |d         d	¦  «        t          |d         d	¦  «        f}t          j        |d         |d          |d         |d         dd¦  «        }|d         dk    rd
}nd}t          |
d         d„ ¬¦  «        D �]¢}|d         }|d         }t          |d         t          j        z  p
|d         dz  ¦  «        }t          j        |d         ¦  «        }t          |d         d„ ¬¦  «        D �].}t          j        |d         ¦  «        }||z  }t          j        |d         ¦  «        |z  }|j        |_        |j        |_        |d         }i d|r|j        |j        z
  n|j        |j        z
  “d|j        “d|j        |z   “d|“d|j        |j        z
  “dt5          |¦  «        “d d!“d"|“d#d$“d%d&“d'|“d|r|n|j        |j        z
  “d(|“d)d$“d*|“d+|“d,|j        “||j        |j        z
  |j        |j        |j        |j        d-œ¥}|                     |¦  «         �Œ0�Œ¤�Œ8�ŒE|S ).z(Extract text as "rawdict" to fill CHARS.r$   r<  Úrawdict)r’   rÂ   rÃ   rÆ   r   rØ  TFrÇ   c                 ó   — | d         d         S ©Nr‰   r   ra   rC  s    r+   rœ   zmake_chars.<locals>.<lambda>o	  s   € ¸A¸f¼IÀa¼L€ r-   rž   ÚfontrÃ  rË   rÊ   é   ÚcolorrÈ   c                 ó   — | d         d         S rž  ra   )rs   s    r+   rœ   zmake_chars.<locals>.<lambda>v	  s   € ÀÀ&Ä	È!Ä€ r-   r‰   Úoriginrs   Úadvrû   r0  rÂ  rÛ  rd  ÚncsÚ	DeviceRGBÚnon_stroking_colorÚnon_stroking_patternNrÚ  rá   Úpage_numberÚstroking_colorÚstroking_patternr8  rÙ   rú   )rc  rÜ  ro   rp   rq   rr   )rw   rE   Únumberr!   rÛ  Útransformation_matrixÚget_textpagerg   rR  r±   r'   ÚMatrixr°   rN   rT  ÚsRGB_to_pdfr(   ÚPointr›   ró  rŠ   Úfrp   ro   rr   rq   r´   r3   )r4   r.  rÈ   r©  Úpage_heightÚctmÚTEXTPAGErÂ   Údoctop_baser¶   rÛ   Úldirrd  rc  rÞ   rÂ  ÚfontsizeÚ	span_boldr¡  rá   r‰   Úbbox_ctmr£  rÙ   Ú	char_dicts                            r+   Ú
make_charsr¼  ]	  sl  € å�KŠK‰MŒM€EØ”+ ‘/€KØ”)Ô"€KØ
Ô
$€CØ× Ò  dµ.Ñ2BÔ2BÐ ÑCÔC€HØ�]Š]˜9¨xˆ]Ñ8Ô8¸ÔB€FØ ¤Ñ+€KØð 0,ñ 0,ˆØ˜'”Nð /	,ñ /	,ˆDØ˜”;ˆDÝ˜$˜qœ' 1Ñ%Ô%¥u¨T°!¬W°aÑ'8Ô'8Ð9ˆDÝ”^ D¨¤G¨d°1¬g¨X°t¸A´wÀÀQÄÈÈAÑNÔNˆFØ�AŒw˜!Š|ˆ|Ø��à�Ý˜t Gœ}Ð2HÐ2HÐIÑIÔIð ',ñ ',�Ø œ<�Ø œ<�Ý Ø˜”M¥GÔ$:Ñ:ÐT¸dÀ<Ô>PÐSTÑ>Tñô �	õ  Ô+¨D°¬MÑ:Ô:�Ý" 4¨¤=Ð6LÐ6LÐMÑMÔMð  ,ñ  ,�DÝ"œ<¨¨V¬Ñ5Ô5�DØ# c™z�HÝ$œ]¨4°¬>Ñ:Ô:¸SÑ@�FØ%œx�F”HØ%œx�F”HØ œ9�Dð!Ø°GÐR˜tœw¨¬Ñ0Ð0ÀÄÈ4Ì7ÑARð!à  $¤'ð!ð ! $¤'¨KÑ"7ð!ð # Hð	!ð
 ! $¤'¨D¬GÑ"3ð!ð !¥%¨¡-¤-ð!ð ˜{ð!ð -¨eð!ð /°ð!ð & vð!ð & {ð!ð ¨GÐ J  ¸¼À4Ä7Ñ9Jð!ð )¨%ð!ð +¨Dð!ð  	ð!ð   ð!!ð" ˜tœwð#!ð$ $+Ø!%¤¨4¬7Ñ!2Ø"œgØ"œgØ&œkØ&œkð/!ð !ð !�Ið2 —L’L Ñ+Ô+Ð+Ñ+ñA ,ñ',ñ/	,ð` €Or-   c                 ón   — | j         |k    r| j         | j        k     p| j        |k    o| j        | j         k     S )z:Whether a rectangle is thin enough to be a simulated line.)rÜ  rÛ  ©r!   rø  s     r+   Ú_is_line_liker¿  Ÿ	  s<   € àŒJ˜*Ò$ÐA¨¬°d´kÒ)Að ØŒ�zÒ!Ð> d¤k°D´JÒ&>ðr-   c                 ó^   — t          | |¦  «        ot          | j        | j        ¦  «        |k    S )a;  Whether a rectangle inside a large fill path is a simulated line.

    A path's aggregate bbox is no evidence about its individual items, so a thin
    rectangle batched into a large fill can still be a grid rule. A thin *and
    short* one cannot: dot screens and vector-drawn glyph fragments consist of
    rectangles that are small in both directions, and a few hundred of them snap
    and join into one long spurious edge. A rule reaches at least the minimum
    edge length along its length, which is the same bound filter_edges() applies
    to the finished edges.)r¿  r{   rÜ  rÛ  r¾  s     r+   Ú_is_batched_rulerÁ  ¦	  s,   € õ ˜˜zÑ*Ô*ÐX­s°4´:¸t¼{Ñ/KÔ/KÈjÒ/XÐXr-   c                 ó’  ‡ ‡‡‡ ‡!‡"‡#‡$‡%‡&— t                                ¦   «         }|j        Š%|j        Š&|j        Š"|j        dk    p
|j        dk    Š!‰ j        j        Š#‰ j	        ‰#z  Š‰ j	        dz   Š$‰ j        }‰ j
        dv r!|j        \  }}	t          j        dd|	|¦  «        }|�t          j        |¦  «        }n|}ˆ%ˆ&fd„Šdˆˆ!ˆ"ˆ ˆ%ˆ&fd„	}
 |
|¬¦  «        \  }}ˆ%ˆ&fd„Š ˆˆ ˆ#ˆ$fd	„}|D �]®}|d
         }|d         rT|d         d         dk    rB|d         d         dk    r0|                     d|d         d         |d         d         f¦  «         |D �]C}|d         dvrŒ|d         dk    r@|dd …         \  }} |||||¦  «        }|r"|                     t          |¦  «        ¦  «         ŒZ|d         dk    �r|d                              ¦   «         }t#          |‰"¦  «        rë|j        |j        k     rTt'          |j        |j        z   ¦  «        dz  }t          j        ||j        ¦  «        }t          j        ||j        ¦  «        }nSt'          |j        |j        z   ¦  «        dz  }t          j        |j        |¦  «        }t          j        |j        |¦  «        } |||||¦  «        }|r"|                     t          |¦  «        ¦  «         �Œ| |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «         �Œn|d         \  }}}} |||||¦  «        }|r"|                     t          |¦  «        ¦  «          |||||¦  «        }|r"|                     t          |¦  «        ¦  «          |||||¦  «        }|r"|                     t          |¦  «        ¦  «          |||||¦  «        }|r"|                     t          |¦  «        ¦  «         �ŒE�Œ°dd ddœ}|D ]ò} |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «         Œó|�t9          |t:          t<          f¦  «        sJ ‚ng }|D ]_\  }}t          j        |¦  «        }t          j        |¦  «        } |||||¦  «        }|r"|                     t          |¦  «        ¦  «         Œ`|�t9          |t:          t<          f¦  «        sJ ‚ng }|D �]}t          j        |¦  «        } |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «          |||j        |j        |¦  «        }|r"|                     t          |¦  «        ¦  «         �Œ	d S )Nr÷   r$   ©rg  re  r   c                 óX  •— |j         ‰z
  | j         cxk    r|j        ‰z   k    s'n |j         ‰z
  | j        cxk    r|j        ‰z   k    rNn nK|j        ‰z
  | j        cxk    r|j        ‰z   k    s'n |j        ‰z
  | j        cxk    r|j        ‰z   k    rn ndS | j         ‰z
  |j         cxk    r| j        ‰z   k    s'n | j         ‰z
  |j        cxk    r| j        ‰z   k    rNn nK| j        ‰z
  |j        cxk    r| j        ‰z   k    s'n | j        ‰z
  |j        cxk    r| j        ‰z   k    rn ndS dS )aM  Detect whether r1, r2 are neighbors.

        Defined as:
        The minimum distance between points of r1 and points of r2 is not
        larger than some delta.

        This check supports empty rect-likes and thus also lines.

        Note:
        This type of check is MUCH faster than native Rect containment checks.
        TF)ro   rp   rq   rr   )r}   r~   Úsnap_xÚsnap_ys     €€r+   Úare_neighborsz!make_edges.<locals>.are_neighborsÈ	  sŠ  ø€ ð ŒE�F‰N˜bœeÐ5Ð5Ò5Ð5 r¤u¨v¡~Ò5Ð5Ð5Ð5ØŒu�v‰~ ¤Ð8Ð8Ò8Ð8¨"¬%°&©.Ò8Ð8Ð8Ð8Ð8àŒE�F‰N˜bœeÐ5Ð5Ò5Ð5 r¤u¨v¡~Ò5Ð5Ð5Ð5ØŒu�v‰~ ¤Ð8Ð8Ò8Ð8¨"¬%°&©.Ò8Ð8Ð8Ð8Ð8à�4ð ŒE�F‰N˜bœeÐ5Ð5Ò5Ð5 r¤u¨v¡~Ò5Ð5Ð5Ð5ØŒu�v‰~ ¤Ð8Ð8Ò8Ð8¨"¬%°&©.Ò8Ð8Ð8Ð8Ð8àŒE�F‰N˜bœeÐ5Ð5Ò5Ð5 r¤u¨v¡~Ò5Ð5Ð5Ð5ØŒu�v‰~ ¤Ð8Ð8Ò8Ð8¨"¬%°&©.Ò8Ð8Ð8Ð8Ð8à�4Øˆur-   c                 ó&  •— | €t          ‰d¬¦  «        }n
| dd…         }g }g }|D ]¡}‰rs|d         dk    rg|d         j        ‰k    rV|d         j        ‰k    rEˆfd„|d         D ¦   «         }|r.|                     ¦   «         }||d<   |                     |¦  «         Œw|                     |¦  «         |                     |¦  «         Œ¢t          t          d	„ |D ¦   «         ¦  «        d
„ ¬¦  «        }g }|rš|d         }	d}
|
r_d}
t          t          |¦  «        dz
  dd¦  «        D ]9} ‰|	||         ¦  «        r%|	||         j	        z  }	|	||         j
        z  }	||= d}
Œ:|
°_t          t          |	¦  «        r|                     |	¦  «         |d= |°š||fS )z:Detect and join rectangles of "connected" vector graphics.NTr   r–   r²  r!   c                 ó|   •— g | ]8}|d          dk    ¯t          |d                              ¦   «         ‰¦  «        ¯6|‘Œ9S )r   r#   r$   )rÁ  Ú	normalize)r)   r*   rø  s     €r+   r,   z6make_edges.<locals>.clean_graphics.<locals>.<listcomp> 
  sN   ø€ ð ð ð àØ˜A”w $’�Õ+;¸DÀ¼G×<MÒ<MÑ<OÔ<OÐQ[Ñ+\Ô+\�ð à&��r-   r.   c                 ó   — g | ]
}|d          ‘ŒS )r!   ra   )r)   Úps     r+   r,   z6make_edges.<locals>.clean_graphics.<locals>.<listcomp>
  s   € Ð;Ð;Ð;¨1˜Q˜vœYÐ;Ð;Ð;r-   c                 ó   — | j         | j        fS r;   )rr   ro   rª   s    r+   rœ   z4make_edges.<locals>.clean_graphics.<locals>.<lambda>
  s   € ÈQÌTÐSTÔSWÈL€ r-   rž   r   Fr$   r¢   )r7   rÜ  rÛ  Úcopyr3   r°   rB   r²   rX   ÚtlÚbrrx   rw   )ÚnpathsÚallpathsr6   Ú
bbox_pathsrÌ  Ú
line_itemsÚ	line_pathÚprectsÚ	new_rectsÚprect0Úrepeatr»   rÇ  r÷   rø  r4   rÅ  rÆ  s               €€€€€€r+   Úclean_graphicsz"make_edges.<locals>.clean_graphicsè	  s  ø€ àˆ>Ý*¨4¸Ð=Ñ=Ô=ˆHˆHà˜a˜a˜a”yˆHØˆØˆ
Øð 	!ð 	!ˆAð ðà�f”I Ò$Ð$Ø�f”I”O fÒ,Ð,Ø�f”IÔ$ vÒ-Ð-ðð ð ð à ! '¤
ðñ ô �
ð
 ð ,Ø !§¢¡¤�IØ)3�I˜gÑ&Ø—L’L Ñ+Ô+Ð+ØØ�LŠL˜‰OŒOˆOØ×Ò˜aÑ Ô Ð Ð õ �Ð;Ð;°
Ð;Ñ;Ô;Ñ<Ô<ÐBXÐBXÐYÑYÔYˆØˆ	ð ð 	Ø˜A”YˆFØˆFØð &Ø�Ý�s 6™{œ{¨Q™°°2Ñ6Ô6ð &ð &�AØ$�} V¨V°A¬YÑ7Ô7ð &Ø &¨¤)¤,Ñ.˜Ø &¨¤)¤,Ñ.˜Ø" 1˜IØ!%˜øð ð &õ �U FÑ+Ô+ð )à× Ò  Ñ(Ô(Ð(Ø�q�	ð! ð 	ð$ ˜%ÐÐr-   )rÑ  c                 óŒ   •— t          | j        |j        z
  ¦  «        ‰k    s t          | j        |j        z
  ¦  «        ‰k    rdS dS )z'Check if line is roughly axis-parallel.TF)rÏ   r›   rŠ   )rå  r“  rÅ  rÆ  s     €€r+   Úis_parallelzmake_edges.<locals>.is_parallel+
  sB   ø€ åˆrŒt�b”d‰{ÑÔ˜vÒ%Ð%­¨R¬T°B´D©[Ñ)9Ô)9¸VÒ)CÐ)CØ�4Øˆur-   c                 óä  •—  ‰||¦  «        si S t          |j        |j        ¦  «        }t          |j        |j        ¦  «        }t          |j        |j        ¦  «        }t          |j        |j        ¦  «        }||j        k    s!||j        k     s||j        k    s||j        k     ri S ||j        k     r|j        }||j        k    r|j        }||j        k     r|j        }||j        k    r|j        }||z
  }||z
  }	||	cxk    rdk    rn ni S i d|“d‰|z
  “d|“d‰|z
  “d|“d|	“d||f||fg“d	| d         “d
d“dd“dd“d| d         r| d         n| d         “dd“dd“d‰“dd“dd“|||‰z   dœ¥}
|
S )z;Given 2 points, make a line dictionary for table detection.r   ro   rq   rp   rr   rÜ  rÛ  rá  Ú	linewidthÚstrokeTÚfillFÚevenoddrª  r¡  r§  NrÚ  rÛ   r©  r«  r¨  )rú   rû   r0  )r|   r›   r{   rŠ   rp   ro   rr   rq   )rÌ  rå  r“  r.  ro   rp   rq   rr   rÜ  rÛ  Ú	line_dictÚdoctop_basisrÜ  r³  r©  s              €€€€r+   Ú	make_linezmake_edges.<locals>.make_line1
  s7  ø€ àˆ{˜2˜rÑ"Ô"ð 	ØˆIå�”�r”t‰_Œ_ˆÝ�”�r”t‰_Œ_ˆÝ�”�r”t‰_Œ_ˆÝ�”�r”t‰_Œ_ˆð �”Š<ˆ<˜2 ¤š<˜<¨2°´ª<¨<¸2ÀÄº<¸<ØˆIà�”Š<ˆ<Ø”ˆBà�”Š<ˆ<Ø”ˆBà�”Š<ˆ<Ø”ˆBà�”Š<ˆ<Ø”ˆBà�R‘ˆØ�b‘ˆØ�FÐÐÒÐ˜aÒÐÐÐÐØˆIð
Ø�"ð
à�+ Ñ"ð
ð �"ð
ð �+ Ñ"ð	
ð
 �Uð
ð �fð
ð �R˜�H˜r 2˜hÐ'ð
ð ˜˜7œð
ð �dð
ð �Eð
ð �uð
ð ¨A¨g¬JÐE˜a œj˜j¸A¸f¼Ið
ð ! $ð
ð ˜6ð
ð ˜;ð
ð   ð!
ð" # Dð#
ð$ ØØ˜<Ñ'ð)
ð 
ð 
ˆ	ð, Ðr-   r.   Ú	closePathr@  r¢   r%   )r@  r#   Úqur#   )r   r   r   )r¡  rà  rÜ  r;   )r‘  rE   rì   rí   rñ   rg  rh  r!   rÛ  r¬  rk  rÐ  r'   r(   r3   rÕ  rÊ  r¿  rÜ  rÏ   rp   ro   r±  rq   rr   rÏ  ÚblÚtrr  r´   r  )'r4   r.  Útsetr6   Ú	add_linesÚ	add_boxesrû  Úprectr®  rÐ  rÚ  rN  rä  rÌ  r.   r»   rå  r“  râ  r!   r›   rŠ   ÚulÚurÚllÚlrr0   r‰   Úboxrˆ   rÇ  rã  rÜ  r÷   rø  r³  r©  rÅ  rÆ  s'   `                             @@@@@@@@@r+   Ú
make_edgesrò  ³	  s)  øøøøøøøøøø€ Ý�KŠK‰MŒM€EØÔ"€FØÔ"€FØÔ%€JàÔ .Ò0ð 	6ØÔ# ~Ò5ð ð ”)Ô"€KØ”; Ñ,€LØ”+ ‘/€KØŒI€EØ„}˜	Ð!Ð!ØŒx‰ˆˆ1Ý”˜Q  1 aÑ(Ô(ˆØÐÝŒ|˜DÑ!Ô!ˆˆàˆðð ð ð ð ð ð@? ð ? ð ? ð ? ð ? ð ? ð ? ð ? ð ? ð ? ð ? ðB #�N¨%Ð0Ñ0Ô0�M€FˆEðð ð ð ð ð ð4ð 4ð 4ð 4ð 4ð 4ð 4ð 4ðl ð F:ñ F:ˆØ�'”
ˆð ˆ[Œ>ð 	;˜e Aœh qœk¨SÒ0Ð0°U¸2´Y¸q´\ÀSÒ5HÐ5HØ�LŠL˜#˜u Rœy¨œ|¨U°1¬X°a¬[Ð9Ñ:Ô:Ð:àð ?	:ñ ?	:ˆAØ�ŒtÐ,Ð,Ð,Øà�Œt�sŠ{ˆ{Ø˜1˜2˜2œ‘��BØ%˜I a¨¨R°Ñ6Ô6�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9øà�1”˜’‘ð ˜”t—~’~Ñ'Ô'�å   zÑ2Ô2ð Ø”z D¤KÒ/Ð/Ý ¤¨$¬'Ñ 1Ñ2Ô2°QÑ6˜Ý$œ]¨1¨d¬gÑ6Ô6˜Ý$œ]¨1¨d¬gÑ6Ô6˜˜å ¤¨$¬'Ñ 1Ñ2Ô2°QÑ6˜Ý$œ]¨4¬7°AÑ6Ô6˜Ý$œ]¨4¬7°AÑ6Ô6˜Ø ) 	¨!¨R°°TÑ :Ô :�IØ ð >ØŸš¥\°)Ñ%<Ô%<Ñ=Ô=Ð=Ùà%˜I a¨¬°$´'¸4Ñ@Ô@�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9à%˜I a¨¬°$´'¸4Ñ@Ô@�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9à%˜I a¨¬°$´'¸4Ñ@Ô@�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9à%˜I a¨¬°$´'¸4Ñ@Ô@�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9ùð "# 1¤‘��B˜˜Bà%˜I a¨¨R°Ñ6Ô6�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9à%˜I a¨¨R°Ñ6Ô6�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9à%˜I a¨¨R°Ñ6Ô6�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9à%˜I a¨¨R°Ñ6Ô6�	Øð :Ø—L’L¥¨iÑ!8Ô!8Ñ9Ô9Ð9ùñ?	:ðB ¨°qÐ9Ð9€DØð 2ð 2ˆØ�I˜d D¤G¨T¬W°dÑ;Ô;ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1à�I˜d D¤G¨T¬W°dÑ;Ô;ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1à�I˜d D¤G¨T¬W°dÑ;Ô;ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1à�I˜d D¤G¨T¬W°dÑ;Ô;ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1øàÐÝ˜)¥e­T ]Ñ3Ô3Ð3Ð3Ð3Ð3àˆ	Øð 2ð 2‰ˆˆBÝŒ]˜2ÑÔˆÝŒ]˜2ÑÔˆØ�I˜d B¨¨DÑ1Ô1ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1øàÐÝ˜)¥e­T ]Ñ3Ô3Ð3Ð3Ð3Ð3àˆ	Øð 2ñ 2ˆÝŒL˜ÑÔˆØ�I˜d A¤D¨!¬$°Ñ5Ô5ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1Ø�I˜d A¤D¨!¬$°Ñ5Ô5ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1Ø�I˜d A¤D¨!¬$°Ñ5Ô5ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1Ø�I˜d A¤D¨!¬$°Ñ5Ô5ˆ	Øð 	2Ø�LŠL� iÑ0Ô0Ñ1Ô1Ð1ùð2ð 2r-   c           	      óÆ  — | j         }| j        }| j         }|dk    r7t          j        dddd|j        |j        z
  |j        z
  |j        z
  d¦  «        }nf|dk    r7t          j        ddddd|j        |j        z
  |j        z
  |j        z
  ¦  «        }n)t          j        ddddd|j        z  d|j        z  ¦  «        }|| j        z  }dt          |¦  «        z  }t          j
                             | |d¦  «        }|dv r8|\  }}	}
}|	|_        ||_        ||_        |
|_        |                      |¦  «         |                      d¦  «         | j        }| j        }||         } | |||fS )zÅNullify page rotation.

    To correctly detect tables, page rotation must be zero.
    This function performs the necessary adjustments and returns information
    for reverting this changes.
    rg  r$   r   re  éþÿÿÿs   %g %g %g %g %g %g cm rÃ  )Úmediaboxrk  r'   r¯  rr   rp   ro   rq   Úderotation_matrixr´   rá  Ú_insert_contentsÚset_mediaboxÚset_rotationÚparentr¬  )r4   rõ  ÚrotÚmbÚmat0ÚmatÚcmdÚxrefro   rq   rp   rr   ÚdocÚpnos                 r+   Úpage_rotation_set0r  à
  sp  € ð Œ}€HØ
Œ-€Cà	Œ€Bà
ˆb‚y€yåŒ~˜a  A q¨"¬%°"´%©-¸"¼%Ñ*?À"Ä%Ñ*GÈÑKÔKˆˆØ	�ŠˆåŒ~˜a  A q¨!¨R¬U°R´U©]¸R¼UÑ-BÀRÄUÑ-JÑKÔKˆˆåŒ~˜a  A q¨"¨r¬u©*°b¸2¼5±jÑAÔAˆð �Ô'Ñ
'€CØ
"¥U¨3¡Z¤ZÑ
/€CÝŒ=×)Ò)¨$°°QÑ7Ô7€Dð ˆiÐÐØ‰ˆˆB��BØˆŒØˆŒØˆŒØˆŒØ×Ò˜"ÑÔÐà×Ò�aÑÔÐð Œ+€CØ
Œ+€CØˆsŒ8€DØ��s˜HÐ$Ð$r-   c                 ó²   — | j         }|                     |d¦  «         |                      |¦  «         |                      |¦  «         | j        }||         } | S )zPReset page rotation to original values.

    To be used before we return tables.ó    )rú  Úupdate_streamrø  rù  r¬  )r4   r   rû  rõ  r  r  s         r+   Úpage_rotation_resetr    s^   € ð Œ+€CØ×Ò�d˜DÑ!Ô!Ð!Ø×Ò�hÑÔÐØ×Ò�cÑÔÐØ
Œ+€CØˆsŒ8€DØ€Kr-   c           	      óJ  — t          ¦   «         }d}t          | ¦  «        D ]‚\  }}d}|D ]x}||f|v r|dz  }||f|v °t          |j        ¦  «        D ]6}t          |j        ¦  «        D ]}|                     ||z   ||z   f¦  «         Œ Œ7||j        z  }t          ||¦  «        }ŒyŒƒ|S )zBColumn extent of a placement grid after resolving colspan/rowspan.r   r$   )rB   r7  r²   r  r  r»  r{   )	rå  ÚoccupiedÚmax_colÚrow_idxrØ  Úcol_idxÚ	placementÚdrÚdcs	            r+   Ú_refine_placement_grid_widthr  !  sï   € å‰uŒu€HØ€GÝ! *Ñ-Ô-ð 	,ð 	,‰ˆ�ØˆØð 	,ð 	,ˆIØ˜GÐ$¨Ð0Ð0Ø˜1‘�ð ˜GÐ$¨Ð0Ð0å˜IÔ-Ñ.Ô.ð ?ð ?�Ý 	Ô 1Ñ2Ô2ð ?ð ?�BØ—L’L '¨B¡,°¸"±Ð!=Ñ>Ô>Ð>Ð>ð?à�yÔ(Ñ(ˆGÝ˜' 7Ñ+Ô+ˆGˆGð	,ð €Nr-   c           
      ó8  — t          | ¦  «        }g }|D �]}g }|D ]›}|€'|                     t          dddd¬¦  «        ¦  «         Œ+t          j        |¦  «        }d„ t          ||| ¬¦  «        D ¦   «         }	|                     t          t          |¦  «        t          |	¦  «        dd¬¦  «        ¦  «         Œœt          |¦  «        |k     r9|                     t          dddd¬¦  «        ¦  «         t          |¦  «        |k     °9|                     |¦  «         �Œ|S )a#  Flat fallback grid: one 1x1 SpanCell per slot, padded to ``col_count``.

    Selects words per cell by center-point and synthesizes each cell's line text
    ("" for a gap), using the same word source and line builder as resolve_spans.
    Used when span resolution changes the column count.NrÁ   r$   r  c                 ó2   — g | ]\  }}t          |¦  «        ‘ŒS ra   )r   )r)   rÌ   rL  s      r+   r,   z/_refine_flat_placement_grid.<locals>.<listcomp>A  s4   € ð ð ð á˜˜4õ *¨$Ñ/Ô/ðð ð r-   )r4   )	r   r3   r   r'   r(   r   r´   r   rX   )
r4   rµ   r÷  Ú
page_wordsÚgridrØ  Úoutr¾   r!   Ú
line_wordss
             r+   Ú_refine_flat_placement_gridr  2  sM  € õ $ DÑ)Ô)€JØ€DØð ñ ˆØˆØð 	ð 	ˆDØˆ|Ø—
’
�8¨°BÀÈ1ÐMÑMÔMÑNÔNÐNÐNå”| DÑ)Ô)�ðð å#=¸jÈ$ÐUYÐ#ZÑ#ZÔ#Zðñ ô �
ð —
’
ÝÝ" 4™[œ[Ý5°jÑAÔAØ !Ø !ð	ñ ô ñô ð ð õ �#‰hŒh˜Ò"Ð"Ø�JŠJ•x T°¸AÀqÐIÑIÔIÑJÔJÐJõ �#‰hŒh˜Ò"Ð"à�Š�CÑÔÐÑØ€Kr-   ©Ústrict_colspanÚheader_row_countc                óª   — t          d„ |D ¦   «         d¬¦  «        }t          | |||¬¦  «        }t          |¦  «        |k    r|S t          | ||¦  «        S )zìThe reconstructed cell grid: resolved SpanCell placements, or the flat 1x1
    fallback when span resolution changes the column count (grid width != col
    count). ``strict_colspan``/``header_row_count`` pass straight to resolve_spans.c              3   ó4   K  — | ]}t          |¦  «        V — Œd S r;   rU  r  s     r+   rt   z1_refine_placement_or_flat_grid.<locals>.<genexpr>W  s(   è è € Ð/Ð/ #•S˜‘X”XÐ/Ð/Ð/Ð/Ð/Ð/r-   r   r   )r  r  )r{   r   r  r  )r4   rµ   r  r  r÷  rå  s         r+   Ú_refine_placement_or_flat_gridr  S  sp   € õ Ð/Ð/¨Ð/Ñ/Ô/¸Ð;Ñ;Ô;€IÝØˆeÐ&6À~ðñ ô €Jõ $ JÑ/Ô/°9Ò<Ð<ØÐÝ& t¨U°IÑ>Ô>Ð>r-   c                 ó   — d„ | D ¦   «         S )zORow-major whitespace-collapsed cell text -- the ``[[text]]`` header rules read.c                 ó&   — g | ]}d „ |D ¦   «         ‘ŒS )c                 ó6   — g | ]}t          |j        ¦  «        ‘ŒS ra   )r   rÙ   rÓ  s     r+   r,   z;_refine_placements_text_grid.<locals>.<listcomp>.<listcomp>b  s#   € Ð9Ð9Ð9¨TÕ˜dœiÑ(Ô(Ð9Ð9Ð9r-   ra   r  s     r+   r,   z0_refine_placements_text_grid.<locals>.<listcomp>b  s'   € ÐJÐJÐJ¸cÐ9Ð9°SÐ9Ñ9Ô9ÐJÐJÐJr-   ra   )r  s    r+   Ú_refine_placements_text_gridr!  `  s   € àJÐJÀTÐJÑJÔJÐJr-   c                 óX   — t          | ¦  «        D ]\  }}|D ]}||k     rdnd|_        ŒŒ| S )zxSet each placement's HTML tag in place: cells in the top header rows
    become ``th``; every other cell becomes ``td``.ÚthÚtd)r7  Útag)r  Útop_header_rowsr  rØ  r¾   s        r+   Ú_refine_tag_gridr'  e  sR   € õ " $™œð Cð C‰ˆ�Øð 	Cð 	CˆDØ&¨Ò8Ð8�t�t¸dˆDŒHˆHð	Cà€Kr-   c                 ó  — 	 t          | |¦  «        }t          t          |¦  «        ¦  «        }n# t          $ r Y dS w xY wt	          |j        ¦  «        }|||r+t          dt          |t          |¦  «        ¦  «        ¦  «        ndfS )a  The merge-preserved model grid plus the header counts derived from it.

    Returns ``(grid, header_rows, body_start)``. ``grid`` is None when span
    resolution or the header rules fail. ``header_rows`` is the header finder's
    own count, where 0 means it found no header row at all; ``body_start`` is
    that count clamped to [1, rows], which is what the row splitter needs. One
    resolve_spans pass serves both the header/body boundary and the repeated-
    header split check, so the split costs no extra pass.
    )Nr   r$   r$   r   )	r  r   r!  Ú	Exceptionr#  r&  r{   r|   rX   )r4   rµ   r  Úregionræ  s        r+   Ú_refine_model_gridr+  n  s’   € ðÝ-¨d°EÑ:Ô:ˆÝ#Õ$@ÀÑ$FÔ$FÑGÔGˆˆøÝð ð ð Øˆzˆzðøøøå�fÔ,Ñ-Ô-€KØ�ÀuÐS�s 1¥c¨+µs¸5±z´zÑ&BÔ&BÑCÔCÐCÐRSÐTÐTs   ‚,/ ¯
=¼=c                 ó6   — t          | |¦  «        \  }}}|€dn|S )z›Header/body boundary: resolve the merge-preserved placement grid once and
    ask the header finder how many leading rows are header, clamped to [1, rows].Nr$   )r+  )r4   rµ   r  Ú_header_rowsÚ
body_starts        r+   Ú_refine_body_start_rowr/  �  s(   € õ &8¸¸eÑ%DÔ%DÑ"€Dˆ,˜
Ø�ˆ1ˆ1 *Ð,r-   c           	      ó²  ‡‡	— d„ | D ¦   «         Š‰sdS t          d„ ‰D ¦   «         ¦  «        }|dk     rdS t          t          t          t          |¦  «        d¦  «        t	          ‰¦  «        ¦  «        ¦  «        D ]Ý}‰|         Š	t	          ‰	¦  «        dz  |k     rŒ!d„ ‰	D ¦   «         }t	          |¦  «        dk     rŒAt          d„ |D ¦   «         ¦  «        sŒ[ˆˆ	fd„t          |d	z   t	          ‰¦  «        ¦  «        D ¦   «         }|sŒ‹|g|¢}g |¢t	          ‰¦  «        ‘}t          d
„ t          ||¦  «        D ¦   «         ¦  «        rt          |¦  «        c S  dS dS )aq  Rows at which an exactly repeated leading header splits a stacked table.

    Several tables printed one under another with no gap are detected as one
    grid, and the giveaway is that their shared header row recurs verbatim. The
    signature is the first row that carries at least two non-empty cells in a
    grid at least two columns wide and is not purely numeric or punctuation; it
    must also be a leading row -- inside the header region the header rules found,
    or within the first three rows, because that finder is conservative and a
    title row and a units row often precede the real header. A repeat further down
    is data, not a header. Repeats are matched on case- and whitespace-normalized
    text only: no fuzzy matching.

    A header signature also carries the grid's column structure, so it must hold
    at least half as many placements as the widest row: a row of a few spanning
    cells is a group header -- a sub-header such as "From- / To-" under an
    eight-column header, which recurs inside one table -- and not the header.

    A repeat is accepted as a cut only if the result really looks like a stack of
    tables rather than a table that happens to repeat a row: every segment must
    hold at least one row below its own signature row. That single structural
    invariant rejects both adjacent duplicate header rows (one header, not a cut)
    and a trailing repeat with no records under it, and it needs no row-count
    constant. Each cut row opens its segment by construction; the first segment
    may carry a title row above the signature. Returns the cut row indices, or ()
    for no split.
    c                 ó@   — g | ]}t          d „ |D ¦   «         ¦  «        ‘ŒS )c              3   óX   K  — | ]%}t          |¦  «                             ¦   «         V — Œ&d S r;   )r   Úcasefold©r)   rÙ   s     r+   rt   zB_refine_repeated_leading_header_cuts.<locals>.<listcomp>.<genexpr>¤  s7   è è € Ð@Ð@°DÕ˜tÑ$Ô$×-Ò-Ñ/Ô/Ð@Ð@Ð@Ð@Ð@Ð@r-   )r´   r  s     r+   r,   z8_refine_repeated_leading_header_cuts.<locals>.<listcomp>£  s<   € ð ð ð ØEH�Ð@Ð@¸CÐ@Ñ@Ô@Ñ@Ô@ðð ð r-   ra   c              3   ó4   K  — | ]}t          |¦  «        V — Œd S r;   rU  r  s     r+   rt   z7_refine_repeated_leading_header_cuts.<locals>.<genexpr>¨  s(   è è € Ð/Ð/˜S•�C‘”Ð/Ð/Ð/Ð/Ð/Ð/r-   r%   ri   c                 ó   — g | ]}|¯|‘ŒS ra   ra   r4  s     r+   r,   z8_refine_repeated_leading_header_cuts.<locals>.<listcomp>±  s   € Ð7Ð7Ð7˜T°$Ð7�DÐ7Ð7Ð7r-   c              3   óH   K  — | ]}|D ]}|                      ¦   «         V — ŒŒd S r;   )Úisalpha)r)   rÙ   rá   s      r+   rt   z7_refine_repeated_leading_header_cuts.<locals>.<genexpr>´  s7   è è € ÐHÐH dÀ4ÐHÐH¸4�4—<’<‘>”>ÐHÐHÐHÐHÐHÐHÐHr-   c                 ó,   •— g | ]}‰|         ‰k    ¯|‘ŒS ra   ra   )r)   Ú	row_indexÚ
normalizedÚ	signatures     €€r+   r,   z8_refine_repeated_leading_header_cuts.<locals>.<listcomp>¶  s3   ø€ ð 
ð 
ð 
àØ˜)Ô$¨	Ò1Ð1ð à1Ð1Ð1r-   r$   c              3   ó.   K  — | ]\  }}||z
  d k    V — ŒdS )r%   Nra   )r)   r  r  s      r+   rt   z7_refine_repeated_leading_header_cuts.<locals>.<genexpr>¿  s/   è è € ÐTÐT¡J E¨3ˆs�U‰{˜aÒÐTÐTÐTÐTÐTÐTr-   )	r{   r²   r|   r#  rX   rv   rQ  rç  r´   )
rÖ  ræ  rÜ  rÌ  ÚnonemptyÚrepeatsÚsignature_rowsÚsegment_endsr;  r<  s
           @@r+   Ú$_refine_repeated_leading_header_cutsrB  ˆ  s¹  øø€ ð6ð ØLPðñ ô €Jð ð ØˆrÝÐ/Ð/ JÐ/Ñ/Ô/Ñ/Ô/€EØˆq‚y€yØˆrõ •s�3�s ;Ñ/Ô/°Ñ3Ô3µS¸±_´_ÑEÔEÑFÔFð ð ˆØ˜uÔ%ˆ	Ýˆy‰>Œ>˜AÑ Ò%Ð%ØØ7Ð7 YÐ7Ñ7Ô7ˆÝˆx‰=Œ=˜1ÒÐØÝÐHÐH¨hÐHÑHÔHÑHÔHð 	Øð
ð 
ð 
ð 
ð 
å" 5¨1¡9­c°*©o¬oÑ>Ô>ð
ñ 
ô 
ˆð
 ð 	ØØÐ* 'Ð*ˆØ2˜Ð2¥# j¡/¤/Ð2ˆÝÐTÐTµ#°nÀlÑ2SÔ2SÐTÑTÔTÑTÔTð 	"Ý˜‘>”>Ð!Ð!Ð!ØˆrˆrØˆ2r-   c                 óæ   — t          | |d|¬¦  «        }t          t          |¦  «        ¦  «        }t          ||j        ¦  «        }t          ||j        ¦  «        }t          ||j        ¦  «        }||fS )zãResolve the final placement grid (strict colspan, header boundary known),
    run header rules on its own text grid, complete the header under spanning
    header cells from the grid's spans, tag cells -> (tagged grid, region).Tr  )r  r   r!  r   r&  r   Úsection_header_rowsr'  )r4   Úworkingr.  r  r*  ÚdepthÚtaggeds          r+   Ú_refine_build_placementsrH  Å  s{   € õ *Øˆg d¸Zðñ ô €Dõ  Õ <¸TÑ BÔ BÑCÔC€Fõ & d¨FÔ,BÑCÔC€EÝ˜% Ô!;Ñ<Ô<€FÝ˜d FÔ$:Ñ;Ô;€FØ�6ˆ>Ðr-   c              #   ó   ‡K  — t          |j        ¦  «        }t          | ||j        ¬¦  «        Št	          | ‰¦  «        \  }}}|€d}d}nt          t          |¦  «        |¦  «        }|r:dg|¢t          ‰¦  «        ‘R }ˆfd„t          ||dd…         ¦  «        D ¦   «         }n‰g}t          |¦  «        dk    }	|D ]’}
|	rt          | |
¦  «        n|}t          | |
|¬¦  «        }
t          |
¦  «        }|s|	rŒ<|rt          | ||	rdn|j        ¬¦  «        n|}t          | |
|¦  «        \  }}||_        |j        |_        |j        |_        |V — Œ“dS )	aO  Refine one detected table's grid and yield the resulting tagged tables.

    Order: structural split (shaded rows + under-segmented columns), the model
    grid that carries both the header/body boundary and the repeated-header split
    decision, then per segment the body-row split, the final merged-cell
    placement grid and the td/th tagging. A grid whose leading header row recurs
    verbatim is several tables printed under one another and yields one table per
    segment; that is the ordinary case of one segment, which yields exactly the
    table the unsplit path produced.
    )Ú
table_bboxNr$   ra   r   c                 ó*   •— g | ]\  }}‰||…         ‘ŒS ra   ra   )r)   r  r  rE  s      €r+   r,   z'_refine_grid_tables.<locals>.<listcomp>ð  s&   ø€ ÐYÐYÐY©:¨5°#�G˜E #˜IÔ&ÐYÐYÐYr-   )r  rG  )r
   rµ   r   r‰   r+  rB  r!  rX   rç  r/  r	   r   rÛ  rÞ  rH  rå  r&  ræ  rD  rç  )r4   Útabr  Ú
model_gridræ  r.  ÚcutsÚ
boundariesÚsegmentsÚ	was_splitÚsegmentr  ÚflatÚnew_tabrå  r*  rE  s                   @r+   Ú_refine_grid_tablesrU  Õ  sº  øè è € õ ! ¤Ñ+Ô+€Dõ $ D¨$¸3¼8ÐDÑDÔD€GÝ*<¸TÀ7Ñ*KÔ*KÑ'€J�˜ZØÐØˆ
Øˆˆõ 4Ý(¨Ñ4Ô4°kñ
ô 
ˆð ð ØÐ-˜$Ð-¥ G¡¤Ð-Ð-ˆ
ØYÐYÐYÐY½¸ZÈÐTUÐTVÐTVÌÑ9XÔ9XÐYÑYÔYˆˆà�9ˆÝ�H‘” Ò!€IØð ð ˆð :CÐRÕ& t¨WÑ5Ô5Ð5È
ˆÝ" 4¨À5ÐIÑIÔIˆÝ$ WÑ-Ô-ˆØð 	˜	ð 	Øð OSÐ[•%˜˜d°Ð)I¨¨ÀÄ	ÐJÑJÔJÐJÐX[ˆõ 6°d¸GÀUÑKÔKÑˆ
�FØ'ˆÔØ$Ô4ˆÔØ%Ô9ˆÔØˆˆˆˆð%ð r-   rÃ   Trg  rh  Úvertical_linesÚhorizontal_linesrë   rì   rí   rî   rï   rð   rñ   rò   ró   rô   rõ   rö   Ú
use_layoutÚunionÚrefinec                 ó0  ‡1‡2— t          j        ¦   «          t                               g ¦  «         t                               g ¦  «         t          t           j                             ¦   «         ¦  «        }t           j                             d¦  «         | j        dk    rt          | ¦  «        \  } }}} nd\  }}} t          | dd¦  «        du }!|!r	 g | _        n# t          $ r d}!Y nw xY w|€t          }|€t          }|
€t          }
|€t          }|€t          }|€t          }|�|}|}i d|“d|“d	|“d
|“d|“d|“d|“d|	“d|
“d|“d|“d|“d|“d|“d|“d|“d|“||dœ¥}"t           j                             ¦   «         }#	 |rddlm}$  |$| ||¬¦  «        Š2‰2j        }%�nôg Š1|rìt           j                             d¦  «         |                      ¦   «          | j        r0t           j                             d¦  «         d„ | j        D ¦   «         Š1‰1s€| j        �yt)          | ¦  «        Š2‰2|!r	 | `n# t          $ r Y nw xY wt           j                             |¦  «         |�t+          | ||| ¦  «        } t           j                             |#¦  «         S t,                               |"¬¦  «        }&|&| _        t3          | |¬¦  «        }%t5          | ||&|||¬¦  «         t)          | |&|¬¦  «        Š2|%‰2_        ‰1rˆ1fd „‰2j        D ¦   «         ‰2_        ˆ2fd!„‰1D ¦   «         }'|'r9d"„ |%                     ¦   «         D ¦   «         }(|                      t<          ¬#¦  «        })|'D ]=}*t?          |)|(|*¦  «        }+|+r(‰2j                              tC          | |+¦  «        ¦  «         Œ>|r6g },‰2j        D ]%}-|, "                    tG          | |-¦  «        ¦  «         Œ&|,‰2_        |�#‰2j        D ]}.|. $                    ¦   «         |._%        Œn¤# t          $ r—}/t          j&        d$tO          |/¦  «        z  ¦  «         Y d}/~/|!r	 | `n# t          $ r Y nw xY wt           j                             |¦  «         |�t+          | ||| ¦  «        } t           j                             |#¦  «         dS d}/~/ww xY w|!r	 | `n# t          $ r Y nw xY wt           j                             |¦  «         |�t+          | ||| ¦  «        } t           j                             |#¦  «         nm# |!r	 | `n# t          $ r Y nw xY wt           j                             |¦  «         |�t+          | ||| ¦  «        } t           j                             |#¦  «         w xY wtQ          tR          ¦  «        }0‰2j        D ]}.|%|._        |0|._*        Œ‰2S )%aÏ  Detect and extract tables on a page.

    use_layout: if True (default), use page.get_layout() to find layout-
    identified table regions and use them to restrict/complete line-based
    detection; if layout ran and found no tables, return an empty result
    immediately. Set False to always run full detection.

    union: if True (requires the layout analyzer), detect tables by fusing the
    layout analyzer's table grids with the line-based finder's candidates -- a
    candidate matching a layout table 1:1 can replace its grid, candidates
    contained in one layout table can split it, and unowned candidates are
    appended -- returning the fused tables in layout order then appended order.
    Off by default. Needs the raw layout form: when page.layout_information is
    None it is computed with page.get_layout(return_raw=True); when already
    populated it is reused as-is.

    refine: if True, refine each detected table's cell grid before building the
    Table -- splitting rows/columns the line grid merged (using page text and
    background shading) -- then reconstruct its merged-cell structure and header
    semantics. The tagged grid is attached as Table.placements (a row-major grid
    of SpanCell colspan/rowspan placements, each carrying its td/th tag; None on
    the default path), the header meta as Table.header_rows/section_rows, and
    Table.to_html() serializes it. Off by default. A grid whose column count the
    span resolution cannot preserve falls back to a flat one-cell-per-slot
    placement grid. A refined grid whose leading header row recurs verbatim is
    split into one table per recurrence: that is several tables printed under one
    another which the line grid detected as one.
    Tr   )NNNr   NFrg  rh  ri  rj  rë   rì   rí   rî   rï   rð   rñ   rò   ró   rô   rõ   rö   Útext_tolerance)Útext_x_toleranceÚtext_y_tolerance)Ú_find_tables_union)rê  rë  c                 ó^   — g | ]*}|d          dk    ¯t          j        |dd…         ¦  «        ‘Œ+S )r¢   ÚtableNrØ  r&   )r)   r`  s     r+   r,   zfind_tables.<locals>.<listcomp>”  sC   € ð ð ð Ø01ÐPQÐRTÔPUÐY`ÒP`ÐP`�œ Q r¨ r¤UÑ+Ô+ÐP`ÐP`ÐP`r-   )r|  r-  )r.  ré  r6   rê  rë  )r|  rˆ  c                 óL   •‡— g | ]Št          ˆfd „‰D ¦   «         ¦  «        ¯‰‘Œ S )c              3   óJ   •K  — | ]}t          ‰j        |¦  «        d k    V — ŒdS ©g333333ã?N©r„   r‰   )r)   rˆ   rL  s     €r+   rt   z)find_tables.<locals>.<listcomp>.<genexpr>²  s4   øè è € ÐCÐC¸�4 ¤¨!Ñ,Ô,°Ò3ÐCÐCÐCÐCÐCÐCr-   ru   )r)   rL  Úboxess    @€r+   r,   zfind_tables.<locals>.<listcomp>¯  sM   øø€ ð ð ð àÝÐCÐCÐCÐC¸UÐCÑCÔCÑCÔCðØðð ð r-   c                 óV   •‡— g | ]$Št          ˆfd „‰j        D ¦   «         ¦  «        ¯"‰‘Œ%S )c              3   óJ   •K  — | ]}t          ‰|j        ¦  «        d k     V — ŒdS rd  re  )r)   rL  rˆ   s     €r+   rt   z)find_tables.<locals>.<listcomp>.<genexpr>¶  s4   øè è € Ð'VÐ'VÀC­¨Q°´Ñ(9Ô(9¸CÒ(?Ð'VÐ'VÐ'VÐ'VÐ'VÐ'Vr-   )rQ  r¾  )r)   rˆ   Útbfs    @€r+   r,   zfind_tables.<locals>.<listcomp>µ  sN   øø€ ð ð ð Ø¥CÐ'VÐ'VÐ'VÐ'VÈ3Ì:Ð'VÑ'VÔ'VÑ$VÔ$VðØðð ð r-   c                 óF   — g | ]}t          j        |d d…         ¦  «        ‘ŒS rI  r&   r±  s     r+   r,   zfind_tables.<locals>.<listcomp>¹  s*   € ÐSÐSÐS°a�gœl¨1¨R¨a¨R¬5Ñ1Ô1ÐSÐSÐSr-   )rË   z#find_tables: exception occurred: %s)+r'   Ú_warn_layout_onceÚ
_CHARS_VARrB   Ú
_EDGES_VARrN   rá  râ  rk  r  r1   r   r)  rs  rã  Úpymupdf._table_unionr_  r’   Ú
get_layoutÚlayout_informationr‡  r  rf  r~  Útable_settingsr¼  rò  r¾  ÚextractWORDSr®  ÚTABLE_DETECTOR_FLAGSr¿   r3   rÛ  rL   rU  rê  rà  r$  r  r  rw   rÝ  )3r4   r.  rg  rh  rV  rW  rë   rì   rí   rî   rï   rð   rñ   rò   ró   rô   rõ   rö   r\  r]  r^  rv  rê  rë  r6   rX  rY  rZ  Ú_cell_group_filterrí  Úold_xrefÚold_rotÚold_mediaboxÚowns_drawingsr|  Úold_quad_correctionsr_  rµ  ré  Úmy_boxesr‹   Útp2r!   rµ   Úrefined_tablesrL  ra  ró  rÈ   rf  ri  s3                                                    @@r+   Úfind_tablesr}  	  s�  øø€ õv ÔÑÔÐÝ‡N‚N�2ÑÔÐÝ‡N‚N�2ÑÔÐÝ•W”]×:Ò:Ñ<Ô<Ñ=Ô=€IÝ„M×)Ò)¨$Ñ/Ô/Ð/Ø„}˜ÒÐÝ0BÀ4Ñ0HÔ0HÑ-ˆˆh˜  à*:Ñ'ˆ�'˜<õ
 ˜DÐ"9¸4Ñ@Ô@ÀDÐH€MØð "ð	"Ø)+ˆDÔ&Ð&øÝð 	"ð 	"ð 	"Ø!ˆMˆMˆMð	"øøøð ÐÝ ÐØÐÝ ÐØÐÝ ÐØÐÝ ÐØÐ'Ý#(Ð ØÐ'Ý#(Ð ØÐØ$ÐØ&ÐðØÐ.ðàÐ2ðð 	" >ðð 	$Ð%5ð	ð
 	˜.ðð 	Ð,ðð 	Ð,ðð 	˜.ðð 	Ð,ðð 	Ð,ðð 	˜?ðð 	Ð0ðð 	Ð 4ðð 	!Ð"8ðð 	#Ð$<ðð  	#Ð$<ð!ð" 	˜.ð#ð$ -Ø,ð'ð ð €Hõ, #œ=×?Ò?ÑAÔAÐðaCØð >	:ð @Ð?Ð?Ð?Ð?Ð?Ø$Ð$ T°YÈ)ÐTÑTÔTˆCØ”|ˆH‰HàˆEØð õ ”×4Ò4°TÑ:Ô:Ð:Ø—’Ñ!Ô!Ð!ØÔ*ð Ý”M×8Ò8¸Ñ>Ô>Ð>ðð Ø59Ô5Lðñ ô �Eð ð  Ô!8Ð!Dõ & dÑ+Ô+�CØðx ð 	ðØÐ.Ð.øÝð ð ð Ø�ðøøøåŒ×-Ò-¨iÑ8Ô8Ð8ØÐÝ& t¨X°wÀÑMÔMˆDÝŒ×,Ò,Ð-AÑBÔBÐBÐBõE !×(Ò(°(Ð(Ñ;Ô;ˆDØ"&ˆDÔå! $¨TÐ2Ñ2Ô2ˆHÝØØØØØ#Ø#ðñ ô ð õ ˜d¨TÐEWÐXÑXÔXˆCØ#ˆCŒLØð ðð ð ð à"œzðñ ô �”
ðð ð ð Ø ðñ ô ˆHð ð DØSÐS¸8×;PÒ;PÑ;RÔ;RÐSÑSÔS�
Ø×'Ò'Õ.BÐ'ÑCÔC�Ø ð :ð :�Ý,¨S°*¸dÑCÔC�Øð :Ø”J×%Ò%¥e¨D°%Ñ&8Ô&8Ñ9Ô9Ð9øØð 	(ð  ˆNØ”zð Fð F�Ø×%Ò%Õ&9¸$ÀÑ&DÔ&DÑEÔEÐEÐEØ'ˆCŒJØÐð œð 4ð 4�Ø %× 1Ò 1Ñ 3Ô 3�”�øøÝð ð ð ÝŒÐ=ÅÀAÁÄÑFÑGÔGÐGØˆtˆtˆtàð 	ðØÐ.Ð.øÝð ð ð Ø�ðøøøåŒ×-Ò-¨iÑ8Ô8Ð8ØÐÝ& t¨X°wÀÑMÔMˆDÝŒ×,Ò,Ð-AÑBÔBÐBÐBÐBøøøøðøøøð ð 	ðØÐ.Ð.øÝð ð ð Ø�ðøøøåŒ×-Ò-¨iÑ8Ô8Ð8ØÐÝ& t¨X°wÀÑMÔMˆDÝŒ×,Ò,Ð-AÑBÔBÐBÐBøð ð 	ðØÐ.Ð.øÝð ð ð Ø�ðøøøåŒ×-Ò-¨iÑ8Ô8Ð8ØÐÝ& t¨X°wÀÑMÔMˆDÝŒ×,Ò,Ð-AÑBÔBÐBÐBøøøõ
 •‰KŒK€EØ”ð ð ˆØ!ˆŒØˆŒˆØ€Js¥   ÃC ÃC'Ã&C'Å?B&O0 È(H+È+
H8È7H8ÊE!O0 Ï/S= Ï0
RÏ:$RÐS= Ð%P( Ð(
P5Ð4P5ÒRÒS= ÒR Ò
R'Ò&R'Ó=U'ÔTÔU'Ô
TÔU'ÔTÔAU')Fr�  )NNr$   r˜  )r$   r$   r;   )NNNNN)–r`   Úinspectr‹  r^  r  Úcollections.abcr   Úcontextvarsr   Údataclassesr   Úoperatorr   r‹  r'   r   Úpymupdf._table_refiner   r	   r
   r   r   Úpymupdf._table_spansr   r   r   r   r   Úpymupdf._table_headersr   r   r   r   r   r   rm  rl  r7   r9   r‘  rw   ÚFZ_STEXT_BOLDrÒ   ÚFZ_STEXT_STRIKEOUTrÑ   rS  ÚTEXT_COLLECT_STYLESÚTEXT_MEDIABOX_CLIPre   rg   rf   ÚTEXT_SEGMENTÚTEXT_COLLECT_VECTORSrs  rB   Ú
whitespacerÐ   rl   rx   r„   rN   rŒ   r”   r¿   ræ   r2  rè   rq  rr  rs  r�  r‚  rƒ  r„  r™  rU  rS  rT  rQ  r5  r  r
  r  r%  rW  r˜  r<  rR  Ú
parametersr§  r¤  r£  r¨  r  rº  rÀ  rÎ  rÕ  rß  ré  rî  rü  r  r/   r  r8  r  r-  r3  r7  r=  rE  rH  rL  rO  r  r#  r]  ro  rƒ  rŒ  rŽ  r©  rÄ  rÆ  rÊ  rÌ  rÙ  Úobjectrß  rÛ  rf  r‡  r¼  r¿  rÁ  rò  r  r  r  r  r  r!  r'  r+  r/  rB  rH  rU  r}  ra   r-   r+   ú<module>r�     s  ððHð HðT €€€Ø Ð Ð Ð Ø €€€Ø €€€Ø $Ð $Ð $Ð $Ð $Ð $Ø "Ð "Ð "Ð "Ð "Ð "Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð .Ð -Ð -Ð -Ð -Ð -ð ˆZÐ-°tÐ<Ñ<Ô<€
ØˆZÐ-°tÐ<Ñ<Ô<€
ð ).ð #ð #ð #ð #ð #ðL#"ð #"ð #"ð #"ð #"ñ #"ô #"ð #"ðL 	ˆ˜
Ñ#Ô#€Øˆ˜
Ñ#Ô#€ØÔ€	ØÔ)€ð ØÔñàÔ!ñ"ð Ô ñ!ð ðð ð ð ØÔ"ñ#àÔñð Ô"ñ#ð Ô ñ	!ð ð ˆs�6Ô$Ñ%Ô%€ðð ð ð	ð 	ð 	ð	9ð 	9ð 	9ðM¨tð Mð Mð Mð Mðð ð ð8ð 8ð 8ðveð eð eð eðZ	ð 	ð 	ð 	ð 	�ñ 	ô 	ð 	ðð ð Ð ð  AÐ@Ð@Ð Øˆ
�1‰Œ€ØÐ ØÐ ØÐ Ø Ð ØÐ ØÐ ØÐ ØÐ Øˆj˜˜u d¨HÑ5Ô5€ð ØØØØØØðð €	ð	 ˜4ð 	 ð 	 ð 	 ð 	 ð#ð #ð #ð #ð #ñ #ô #ð #ðL^!ð ^!ð ^!ð ^!ð ^!ñ ^!ô ^!ð ^!ðBTð Tð Tð Tð Tñ Tô Tð Tðn8˜ð 8¨Dð 8ð 8ð 8ð 8ð #�Ô" 7Ô#5Ñ6Ô6ÔA×FÒFÑHÔH€Ø)˜Ô)¨-Ñ8Ô8ÔC×HÒHÑJÔJÐ ð˜Dð ¨wð ð ð ð ð˜ð ¨3ð ð ð ð ðF "ðð Øðð 	ðð ð ð ð,ð ,˜ð ,¨dð ,ð ,ð ,ð ,ð.ð ð ð%&˜4ð %&ð %&ð %&ð %&ðP˜Tð ð ð ð ð$H˜ð Hð Hð Hð Hð ØØð	%ð %ð
 
ð%ð %ð %ð %ð$ð  Tð ð ð ð ð(1¨Dð 1ð 1ð 1ð 1ð5¨dð 5ð 5ð 5ð 5ð @˜3ð @ð @ð @ð @ð,	4˜Sð 	4°ð 	4ð 	4ð 	4ð 	4ð 'Ø&ð!ð !ð !ð !ð$@˜Cð @ð @ð @ð @ð6 8Nð ð ¨ð ð ð ð ð6ð ð ðBM˜$ð Mð Mð Mð Mð2 ð 2ð 2ð 2ð 2ð5ð 5ð 5ð3ð 3ð 3ð 3Oð &ð &¨Cð &ð &ð &ð &ðRð ð ð 3Mð :ð :¨Cð :ð :ð :ð :ðzð À4ð ð ð ð ð2ð ð ð;(ð ;(ð ;(ð|_ Dð _ð _ð _ð _ðD
ð 
ð 
ð 
ð 
ñ 
ô 
ð 
ð	ð 	ð 	ð 	ð 	ˆyñ 	ô 	ð 	ðð ð ð ð ñ ô ð ðð ð ð  �‘”€ðUHð UHð UHð UHð UHñ UHô UHð UHðp ðYEð YEð YEð YEð YEñ YEô YEñ „ðYEðxFð Fð Fð Fð Fñ Fô Fð FðRð*:ð :ð :ð :ðDð ð ð
Yð 
Yð 
Yðj2ð j2ð j2ð j2ðZ	)%ð )%ð )%ðX
ð 
ð 
ð*ð ð ð"ð ð ðB CHÐZ^ð 
?ð 
?ð 
?ð 
?ð 
?ðKð Kð Kð
ð ð ðUð Uð Uð&-ð -ð -ð:ð :ð :ðzð ð ð 1ð 1ð 1ðl 
Ø$Ø&ØØ!Ø2Ø"Ø"Ø2Ø"Ø"ØØ :Ø">Ø$%Ø&*Ø&*ØØØØØØØ
ØØØØð;`ð `ð ð`ð ð	`ð
 ð`ð ð`ð ð`ð ð`ð ð`ð ð`ð ð`ð ð`ð ð`ð ð`ð  ð`ð  "ð!`ð" $ð#`ð$ $ð%`ð4 ð5`ð6 ð7`ð8 ð9`ð `ð `ð `ð `ð `r-   