ó
    À‘´j,#  ã                  ó  • S r SSKJr  SSKJr  SSKJrJrJrJ	r	  SSK
Jr  SSKJrJrJr  SSKJr  SSKJrJr  SS	KJr  \" S
S15      r\" SS15      rSr " S S\5      r S     SS jjrSS jrSS jrSS jrSS jr g)uõ  Which pages get scanned, read off the parse.

ADE is the right reader for three things a financial document prints on a page,
and nomination is how we aim it at them.

It chooses pages, not regions. ADE locates and bounds whatever it finds on the
page it is handed, so there is nothing here to bound and no second judgement to
make. The only decision is where to send it.

The parse already reports the two picture signals, and the table signal is a
count of words in the source's text layer, so nomination makes no model call:

- A picture the parse classified as a chart. Plotted values are the whole point
  of a chart, and no component in the pipeline reads them.
- A picture the parse classified as something else with content in it â€” a
  photograph, a map, a diagram, a calendar. Also read by nothing today.
- A table with no text layer under it. Its cells hold text, so something read
  them, and the only thing that could have is the parse reading the page image.
  Such a table never reached the Set-of-Mark and Camelot engine either, because
  that engine extracts from a text layer and there was none, so what stands in
  the document is the parse's own reading with nothing having checked it since.
  `table_verdicts` measures this against the source document rather than against
  a record written earlier, so it holds however the tables have been renumbered
  since and needs no artifact beyond the two the workflow already takes.

Logos and icons are left where they are. A wordmark is printed on every page of a
deck as identity rather than content, and there is nothing inside it to read.

Every nominated page is scanned; nothing filters the list after it is built.
Nomination is a cost optimization, not a guarantee: a page whose content the
parse never classified â€” an infographic drawn entirely in the text layer â€” has
no signal here and is invisible to it. The orchestrator's `pages="all"` mode
exists for exactly those documents, scanning every page so nothing depends on
the parse having seen what matters.
é    )Úannotations)ÚPath)ÚDictÚListÚMappingÚOptional)ÚCoordOrigin)ÚDoclingDocumentÚPictureItemÚ	TableItem)Úlogger)Ú	BaseModelÚField)Ú
page_wordsÚlogoÚiconÚocrÚemptyg      à?c                  óx   • \ rS rSr% Sr\" SS9rS\S'   \" \SS9r	S	\S
'   \" \SS9r
S	\S'   \" \SS9rS	\S'   Srg)ÚNominatedPageéE   z9One page the parse says holds something nothing has read.z1-based source page)ÚdescriptionÚintÚpagez=The pictures on the page that nominated it, in document order)Údefault_factoryr   ú	List[str]Úpicture_refsz)The class the parse assigned each of themÚpicture_classeszGTables on the page the parse read off the page image, in document orderÚ
table_refs© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r   Ú__annotations__Úlistr   r   r   Ú__static_attributes__r    ó    Ú9/home/mande/repo/quber/src/quber/core/figures/nominate.pyr   r   E   s^   ‡ ÙCáÐ"7Ñ8€Dˆ#Ó8Ù#ØÐ*iñ€L�)ó ñ "'ØÐ*Uñ"€O�Yó ñ "ØØ]ñ€J�	ö r)   r   Nc                óð  ^	• U=(       d    0 n0 m	SU	4S jjnU R                    H   nUR                  (       d  M  [        U5      nU(       a  [        S U 5       5      (       a  MA  U" UR                  S   R                  5      nUR
                  R                  UR                  5        UR                  R                  U5        M¢     U R                   H}  nUR                  (       d  M  UR                  UR                  5      [        ;  a  M;  U" UR                  S   R                  5      R                  R                  UR                  5        M     [        T	5       Vs/ s H  nT	U   PM
     sn$ s  snf )a˜  Pages of `document` holding a picture or a table nothing has read.

`table_verdicts` maps a table's `self_ref` to a verdict on whether its text
stands in the page's text layer. The orchestrator passes the map this
module's `table_verdicts` measures against the source document. A table
nominates its page when its verdict is in `UNREAD_VERDICTS`. Omitted, no
table nominates a page and only the pictures do.
c                ó6   >• TR                  U [        U S95      $ )N)r   )Ú
setdefaultr   )r   Úby_pages    €r*   Ú
page_entryÚ"nominate_pages.<locals>.page_entryd   s   ø€ Ø×!Ñ! $¬¸4Ñ(@ÓAÐAr)   c              3  ó2   #   • U  H  o[         ;   v •  M     g 7f©N)ÚFURNITURE_CLASSES©Ú.0Úcs     r*   Ú	<genexpr>Ú!nominate_pages.<locals>.<genexpr>k   s   é € ÐCº7°aÔ 1Ö1º7ùs   ‚r   )r   r   Úreturnr   )ÚpicturesÚprovr   ÚallÚpage_nor   ÚappendÚself_refÚextendÚtablesÚgetÚUNREAD_VERDICTSr   Úsorted)
ÚdocumentÚtable_verdictsÚverdictsr/   ÚpictureÚclassesÚ	nominatedÚtableÚpr.   s
            @r*   Únominate_pagesrM   U   s  ø€ ð ×# €HØ(*€G÷Bð ×$Ô$ˆØ�|�|ÙÜ! 'Ó*ˆÞ”sÑC¹7ÓC×CÑCÙÙ˜wŸ|™|¨A™×6Ñ6Ó7ˆ	Ø×Ñ×%Ñ% g×&6Ñ&6Ô7Ø×!Ñ!×(Ñ(¨Ö1ñ %ð —”ˆØ�z�zÙØ�<‰<˜Ÿ™Ó'¬Ó>ÙÙ�5—:‘:˜a‘=×(Ñ(Ó)×4Ñ4×;Ñ;¸E¿N¹NÖKñ !ô !' w¤Ó0¢˜1ˆG�AŒJ¡Ñ0Ð0ùÒ0s   Å!E3c                ó”  ^^• 0 nU R                    HN  mTR                  (       d  M  UR                  TR                  S   R                  / 5      R	                  T5        MP     0 n[        UR                  5       5       Hx  u  pE [        X5      u  nmnU H]  m[        S TR                  R                    5       5      n	[        UU4S jU 5       5      n
U
["        U	-  :¼  a  SOSUTR$                  '   M_     Mz     U$ ! [         aA  n[        R                  " SU[        U5      R                  U[        U5      5         SnAMÄ  SnAff = f)u�  Whether each table's text stands in the page's text layer, keyed by reference.

A table is `native` when the page prints text under its box, and `ocr` when
it holds cells the page has no text for â€” the parse read those off the page
image. The comparison is a count of words under the box against the cells the
table holds, and the two cases are far apart: a table typeset as text carries
at least a word per filled cell, one printed as an image carries none.

A page whose text cannot be read at all gives its tables no entry in the
map. `nominate_pages` treats a missing entry as read, so a failure here
never sends a page to be scanned on a signal nobody measured.
r   zsNomination: page {} text layer unreadable ({}: {}); its {} table(s) are taken as typeset text and none is nominatedNc              3  óx   #   • U  H0  oR                   =(       d    S R                  5       (       d  M,  Sv •  M2     g7f)Ú é   N)ÚtextÚstripr4   s     r*   r7   Ú!table_verdicts.<locals>.<genexpr>œ   s%   é € ÐUÒ$:˜q¿v¹v¿|È×>RÑ>R×>TŸ™Ò$:ùs   ‚+:±	:c              3  ób   >#   • U  H$  n[        U[        TT5      5      (       d  M   S v •  M&     g7f)rQ   N)Ú
_center_inÚ_top_left_box)r5   ÚwÚheightrK   s     €€r*   r7   rT   �   s#   øé € ÐX¢5˜a¬J°q¼-ÈÈvÓ:V×,WŸ™¢5ùs   ƒ/¦	/Únativer   )rA   r;   r-   r=   r>   rD   Úitemsr   Ú	Exceptionr   ÚwarningÚtyper!   ÚlenÚsumÚdataÚtable_cellsÚTEXT_LAYER_RATIOr?   )rE   Úsourcer.   rG   r   rA   Ú_widthÚwordsÚexcÚfilledÚunderrY   rK   s              @@r*   rF   rF   {   s  ù€ ð +-€GØ—”ˆØ�:�:‰:Ø×Ñ˜uŸz™z¨!™}×4Ñ4°bÓ9×@Ñ@ÀÖGñ !ð  "€HÜ˜wŸ}™}›Ö/‰ˆð	Ü$.¨vÓ$<Ñ!ˆF�F˜Eó ˆEÜÑU E§J¡J×$:Ò$:ÓUÓUˆFÜÕX¡5ÓXÓXˆEØ38Ô<LÈvÑ<UÓ3U¡xÐ[`ˆH�U—^‘^Ó$ó ñ 0ð" €Oøô ó 		Ü�NŠNð5àÜ�S“	×"Ñ"ØÜ�F“ôõ ûð		ús   ÂC<Ã<
EÄ6EÅEc                óÔ  • U R                   S   R                  nUR                  [        R                  :X  aV  UR
                  [        UR                  UR                  5      UR                  [        UR                  UR                  5      4$ UR
                  U[        UR                  UR                  5      -
  UR                  U[        UR                  UR                  5      -
  4$ )zJA table's provenance box as (left, top, right, bottom) in top-left points.r   )r;   ÚbboxÚcoord_originr	   ÚTOPLEFTÚlÚminÚtÚbÚrÚmax)rK   Úpage_heightrk   s      r*   rW   rW   ¢   s£   € à�:‰:�a‰=×Ñ€DØ×ÑœK×/Ñ/Ó/Ø—‘œ˜DŸF™F D§F¡FÓ+¨T¯V©V´S¸¿¹ÀÇÁÓ5HÐIÐIØ�F‰F�K¤# d§f¡f¨d¯f©fÓ"5Ñ5°t·v±v¸{ÌSÐQU×QWÑQWÐY]×Y_ÑY_ÓM`Ñ?`ÐaÐar)   c                óš   • Uu  p#pEX S   U S   -   S-  s=:*  =(       a    U:*  Os  =(       a     X0S   U S   -   S-  s=:*  =(       a    U:*  $ s  $ )z6True when a word's centre falls inside a top-left box.r   é   rQ   é   r    )ÚwordÚboxÚleftÚtopÚrightÚbottoms         r*   rV   rV   ª   sY   € à"Ñ€DˆuØ˜‘G˜d 1™gÑ%¨Ñ*×3Ó3¨eÔ3×`¸ÀQÁÈ$ÈqÉ'Ñ@QÐUVÑ?V×8`Ó8`ÐZ`Ñ8`Ð`Ñ8`Ð`r)   c                ó*  • [        U SS5      nUb  [        USS5      OSnUb  [        USS5      OSnU(       a  US   R                  /$ / n[        U S/ 5       H7  n[        USS5      nU(       d  M  UR                  US   R                  5        M9     U$ )a   The parse's top predicted class for a picture (empty if unclassified).

Predictions are ordered by descending confidence, so the first entry is the
call. Reads the current `meta.classification` field, falling back to the
deprecated `annotations` list for output written before that move.
ÚmetaNÚclassificationÚpredictionsr   r   Úpredicted_classes)ÚgetattrÚ
class_namer>   )rH   r   r€   r�   rI   ÚannÚ	predicteds          r*   r   r   °   sž   € ô �7˜F DÓ)€DØ>BÑ>N”W˜TÐ#3°TÔ:ÐTX€NØBPÑB\”'˜.¨-¸Ô>Ðbf€KÞØ˜A‘×)Ñ)Ð*Ð*à€GÜ�w ¨rÖ2ˆÜ˜CÐ!4°dÓ;ˆ	ßˆ9Ø�N‰N˜9 Q™<×2Ñ2Ö3ñ 3ð €Nr)   r2   )rE   r
   rF   zOptional[Mapping[str, str]]r9   zList[NominatedPage])rE   r
   rd   r   r9   zDict[str, str])rK   r   rt   Úfloatr9   ú!tuple[float, float, float, float])rx   z&tuple[float, float, float, float, str]ry   rˆ   r9   Úbool)rH   r   r9   r   )!r%   Ú
__future__r   Úpathlibr   Útypingr   r   r   r   Údocling_core.types.doc.baser	   Údocling_core.types.doc.documentr
   r   r   Úlogurur   Úpydanticr   r   Úquber.agents.completenessr   Ú	frozensetr3   rC   rc   r   rM   rF   rW   rV   r   r    r)   r*   Ú<module>r“      sž   ðñ"õH #å ß 0Ó 0å 3ß SÑ SÝ ß %å 0ñ
 ˜v vÐ.Ó/Ð ñ ˜U GÐ,Ó-€ð Ð ô�Iô ð$ 37ð#1Øð#1à/ð#1ð õ#1ôL$ôNbôaõr)   