ó
    uÕgj"  ã                  óL  • S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	J
r
JrJr  SSKJrJrJrJr  SSKJr  SSKJr  SS	KJrJrJrJrJr  SS
KJrJrJr  SSK J!r!J"r"  SSK#J$r$J%r%J&r&  SSK'J(r(  Sr) S           SS jjr*        SS jr+            SS jr,SS jr-g)u  Settle what a figure leaves on the page once the scan has read the figure.

Two answers come back from one look at the page: the text around the figure that
is only its furniture, which is removed, and the footnote markers its labels
carry, which are recorded on the picture.

The parse lifts what it can off a picture and files the fragments as text. Where
it files them under the picture, the graft removes them with the picture's
children. Where it files them under the page body instead â€” which it does
page to page with no pattern â€” they survive, and the document then holds a
chart's axis printed as forty separate records beside the reading that
supersedes them. Indexed for retrieval, each one carries the chart's heading, so
a gridline labelled 3.50 becomes a chunk that answers a question about the
weighted average risk rating with a number off the ruler.

The candidates are the plain text items overlapping a figure the scan read. That
is a bound on what can be removed rather than a decision about it: a heading, a
caption, a footnote or a page mark is never a candidate, whatever it overlaps,
and neither is a page the scan returned no figure for.

Deciding among the candidates is left to the agent, which is shown the page.
Nothing here inspects the text.

The markers are asked for on every page the scan returned a figure on, whether or
not that page has candidate text. A chart printing "(1,2)" on its title leaves
nothing behind to sweep, and it still carries a qualification the description
alone does not state.
é    )ÚannotationsN)ÚPath)ÚDictÚListÚOptionalÚSequenceÚTuple)ÚDoclingDocumentÚPictureItemÚPictureMetaÚTextItem)ÚDocItemLabel)Úlogger)ÚFigureÚFigureCorrectorÚFragmentÚMarkerÚNote)ÚNormBoxÚnorm_boxÚprov_box)ÚFOOTNOTE_MARKS_FIELDÚFOOTNOTES_FIELD)ÚFigureRecordÚPageScanÚRemovedText)Úrender_pageéÈ   c              ƒ  ó¤  ^^^#   • Tc  / $ U VVVs/ s HH  nUR                    Vs/ s H  owR                  (       d  M  UPM     nnU(       d  M:  XV[        XU5      4PMJ     nnnnU(       d  / $ [        R                  " SS9 m[
        R                  " UU4S jU 5       6 I Sh  v•N n	[
        R                  " U4S j[        X‰SS9 5       6 I Sh  v•N n
SSS5        / n/ n[        UW
SS9 GH  u  u  pVpÞUR                  UR                  S5      u  nn[        XUR                  UR                  UR                  5        UR                   Vs/ s H  nUUR                     UR                  4PM      nnU(       a5  [         R"                  " S	UR                  [%        U5      [%        U5      5        U HQ  u  nnUR'                  U5        UR'                  [)        UR                  UR                  [+        UUU5      US
95        MS     GM     U(       d  / $ U R-                  US9  U$ s  snf s  snnnf  GN� GNf! , (       d  f       GNk= fs  snf 7f)až  Sweep each page's figure furniture from `document` and record its markers.

Each removal is returned with its text and its box, because a completeness
check reading the source PDF cannot otherwise tell this from a silent loss:
both leave printed text the document does not hold.

Mutates `document` in place. Does nothing when the sweep is switched off, when
no page carries a figure, or when a page's call fails.
Nzquber-correction-)Úprefixc              3  ó¸   >#   • U  HO  u  pn[         R                  " [        TUR                  [        [        T5      S UR                  S S3-  5      v •  MQ     g7f)zpage-Ú04dz.pngN)ÚasyncioÚ	to_threadr   ÚpageÚCORRECTION_DPIr   )Ú.0ÚscanÚ_fÚ_cÚsourceÚtmps       €€Ú8/home/mande/repo/quber/src/quber/core/figures/correct.pyÚ	<genexpr>Ú"correct_figures.<locals>.<genexpr>R   s^   øé € ð ò %)‘L�D˜bô ×!Ò!Ü ¨¯©´NÄDÈÃIÐRWÐX\×XaÑXaÐbeÐWfÐfjÐPkÑDk÷ð ò %)ùs   ƒAAc              3  ó^  >#   • U  H–  u  u  pnu  pEnT
R                  [        U5      R                  5       [        U5       VVs/ s H  u  px[	        XxR
                  S 9PM     snn[        U5       VV	s/ s H  u  py[        XyR
                  S9PM     sn	n5      v •  M˜     gs  snnf s  sn	nf 7f))ÚindexÚdescription)r1   ÚtextN)Úcorrect_figurer   Ú
read_bytesÚ	enumerater   r3   r   )r'   Ú_scanÚfiguresÚeligibleÚimageÚ_wÚ_hÚiÚfÚitemÚfinders             €r-   r.   r/   Z   s    øé € ð ò DdÑ?Ñ.�U X±°¸Bð ×%Ñ%Ü˜“K×*Ñ*Ó,ÜENÈwÔEWÔXÒEW¹T¸Q”V !·±Ô8ÑEWÒXÜFOÐPXÔFYÔZÒFY¹7¸1”X A¯I©IÔ6ÑFYÒZ÷ð ò
 Ddùó YùÛZùs   ƒA B-ÁB!Á"B-Á3B'ÂB-T)Ústrict©g      ƒ@g     Àˆ@zXFigure correction: page {} removing {} of {} fragment(s) the scan's figures already read)r%   r3   ÚboxÚreason)Ú
node_items)r8   r3   Ú
candidatesÚtempfileÚTemporaryDirectoryr#   ÚgatherÚzipÚgetr%   Ú_record_markersÚmarkersÚnotesÚ	furniturer1   rD   r   ÚinfoÚlenÚappendr   r   Údelete_items)ÚdocumentÚscansÚ	page_dimsr+   r@   r(   r8   ÚfigureÚworkÚrenderedÚverdictsÚdoomedÚremovedr9   Ú
correctionÚwidthÚheightr>   Úmarkedr?   rD   r,   s      ``                @r-   Úcorrect_figuresra   4   s  úé € ð  �~Øˆ	ñ õâˆDØ.2¯lªlÓJªl F¿k½kŸ©lˆGÐJÜó 	?ˆœ
 8°9Ó=Ó>Ùð 	ò ö Øˆ	ä	×	$Ò	$Ð,?Ò	@ÀCÜ Ÿšõñ %)ó	ð
÷ 
ˆô !Ÿšôô DGÀtÐ^bÒCcóð	
÷ 	
ˆ÷ 
Að( €FØ!#€GÜ14°T¸8ÈDÕ1QÑ-Ñ!ˆ˜Ø!Ÿ™ d§i¡i°Ó@‰ˆˆvÜ˜¨:×+=Ñ+=¸z×?OÑ?OÐQU×QZÑQZÔ[Ø9C×9MÒ9MÓNÒ9M°A�8˜AŸG™GÑ$ a§h¡hÓ/Ñ9MˆÐNÞÜ�KŠKØjØ—	‘	Ü�F“Ü�H“ô	ó #‰LˆD�&Ø�M‰M˜$ÔØ�N‰NÜØŸ™ØŸ™Ü   u¨fÓ5Ø!ñ	öô #ñ 2Rö, Øˆ	ð ×Ñ VÐÑ,Ø€Nùòo Kùôò
ò	
÷ 
AÖ	@üò2 Oùs|   …I‘H,¥H'½H'ÁH,ÁH,Á !IÂ"H9Â#H3Â$,H9ÃH6ÃH9ÃA9IÅ%IÅ3B4IÈ'H,È,IÈ3H9È6H9È9
IÉIc                óâ  ^• S UR                    5        Vs/ s H	  o3c  M  UPM     nnU(       d  / $ UR                  UR                  S5      u  pV/ nU R                   GH  nUR                  [
        R                  :w  d(  UR                  =(       d    SR                  5       (       d  ML  UR                  (       a'  UR                  S   R                  UR                  :w  a  M†  [        UR                  (       a  UR                  R                  U 5      OS[        5      (       a  MÉ  [        X…U5      mTc  MÚ  [!        U4S jU 5       5      (       d  Mö  UR#                  U5        GM
     U$ s  snf )zHThe plain text items on `scan`'s page that overlap a figure it returned.c              3  óL   #   • U  H  n[        UR                  5      v •  M     g 7f©N)r   rC   )r'   Úcharts     r-   r.   Úcandidates.<locals>.<genexpr>ˆ   s   é € ÐKºl°UœX e§i¡i×0Ð0ºlùs   ‚"$NrB   Ú r   c              3  ó<   >#   • U  H  n[        UT5      v •  M     g 7frd   )Ú	_overlaps)r'   rW   rC   s     €r-   r.   rf   —   s   øé € Ð"NÊ¸f¤9¨V°S×#9Ð#9Êùs   ƒ)r8   rK   r%   ÚtextsÚlabelr   ÚTEXTr3   ÚstripÚprovÚpage_noÚ
isinstanceÚparentÚresolver   r   ÚanyrR   )	rT   r(   rV   rC   Úboxesr^   r_   Úfoundr?   s	      `     r-   rF   rF   „   s  ø€ ñ L¸d¿lºlÔKÓ_ÒK�S�SÑK€EÐ_ÞØˆ	Ø—M‘M $§)¡)¨^Ó<�M€EØ€EØ—•ˆØ�:‰:œ×*Ñ*Ó*°4·9±9·?À×2IÑ2I×2KÑ2KÙØ�y�y˜DŸI™I a™L×0Ñ0°D·I±IÓ=Ùô °t·{·{�d—k‘k×)Ñ)¨(Ô3ÈÌk×ZÑZÙÜ�t FÓ+ˆØ‹?œsÔ"NÉÓ"N×NÓNØ�L‰L˜×ñ ð €Lùò# `s
   —E,¡E,c                óÒ  • U(       d  U(       d  gU R                    Vs0 s H  oUR                  U_M     nn[        U5       GH‰  u  pxU V	s/ s H  o™R                  U:X  d  M  U	PM     n
n	U Vs/ s H  o»R                  U:X  d  M  UPM     nnU
(       d	  U(       d  M\  UR	                  UR
                  =(       d    S5      nUc$  [        R                  " SUU[        U
5      5        M§  UR                  =(       d
    [        5       nUR                  [        U
 V	s/ s H&  o™R                  U	R                  U	R                  S.PM(     sn	[         U Vs/ s H  o»R                  UR"                  S.PM     sn0S9Ul	        [        R$                  " SUUR                  SR'                  S	 U
 5       5      =(       d    S
[        U5      5        GMŒ     gs  snf s  sn	f s  snf s  sn	f s  snf )zúWrite each figure's markers and printed notes onto its picture.

A figure the graft never placed has no picture to carry them. The run already
reports that figure as unplaced, so the markers are logged and dropped rather
than reported a second time.
Nrg   zMFigure markers: page {} figure {} carries {} marker(s) and sits on no picture)ÚmarkerÚkindrk   )rw   r3   )ÚupdatezOFigure markers: page {} picture {} carries {} with {} note(s) read off the pagez, c              3  óX   #   • U  H   oR                    S UR                   S3v •  M"     g7f)z (Ú)N)rw   rx   )r'   Úms     r-   r.   Ú"_record_markers.<locals>.<genexpr>Å   s#   é € Ð=º°1Ÿ™˜
 " Q§V¡V H¨AÕ.ºùs   ‚(*z
no markers)ÚpicturesÚself_refr6   rW   rK   Úpicture_refr   ÚwarningrQ   Úmetar   Ú
model_copyr   rw   rx   rk   r   r3   rP   Újoin)rT   r8   rM   rN   r%   ÚpictureÚby_refr1   rW   r|   ÚmineÚnÚreadÚbases                 r-   rL   rL   œ   s‹  € ö ž5ØØ7?×7HÒ7HÓIÒ7H¨G×Ñ Ò'Ñ7H€FÐIÜ" 7×+‰ˆÙ"Ó8š7�a§h¡h°%Ñ&7—™7ˆÐ8Ù Ó6š5�a§H¡H°Ñ$5—™5ˆÐ6ÞžDÙØ—*‘*˜V×/Ñ/×5°2Ó6ˆØ‰?Ü�NŠNØ_ØØÜ�D“	ô	ñ Ø�|‰|×,œ{›}ˆØ—‘ä$ÑgkÓ&lÒgkÐbc·(±(ÀAÇFÁFÐUV×U\ÑU\Ô']ÑgkÑ&lÜÑPTÓ!UÒPTÈ1¯X©X¸q¿v¹vÔ"FÑPTÑ!Uðð 'ð 
ˆŒô 	�ŠØ]ØØ×ÑØ�I‰IÑ=¹Ó=Ó=×MÀÜ�‹I÷	
ò+ ,ùò Jùâ8ùÚ6ùò 'mùÚ!Us)   žGÁGÁ"GÁ.GÂGÄ-GÅ"G$c                ó¸   • [        U S   US   5      [        U S   US   5      -
  n[        U S   US   5      [        U S   US   5      -
  nUS:„  =(       a    US:„  $ )aE  Do the two boxes share any area at all?

Any overlap, with no fraction to tune. Measured on three decks: every text
item on a scanned page either sits well inside a figure or misses it
entirely, and not one landed in between, so a threshold decided nothing and
only added a constant fitted to whichever deck it was read off.
é   r   é   é   )ÚminÚmax)rW   r3   ÚwideÚtalls       r-   ri   ri   Ê   sg   € ô ˆv�a‰y˜$˜q™'Ó"¤S¨°©°D¸±GÓ%<Ñ<€DÜˆv�a‰y˜$˜q™'Ó"¤S¨°©°D¸±GÓ%<Ñ<€DØ�!‰8× ˜˜q™Ð ó    rd   )rT   r
   rU   zSequence[PageScan]rV   úDict[int, Tuple[float, float]]r+   r   r@   zOptional[FigureCorrector]ÚreturnzList[RemovedText])rT   r
   r(   r   rV   r”   r•   zList[TextItem])rT   r
   r8   zSequence[FigureRecord]rM   zSequence[Marker]rN   zSequence[Note]r%   Úintr•   ÚNone)rW   r   r3   r   r•   Úbool).Ú__doc__Ú
__future__r   r#   rG   Úpathlibr   Útypingr   r   r   r   r	   Údocling_core.types.doc.documentr
   r   r   r   Údocling_core.types.doc.labelsr   Úlogurur   Úquber.agents.figure_correctionr   r   r   r   r   Úquber.core.figures.geometryr   r   r   Úquber.core.figures.graftr   r   Úquber.core.figures.modelsr   r   r   Úquber.files.pdfr   r&   ra   rF   rL   ri   © r“   r-   Ú<module>r¦      sû   ðñõ: #ã Û Ý ß 8Õ 8ç _Ó _Ý 6Ý ç ZÕ Zß CÑ Cß Jß IÑ IÝ 'ð €ð )-ðMØðMàðMð .ðMð ð	Mð
 &ðMð õMð`ØðØ%-ðØ:Xðàôð0+
Øð+
à#ð+
ð ð+
ð ð	+
ð
 ð+
ð 
ô+
õ\
!r“   