ó
    9°Mj©  ã                  óÜ   • S r SSKJ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  SSKJrJr  SS	KJr  S
r\" S \ 5       5      rSrSS jrSS jrSS jr\S.       SS jjrg)u  Flagged-decision review HTML â€” the human view of the run's flags record.

One section per table carrying any flagged decision: the table as printed (a
page crop with the table's boundary drawn), the extraction output with the
flagged cells highlighted â€” red for a defect the page contradicts, gold for a
cell that could not be verified, green for a conventional label the extraction
added â€” and the reasoning recorded for each flag. Printed text that reached no
output cell (a table-level 'header_text_dropped' flag) is listed with the
reasoning, since it has no output cell to highlight.

Rendered from tables already extracted, no extraction of its own. The
stylesheet carries print rules (A4 landscape, one table per page), so printing
the HTML to PDF yields the same paginated document.
é    )Úannotations)Úescape)ÚPath)ÚListÚOptionalÚSequenceÚTuple)ÚImage)ÚExtractedTable)ÚCELL_STATUS_REFERENCEÚGroundedCell)Ú
before_b64é–   c              #  ó^   #   • U  H#  oR                   (       d  M  UR                  v •  M%     g 7f)N)ÚinspectÚcode)Ú.0Úss     Ú0/home/mande/repo/quber/src/quber/review/flags.pyÚ	<genexpr>r   !   s   é € ÐQÒ.C¨ÇyÅy›f˜aŸfžfÒ.Cùs   ‚-š-aŠ  
@page { size: A4 landscape; margin: 13mm; }
body { font-family: 'Liberation Serif', serif; color: #1a1a1a; font-size: 10.5pt; }
h1 { font-size: 13.5pt; color: #1f3756; border-bottom: 2px solid #46647f; padding-bottom: 4px; }
h2 { font-size: 11pt; color: #46647f; margin: 10px 0 3px 0; }
.pagebreak { page-break-before: always; }
p, li { line-height: 1.45; }
img.capture { max-width: 100%; max-height: 300px; border: 1px solid #ccc; }
table.md { border-collapse: collapse; width: 100%; margin-top: 6px; font-size: 7.2pt; }
table.md th { background: #1f3756; color: #fff; padding: 3px 5px; text-align: left; font-size: 7pt; }
table.md td { border: 1px solid #b9c6d4; padding: 2.5px 5px; }
table.md tr:nth-child(even) td { background: #eef3f9; }
table.md th.defect, table.md td.defect { background: #f7d9d9; color: #7a1212; border: 2px solid #c81e1e; }
table.md th.unverified, table.md td.unverified { background: #f5e3bb; color: #6b4e0e; border: 2px solid #bd8b1c; }
table.md th.total_label_added, table.md td.total_label_added,
table.md th.header_label_added, table.md td.header_label_added
  { background: #e2efe5; color: #205231; border: 2px solid #2f6b3f; }
span.defect { color: #c81e1e; font-weight: bold; }
span.unverified { color: #bd8b1c; font-weight: bold; }
span.total_label_added, span.header_label_added { color: #2f6b3f; font-weight: bold; }
span.header_text_dropped { color: #46647f; font-weight: bold; }
c                óN   • SSK Jn  U" [        U 5      USXS9nU(       a  US   $ S$ )zERasterize one page of the PDF; None when the page cannot be rendered.r   )Úconvert_from_pathÚpng)ÚdpiÚfmtÚ
first_pageÚ	last_pageN)Ú	pdf2imager   Ústr)ÚpdfÚpager   r   Úimgss        r   Úrender_flag_pager#   ;   s*   € å+áœS ›X¨3°EÀdÑ[€DÞˆ4�‰7Ð$ Ð$ó    c                ó�  • / n[        U 5       HŸ  u  p#US:X  a  SOSn/ nU Hb  nUR                  [        ;   a  SUR                   S3OSnUR                  SU U S[	        UR
                  5      =(       d    S	 S
U S35        Md     UR                  SSR                  U5      -   S-   5        M¡     SSR                  U5      -   S-   $ )Nr   ÚthÚtdz class="Ú"Ú Ú<Ú>z&nbsp;z</z<tr>z</tr>z<table class="md">z</table>)Ú	enumerateÚstatusÚRENDERED_STATUSESÚappendr   ÚtextÚjoin)ÚgridÚrowsÚrÚrowÚtagÚcellsÚcellÚclss           r   Ú
_grid_htmlr:   C   sÂ   € Ø€DÜ˜D–/‰ˆØ˜1“f‰d $ˆØˆÛˆDØ/3¯{©{Ô>OÓ/O�H˜TŸ[™[˜M¨Ñ+ÐUWˆCØ�L‰L˜1˜S˜E #  a¬¨t¯y©yÓ(9×(E¸XÐ'FÀbÈÈÈQÐOÖPñ ð 	�‰�F˜RŸW™W U›^Ñ+¨gÑ5Ö6ñ "ð   "§'¡'¨$£-Ñ/°*Ñ<Ð<r$   c                ól  • / nU  Ho  u  p4n[        UR                  =(       d    S5      nUR                  SU SU SUR                   SUR                   S[        UR                  5       SU S35        Mq     U H!  nUR                  S	[        U5       S
35        M#     SSR                  U5      -   S-   $ )Nz (no inspector evidence recorded)z<li><b>(Ú,z)</b> <span class='ú'>z	</span> 'z': z</li>zQ<li><b>(table)</b> <span class='header_text_dropped'>header_text_dropped</span> 'zR': printed above the table's first value row but carried into no output cell.</li>z<ul>r)   z</ul>)r   Únoter/   r-   r0   r1   )ÚflaggedÚdroppedÚitemsr4   Úcr8   r>   Úfragments           r   Ú_reasoning_htmlrD   O   sÅ   € Ø€EÛ‰
ˆˆdÜ�d—i‘i×EÐ#EÓFˆØ�‰Ø�q�c˜˜1˜#Ð0°·±°¸RÀÇÁ¸}ð MÜ�t—y‘yÓ!Ð" # d V¨5ð2ö	
ñ ó ˆØ�‰ðÜ�xÓ Ð!ð "(ð(ö	
ñ ð �B—G‘G˜E“NÑ" WÑ,Ð,r$   )r   c               óì  • / nU  GH©  u  pEU GHœ  n[        UR                  =(       d    / 5       VVV	V
s/ s H4  u  px[        U5        H  u  pšU
R                  [        ;   d  M  XyU
4PM!     M6     nn	nnn
U(       d  UR                  (       d  M�  UR
                  =(       d    UR                  nUR                  =(       d    UR
                  nU(       a  U(       a  [        XFR                  U5      OSnUb  U(       a  U(       a  S[        XìU5       S3OSn[        UR                  =(       d    SUR                   3 SUR                  =(       d    S 35      nUR                  SU S	UR                   S
U S[        UR                  5       S[        X¶R                  5       S35        GMŸ     GM¬     U(       d  gSnUR!                  S["         SU 3SR%                  U5      -   S-   SS9  U$ s  sn
n	nnf )a�  Render the flagged-decision review document for already-extracted PDFs.

``items`` pairs each source PDF with its extracted tables, the same shape
``render_review_html`` takes. Only tables carrying at least one flagged
decision (a cell whose status is registered for inspection, or dropped
printed text) get a section; when no table qualifies, nothing is written
and None is returned.
Nz0<img class='capture' src='data:image/png;base64,r=   z)<p><em>(no page image available)</em></p>Úpz: z
(untitled)z<div class='pagebreak'><h1>z</h1><h2>As printed (page z)</h2>zQ<h2>Extraction output (red = defect, gold = unverified, green = added label)</h2>z<h2>Flagged decisions</h2>z</div>uú  <p>Each section shows one table with flagged decisions: the table as printed, the extraction output with the flagged cells highlighted â€” red where the page contradicts the output (defect), gold where the output could not be verified against the page (unverified), green where the extraction added a conventional label the page does not print (total_label_added / header_label_added) â€” and the reasoning recorded for each. Printed text that reached no output cell is listed as 'header_text_dropped'.</p>z8<!doctype html><html><head><meta charset='utf-8'><style>uK   </style></head><body><h1>Review queue â€” flagged extraction decisions</h1>r)   z</body></html>zutf-8)Úencoding)r,   Úcorrected_gridr-   r.   Údropped_textÚcontent_regionÚ
som_regionr#   r!   r   r   Útable_idÚtitler/   r:   rD   Ú
write_textÚCSSr1   )rA   Úout_pathr   Úsectionsr    ÚtablesÚftr4   r5   rB   r8   r?   ÚboxÚcrop_regionÚimgÚimg_htmlÚheadingÚintros                     r   Úrender_flags_htmlrZ   `   sì  € ð €HÜ‰ˆÜˆBô (¨×(9Ñ(9×(?¸RÔ@öâ@‘F�AÜ(¨Ÿ~‘G�AØ—;‘;Ô"3Ñ3ó ��t“á-ñ Ù@ð ó ö  2§?§?Ùà×#Ñ#×4 r§}¡}ˆCØŸ-™-×<¨2×+<Ñ+<ˆKÞ9<ÆÔ" 3¯©°Ô5ÐRVˆCð ‘?¦s®{ð CÄ:ÈcÐXcÓCdÐBeÐegÑhà@ð ô
  §¡× <°°2·7±7°)¨}Ð=¸RÀÇÁ×@XÈLÐ?YÐZÓ[ˆGØ�O‰OðØ�ið  (Ø(*¯© y°°x°jØcÜ˜b×/Ñ/Ó0Ð1Ø,¬_¸WÇoÁoÓ-VÐ,WØð÷ô' ñ ö< Øð	[ð 
ð ×ÑØ
BÄ3À%ð HAØAFÀð	IØKMÏ7É7ÐS[ÓK\ñ	]Ø_oñ	pàð ñ ð
 €OùõYs   ´+G.Á#G.N)r    r   r!   Úintr   r[   ÚreturnzOptional[Image])r2   zList[List[GroundedCell]]r\   r   )r?   z#List[Tuple[int, int, GroundedCell]]r@   zSequence[str]r\   r   )rA   z/Sequence[Tuple[Path, Sequence[ExtractedTable]]]rP   r   r   r[   r\   zOptional[Path])Ú__doc__Ú
__future__r   Úhtmlr   Úpathlibr   Útypingr   r   r   r	   Ú	PIL.Imager
   Úquber.core.extractorsr   Úquber.core.extractors.baser   r   Úquber.review.htmlr   ÚDEFAULT_DPIÚ	frozensetr.   rO   r#   r:   rD   rZ   © r$   r   Ú<module>ri      s„   ðñõ #å Ý ß 2Ó 2å å 0ß JÝ (à€ñ
 ÑQÑ.CÓQÓQÐ ð€ô0%ô	=ô-ð* ñ	=Ø:ð=àð=ð 
ð	=ð
 ö=r$   