§
    �Øj	H  ã                   ó,  — d Z ddlZddlmZmZmZmZ ej                             d¦  «         ddddddddœd„Z	e
d	k    �rT	 ddlZej        d
         Zej        d         Z eej        ¦  «        dk    r eej        d         ¦  «        ZndZ eej        ¦  «        dk    r eej        d         ¦  «        ZndZ ej        e¦  «        ZeD ]�Z e	eee¬¦  «        Ze                     ¦   «         Z ee¦  «        D ]C\  ZZe                     e¦  «         e                     ej        dz    e e¦  «        e¬¦  «         ŒDe !                    e¬¦  «         e "                    ¦   «          Œže #                    e $                    dd¦  «        ¦  «         dS dS )aÊ  
This is an advanced PyMuPDF utility for detecting multi-column pages.
It can be used in a shell script, or its main function can be imported and
invoked as descript below.

Features
---------
- Identify text belonging to (a variable number of) columns on the page.
- Text with different background color is handled separately, allowing for
  easier treatment of side remarks, comment boxes, etc.
- Uses text block detection capability to identify text blocks and
  uses the block bboxes as primary structuring principle.
- Supports ignoring footers via a footer margin parameter.
- Returns re-created text boundary boxes (integer coordinates), sorted ascending
  by the top, then by the left coordinates.

Restrictions
-------------
- Only supporting horizontal, left-to-right text
- Returns a list of text boundary boxes - not the text itself. The caller is
  expected to extract text from within the returned boxes.
- Text written above images is ignored altogether (option).
- This utility works as expected in most cases. The following situation cannot
  be handled correctly:
    * overlapping (non-disjoint) text blocks
    * image captions are not recognized and are handled like normal text

Usage
------
- As a CLI shell command use

  python multi_column.py input.pdf footer_margin header_margin

  Where margins are the height of the bottom / top stripes to ignore on each
  page.
  This code is intended to be modified according to your need.

- Use in a Python script as follows:

  ----------------------------------------------------------------------------------
  from multi_column import column_boxes

  # for each page execute
  bboxes = column_boxes(page, footer_margin=50, no_image_text=True)

  bboxes is a list of pymupdf.IRect objects, that are sorted ascending by their
  y0, then x0 coordinates. Their text content can be extracted by all PyMuPDF
  get_text() variants, like for instance the following:
  for rect in bboxes:
      print(page.get_text(clip=rect, sort=True))
  ----------------------------------------------------------------------------------

Dependencies
-------------
PyMuPDF v1.24.2 or later

Copyright and License
----------------------
Copyright 2024 Artifex Software, Inc.
License GNU Affero GPL 3.0
é    N)ÚWHITE_CHARSÚare_disjointÚintersect_rectsÚbbox_is_emptyTé2   F)Úfooter_marginÚheader_marginÚno_image_textÚtextpageÚpathsÚavoidÚignore_imagesc                óf  ‡&‡'‡(‡)‡*— d„ }d„ Š'd„ Š(d„ Š)ˆ)fd„}	d„ }
d„ }d„ }ˆ(fd	„}| j         
 Š&‰&xj        |z  c_        ‰&xj        |z  c_        |€ ˆ&fd„|                      ¦   «         D ¦   «         }|€!|                      ‰&t
          j        ¬¦  «        }g }g }|�|                     |¦  «         g }g Š*|D ]†}|d         }|d         x}€dn|dz  }|j        dk    r |xj	        |z  c_	        |xj
        |z  c_
        |j        dk    r |xj        |z  c_        |xj        |z  c_        ‰*                     |¦  «         Œ‡‰*                     d„ ¬¦  «         |du rE|                      ¦   «         D ]0}|                     |                      |d         ¦  «        ¦  «         Œ1|                     ¦   «         d         }|D �]}t          j        |d         ¦  «        }|r ‰'||¦  «        rŒ,	 |d         d         }n# t$          $ r Y ŒHw xY wt'          d|d         d         z
  ¦  «        dk    r|                     |¦  «         Œ„t          j        ¦   «         }|d         D ]Q}t          j        |d         ¦  «        }d                     d„ |d         D ¦   «         ¦  «        } ||¦  «        s||z  }ŒR|
 }|j        s|                     |¦  «         �Œ|                     ˆ'ˆ*fd„¬¦  «         |g k    rg S |d         g}|dd
…         }i }t/          |¦  «        D ]ê\  } }!d}"t1          t3          |¦  «        ¦  «        D ]c}#||#         }$|!� |$j
        |!j	        k     s|!j
        |$j	        k     rŒ- ‰(|$‰*|¦  «         ‰(|!‰*|¦  «        k    rŒJ|!|$z  }% |	|%|$||¦  «        }"|"du r nŒd|"s/|                     |!¦  «         t3          |¦  «        dz
  }#||#         }% |	|%|!||¦  «        }"|"du r|                     |!¦  «         n|%||#<   d
|| <   Œë |
|¦  «        }t3          |¦  «        dk    r|S  ||¦  «        } ||‰*|¦  «        }|S )a¥  Determine bboxes which wrap a column on the page.

    Args:
        footer_margin: ignore text if distance from bottom is less
        header_margin: ignore text if distance from top is less
        no_image_text: ignore text inside image bboxes
        textpage: use this textpage instead of creating one
        paths: use these drawings instead of extracting here
        avoid: ignore text in any of these areas
    c                 ó*   — t          j        | ¦  «        S )zCheck for relevant text.)r   Ú
issuperset©Útexts    ú•/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/pymupdf4llm/helpers/multi_column.pyÚis_whitezcolumn_boxes.<locals>.is_white`   s   € åÔ% dÑ+Ô+Ð+ó    c                 óD   — t          |d¬¦  «        D ]\  }}| |v r|c S ŒdS )ú;Return 1-based number if a bbox contains bb, else return 0.é   ©Ústartr   )Ú	enumerate)ÚbbÚbboxesÚiÚbboxs       r   Úin_bboxzcolumn_boxes.<locals>.in_bboxd   s>   € å  ¨qÐ1Ñ1Ô1ð 	ð 	‰GˆAˆtØ�TˆzˆzØ���ð àˆqr   c                 óÈ   — 	 t          | ¦  «        › dt          |¦  «        › �}|                     |¦  «        }|�|S d}t          |d¬¦  «        D ]\  }}| |v r|} nŒ|||<   |S )r   Ú_Nr   r   r   )ÚidÚgetr   )r   r   ÚcacheÚ	cache_keyÚcachedÚindexr   r    s           r   Úin_bbox_using_cachez)column_boxes.<locals>.in_bbox_using_cachek   sŽ   € à:Ý˜"‘v”vÐ,Ð,¥ 6¡
¤
Ð,Ð,ˆ	Ø—’˜9Ñ%Ô%ˆØÐØˆMàˆÝ  ¨qÐ1Ñ1Ô1ð 	ð 	‰GˆAˆtØ�TˆzˆzØ�Ø�ð ð !ˆˆiÑØˆr   c                 ó:   ‡ — t          ˆ fd„|D ¦   «         ¦  «        S )z4Return True if a bbox touches bb, else return False.c              3   ó>   •K  — | ]}t          ‰|d ¬¦  «         V — ŒdS )T)ÚstrictN)r   )Ú.0r    r   s     €r   ú	<genexpr>z:column_boxes.<locals>.intersects_bboxes.<locals>.<genexpr>~   s5   øè è € ÐNÐN¸t•| B¨°TÐ:Ñ:Ô:Ð:ÐNÐNÐNÐNÐNÐNr   )Úany)r   r   s   ` r   Úintersects_bboxesz'column_boxes.<locals>.intersects_bboxes|   s&   ø€ åÐNÐNÐNÐNÀvÐNÑNÔNÑNÔNÐNr   c                 ó~   •— |D ]8} ‰| |¦  «        s(|�%||k    st          t          | |d¬¦  «        ¦  «        rŒ6 dS dS )aG  Determines whether rectangle 'temp' can be extended by 'bb'
        without intersecting any of the rectangles contained in 'bboxlist'
        or 'vert_bboxes'.

        Items of bboxlist may be None if they have been removed.

        Returns:
            True if 'temp' has no intersections with items of 'bboxlist'.
        NT)Ú	bbox_onlyF)r   r   )Útempr   ÚbboxlistÚvert_bboxesÚbr1   s        €r   Ú
can_extendz column_boxes.<locals>.can_extend€   sg   ø€ ð ð 	ð 	ˆAØ$Ð$ T¨;Ñ7Ô7ð Ø�	Ø˜’7�7Ý ¥°°qÀDÐ!IÑ!IÔ!IÑJÔJð ð Ø�5�5àˆtr   c                 ó2  — t          | ¦  «        }|dk     r| S |dz
  }t          |dd¦  «        D ]}| |         }| |dz
           }||k    r| |= Œt          | ¦  «        dk    r| S | d         j        }d}d}t          dt          | ¦  «        ¦  «        D ][}| |         }	t          |	j        |z
  ¦  «        dk    r4||k    r%t	          | ||dz   …         d„ ¬¦  «        | ||dz   …<   |	j        }|}|}Œ\||k    r%t	          | ||dz   …         d„ ¬¦  «        | ||dz   …<   | S )	zDo some elementary cleaning.é   r   éÿÿÿÿr   é   c                 ó   — | j         S ©N©Úx0©r7   s    r   ú<lambda>z5column_boxes.<locals>.clean_nblocks.<locals>.<lambda>´   s   € ¸A¼D€ r   ©Úkeyc                 ó   — | j         S r>   r?   rA   s    r   rB   z5column_boxes.<locals>.clean_nblocks.<locals>.<lambda>º   s   € ÈaÌd€ r   )ÚlenÚrangeÚy1ÚabsÚsorted)
ÚnblocksÚblenr   r   Úbb1Úbb0rH   Úi0Úi1Úb1s
             r   Úclean_nblocksz#column_boxes.<locals>.clean_nblocks•   se  € õ �7‰|Œ|ˆØ�!Š8ˆ8ØˆNØ�q‘ˆÝ�u˜b "Ñ%Ô%ð 	ð 	ˆAØ˜!”*ˆCØ˜!˜a™%”.ˆCØ�cŠzˆzØ˜A�Jøåˆw‰<Œ<˜1ÒÐØˆNð
 �QŒZŒ]ˆØˆØˆõ �q�#˜g™,œ,Ñ'Ô'ð 		ð 		ˆAØ˜”ˆBÝ�2”5˜2‘:‰Œ Ò"Ð"Ø˜’7�7Ý+1Ø  R¨!¡V Ô,°.°.ð,ñ ,ô ,�G˜B  a¡˜KÑ(ð ”U�Ø�ØˆBˆBØ�Š7ˆ7Ý#)¨'°"°r¸A±v°+Ô*>ÀNÀNÐ#SÑ#SÔ#SˆG�B˜˜a™�KÑ Øˆr   c                 ó  — d}| dd…         }g }|rq|d         }d}|rKd}t          t          |¦  «        dz
  dd¦  «        D ]%}||z   ||         z  j        r|||         z  }||= d}Œ&|°K|                     |¦  «         |d= |°q|S )zñPostprocess identified text blocks, phase 1.

        Joins any rectangles that "touch" each other.
        This means that their intersection is valid (but may be empty).
        To prefer vertical joins, we will ignore small gaps.
        )r   r   r   é
   Nr   TFr   r;   )rG   rF   Úis_validÚappend)r   ÚdeltaÚprectsÚ	new_rectsÚprect0Úrepeatr   s          r   Újoin_rects_phase1z'column_boxes.<locals>.join_rects_phase1½   sÏ   € ð ˆØ˜˜˜”ˆØˆ	Øð 	Ø˜A”YˆFØˆFØð &Ø�Ý�s 6™{œ{¨Q™°°2Ñ6Ô6ð &ð &�AØ %™¨6°!¬9Ñ4Ô>ð &Ø &¨¤)Ñ+˜Ø" 1˜IØ!%˜øð ð &ð ×Ò˜VÑ$Ô$Ð$Ø�q�	ð ð 	ð Ðr   c                 óf  ‡— | dd…         }t          t          |¦  «        ¦  «        D ]S}||         Št          ˆfd„|D ¦   «         ¦  «        }t          ˆfd„|D ¦   «         ¦  «        }|‰_        |‰_        ‰||<   ŒT|                     d„ ¬¦  «         |d         g}|dd…         D ]Š}|d         }t          |j        |j        z
  ¦  «        d	k    rKt          |j        |j        z
  ¦  «        d	k    r+t          |j        |j	        z
  ¦  «        d
k    r||z  }||d<   Œu| 
                    |¦  «         Œ‹|S )zÜPostprocess identified text blocks, phase 2.

        Increase the width of each text block so that small left or right
        border differences are removed. Then try to join even more text
        rectangles.
        Nc                 ó^   •— g | ])}t          |j        ‰j        z
  ¦  «        d k    ¯"|j        ‘Œ*S ©r<   )rI   r@   ©r.   r   r7   s     €r   ú
<listcomp>z;column_boxes.<locals>.join_rects_phase2.<locals>.<listcomp>à   ó5   ø€ ÐGÐGÐG µ°B´E¸A¼D±LÑ0AÔ0AÀQÒ0FÐ0F�b”eÐ0FÐ0FÐ0Fr   c                 ó^   •— g | ])}t          |j        ‰j        z
  ¦  «        d k    ¯"|j        ‘Œ*S r_   )rI   Úx1r`   s     €r   ra   z;column_boxes.<locals>.join_rects_phase2.<locals>.<listcomp>á   rb   r   c                 ó   — | j         | j        fS r>   )r@   Úy0rA   s    r   rB   z9column_boxes.<locals>.join_rects_phase2.<locals>.<lambda>ç   ó   €  1¤4¨¬ ,€ r   rC   r   r   r;   r<   rT   )rG   rF   ÚminÚmaxr@   rd   ÚsortrI   rH   rf   rV   )	r   rX   r   r@   rd   rY   ÚrÚr0r7   s	           @r   Újoin_rects_phase2z'column_boxes.<locals>.join_rects_phase2Õ   sa  ø€ ð ˜˜˜”ˆÝ•s˜6‘{”{Ñ#Ô#ð 	ð 	ˆAØ�q”	ˆAåÐGÐGÐGÐG fÐGÑGÔGÑHÔHˆBÝÐGÐGÐGÐG fÐGÑGÔGÑHÔHˆBØˆAŒDØˆAŒDØˆF�1‰IˆIð 	�ŠÐ.Ð.ˆÑ/Ô/Ð/Ø˜A”Y�Kˆ	ð ˜˜˜”ð 	 ð 	 ˆAØ˜2”ˆBõ �A”D˜2œ5‘LÑ!Ô! QÒ&Ð&Ý˜œ˜rœu™Ñ%Ô%¨Ò*Ð*Ý˜œ ¤™Ñ%Ô%¨Ò+Ð+à�a‘�Ø "�	˜"‘Øà×Ò˜QÑÔÐÐØÐr   c                 ó&  •‡‡— | d d …         }g }|rõ|d         }d}|rÏd}t          t          |¦  «        dz
  dd¦  «        D ]©}||         }|j        |j        k    s|j        |j        k     rŒ+ ‰|||¦  «         ‰|||¦  «        k    rŒH||z  Št	          ˆfd„||z   D ¦   «         ¦  «        }	|	t	          t          |¦  «        t          |¦  «        f¦  «        k    r||z  }||d<   ||= d}Œª|°Ï|                     |¦  «         |d= |°õ	 g }
|D ]\Št          ˆfd„|D ¦   «         d„ ¬	¦  «        }|r|d         j        ‰j        f}n‰j        ‰j        f}|
                     ‰|f¦  «         Œ]|
 	                    d
„ ¬	¦  «         d„ |
D ¦   «         }g }||z   S )Nr   TFr   r;   c                 óX   •— g | ]&}|                      ‰¦  «        ¯t          |¦  «        ‘Œ'S © )Ú
intersectsÚtuple)r.   r7   r4   s     €r   ra   z;column_boxes.<locals>.join_rects_phase3.<locals>.<listcomp>  s0   ø€ ÐTÐTÐT aÀÇÂÈdÑASÔASÐT�˜q™œÐTÐTÐTr   c                 ó®   •— g | ]Q}|j         ‰j        k     r?‰j        |j        cxk    r‰j        k    s!n ‰j        |j        cxk    r‰j        k    ¯Ln n|‘ŒRS rp   )rd   r@   rf   rH   )r.   rk   Úboxs     €r   ra   z;column_boxes.<locals>.join_rects_phase3.<locals>.<listcomp>6  s   ø€ ð ð ð àØ”t˜cœf’}�}Øœ 1¤4Ð1Ð1Ò1Ð1¨3¬6Ò1Ð1Ð1Ð1°S´V¸q¼tÐ5MÐ5MÒ5MÐ5MÀsÄvÒ5MÐ5MÐ5MÐ5MÐ5Mð ð 6NÐ5MÐ5Mr   c                 ó   — | j         S r>   )rd   )rk   s    r   rB   z9column_boxes.<locals>.join_rects_phase3.<locals>.<lambda>=  s   € ˜aœd€ r   rC   c                 ó   — | d         S )Nr   rp   )Úsrs    r   rB   z9column_boxes.<locals>.join_rects_phase3.<locals>.<lambda>D  s
   €  r¨!¤u€ r   c                 ó   — g | ]
}|d          ‘ŒS )r   rp   )r.   rw   s     r   ra   z;column_boxes.<locals>.join_rects_phase3.<locals>.<listcomp>E  s   € Ð0Ð0Ð0˜r�R˜”UÐ0Ð0Ð0r   )
rG   rF   r@   rd   Úsetrr   rV   rJ   rf   rj   )r   Ú
path_rectsr&   rX   rY   rZ   r[   r   Úprect1ÚtestÚ
sort_rectsÚ
left_rectsrD   Úshadow_rectsrt   r4   r*   s                 @@€r   Újoin_rects_phase3z'column_boxes.<locals>.join_rects_phase3û   sT  øøø€ Ø˜˜˜”ˆØˆ	àð 	Ø˜A”YˆFØˆFØð &Ø�Ý�s 6™{œ{¨Q™°°2Ñ6Ô6ð &ð &�AØ# AœY�Fà”y 6¤9Ò,Ð,°´	¸F¼IÒ0EÐ0EØ ð +Ð*Ø 
¨Eñô à,Ð,¨V°ZÀÑGÔGòHð Hð !Ø! F™?�DÝØTÐTÐTÐT¨6°IÑ+=ÐTÑTÔTñô �Dð �s¥E¨&¡M¤Mµ5¸±=´=Ð#AÑBÔBÒBÐBØ &Ñ(˜Ø$*˜˜q™	Ø" 1˜IØ!%˜øð+ ð &ð, ×Ò˜VÑ$Ô$Ð$Ø�q�	ð5 ð 	ð8	ð* ˆ
Øð 	*ð 	*ˆCõ  ðð ð ð à&ðñ ô ð #�Nð	ñ 	ô 	ˆJð ð 'Ø! "”~Ô(¨#¬&Ð1��à”v˜sœvÐ&�Ø×Ò˜s C˜jÑ)Ô)Ð)Ð)Ø�ŠÐ,Ð,ˆÑ-Ô-Ð-Ø0Ð0 ZÐ0Ñ0Ô0ˆ	ð ˆð ˜<Ñ'Ð'r   Nc                 ól   •— g | ]0}|d          j         ‰j         k     ¯|d          j        ‰j        k     ¯.|‘Œ1S )Úrect)ÚwidthÚheight)r.   ÚpÚclips     €r   ra   z column_boxes.<locals>.<listcomp>V  sI   ø€ ð 
ð 
ð 
àØ�ŒyŒ ¤Ò+Ð+°°&´	Ô0@À4Ä;Ò0NÐ0Nð à0NÐ0NÐ0Nr   )r†   Úflagsr‚   rƒ   g      à?r   c                 ó   — | j         | j        fS r>   ©rf   r@   rA   s    r   rB   zcolumn_boxes.<locals>.<lambda>y  rg   r   rC   FÚblocksr    Úlinesr   Údirgü©ñÒMbP?Ú c                 ó   — g | ]
}|d          ‘ŒS r   rp   )r.   Úss     r   ra   z column_boxes.<locals>.<listcomp>˜  s   € Ð=Ð=Ð=¨!˜A˜fœIÐ=Ð=Ð=r   Úspansc                 ó6   •—  ‰| ‰¦  «        | j         | j        fS r>   r‰   )Úkr!   rz   s    €€r   rB   zcolumn_boxes.<locals>.<lambda>¡  s   ø€ ˜w˜w q¨*Ñ5Ô5°q´t¸Q¼TÐB€ r   T)r‚   rH   rf   Úget_drawingsÚget_textpageÚpymupdfÚTEXT_ACCURATE_BBOXESÚextendrƒ   r@   rd   r„   rV   rj   Ú
get_imagesÚget_image_rectsÚextractDICTÚRectÚ
IndexErrorrI   Ú
EMPTY_RECTÚjoinÚis_emptyr   rG   rF   )+Úpager   r	   r
   r   r   r   r   r   r8   rR   r\   rm   r€   r   Ú
img_bboxesr6   r…   Úprectr#   ÚlwidthÚitemrŠ   r7   r    Úline0ÚsrectÚlineÚlbboxr   rK   r&   r   r   ÚcheckÚjÚnbbr4   r†   r!   r*   r1   rz   s+                                         @@@@@r   Úcolumn_boxesr¬   J   sÌ  øøøøø€ ð,,ð ,ð ,ðð ð ðð ð ð"Oð Oð Oðð ð ð ð ð*&ð &ð &ðPð ð ð0$ð $ð $ðLS(ð S(ð S(ð S(ð S(ðl ŒIˆ:€DØ€G„Gˆ}Ñ€G„GØ€G„Gˆ}Ñ€G„Gà€}ð
ð 
ð 
ð 
à×&Ò&Ñ(Ô(ð
ñ 
ô 
ˆð ÐØ×$Ò$¨$µgÔ6RÐ$ÑSÔSˆà€Fð €JØÐØ×Ò˜%Ñ Ô Ð ð €Kð €JØð !ð !ˆà�&”	ˆØ œj˜˜Ð1��°q¸3±wˆàŒ;˜!ÒÐØˆHŒH˜ÑˆHŒHØˆHŒH˜ÑˆHŒHØŒ<˜1ÒÐØˆHŒH˜ÑˆHŒHØˆHŒH˜ÑˆHŒHØ×Ò˜%Ñ Ô Ð Ð ð ‡O‚OÐ.Ð.€OÑ/Ô/Ð/ð ˜ÐÐØ—O’OÑ%Ô%ð 	=ð 	=ˆDØ×Ò˜d×2Ò2°4¸´7Ñ;Ô;Ñ<Ô<Ð<Ð<ð ×!Ò!Ñ#Ô# HÔ-€Fð ð  ñ  ˆÝŒ|˜A˜fœIÑ&Ô&ˆð ð 	˜W˜W T¨:Ñ6Ô6ð 	Øð	Ø�g”J˜q”MˆEˆEøÝð 	ð 	ð 	ØˆHð	øøøõ ˆq�5˜”< ”?Ñ"Ñ#Ô# dÒ*Ð*Ø×Ò˜tÑ$Ô$Ð$ØåÔ"Ñ$Ô$ˆØ�g”Jð 	ð 	ˆDÝ”L  f¤Ñ.Ô.ˆEØ—7’7Ð=Ð=¨t°G¬}Ð=Ñ=Ô=Ñ>Ô>ˆDØ�8˜D‘>”>ð Ø˜‘�øØˆvˆàŒ}ð 	 Ø�MŠM˜$ÑÔÐùð ‡K‚KÐBÐBÐBÐBÐB€KÑCÔCÐCð �‚|€|Øˆ	ð
 �aŒyˆk€GØ�A�B�BŒZ€FØ€Eå˜6Ñ"Ô"ð !ð !‰ˆˆ2Øˆõ •s˜7‘|”|Ñ$Ô$ð 	ð 	ˆAØ˜!”*ˆCð ˆz˜SœV b¤eš^˜^¨r¬u°s´vª~¨~Øð #Ð" 3¨
°EÑ:Ô:Ð>QÐ>QØ�J ñ?ô ?ò ð ð à˜‘8ˆDØ�J˜t S¨'°;Ñ?Ô?ˆEØ˜ˆ}ˆ}Ø�ð ð ð 	Ø�NŠN˜2ÑÔÐÝ�G‘”˜qÑ ˆAØ˜1”:ˆDð �
˜4  V¨[Ñ9Ô9ˆØ�Eˆ>ˆ>Ø�NŠN˜2ÑÔÐÐàˆG�A‰JØˆˆq‰	ˆ	ð ˆm˜GÑ$Ô$€GÝ
ˆ7�|„|�qÒÐØˆð
  Ð Ñ(Ô(€GØÐ ¨°UÑ;Ô;€Gð €Ns   Ç#G2Ç2
G?Ç>G?Ú__main__Úredr   r:   r<   )r   r	   )é   é   )Úcolorz.pdfz-blocks.pdf)%Ú__doc__r•   Úpymupdf4llm.helpers.utilsr   r   r   r   ÚTOOLSÚunset_quad_correctionsr¬   Ú__name__ÚsysÚpdfcolorÚREDÚargvÚfilenamerF   Úintr   r	   ÚopenÚdocr    r   Ú	new_shapeÚshaper   r   r‚   Ú	draw_rectÚinsert_textÚtlÚstrÚfinishÚcommitÚez_saveÚreplacerp   r   r   ú<module>rÉ      sL  ðð<ð <ð| €€€ðð ð ð ð ð ð ð ð ð ð ð ð „× $Ò $ TÑ *Ô *Ð *ð ØØØØ
Ø
ØðSð Sð Sð Sð Sðl ˆzÒÑðð €J€J€Jà
Ô
˜5Ô
!€CàŒx˜Œ{€Hð €sˆ3Œ8�}„}�qÒÐØ˜˜CœH QœKÑ(Ô(ˆˆàˆð €sˆ3Œ8�}„}�qÒÐØ˜˜CœH QœKÑ(Ô(ˆˆàˆð ˆ'Œ,�xÑ
 Ô
 €Cð ð ð ˆà�Ø ¸]ð
ñ 
ô 
ˆð
 —’Ñ Ô ˆð !�y Ñ(Ô(ð 	Dð 	D‰GˆAˆtØ�OŠO˜DÑ!Ô!Ð!ð ×Ò˜dœg¨Ñ/°°°Q±´¸sÐÑCÔCÐCÐCð 	�Š˜3ˆÑÔÐØ�Š‰Œˆˆð ‡K‚K�× Ò  ¨Ñ7Ô7Ñ8Ô8Ð8Ð8Ð8ðe Ðr   