ó
    ¯”'jÊ=  ã                  ód  • S r SSKJr  SSKrSSKrSSK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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\\%\\%   4   r&SS jr' " S S\5      r(SS jr)SS jr*SS jr+SS jr,\$4     SS jjr-S S jr. " S S5      r/g)!uz  
CamelotLLMTableExtractor â€” Camelot for cell values, LLM for structure.

The integrity contract being ported from quber-driver:

- Camelot DataFrame numeric values flow into the output unchanged.
- The page PNG raster flows into both the count-tables audit and the
  structure-correction call.
- The LLM is forbidden from touching numbers (enforced by the system
  prompt in `quber.agents.llm_client`).

We do *not* import from `xmandeng/quber-driver`. It is closed reference.

Both Camelot flavors run in parallel (QUE-221 rebuild):

- `lattice` â€” visible grid lines.
- `stream` â€” whitespace-based; more permissive.

Output from both flows into the classifier (drops non-tables) and then
the unifier (combines the flavor outputs per page). The legacy lattice-first /
fallback-on-empty gate is gone â€” it produced empty-shell false
positives on whitespace-aligned PDFs (TMUS-class).
é    )ÚannotationsN)ÚProcessPoolExecutor)ÚTimeoutError)ÚPath)ÚListÚLiteralÚOptionalÚTuple)Úlogger)Ú	BaseModelÚField)ÚClassifierResultÚTableClassifierÚget_classifier)Ú	LLMClientÚget_llm_client)ÚCandidateInputÚTableUnifierÚget_unifier)ÚExtractedTableg      N@ÚCamelotCandidatec                óÌ   • SSK Jn  U" [        U 5      US[        U5      S9n/ n[        USS9 H2  u  pgUSUS S	3-  nUR	                  US
5        UR                  U5        M4     U$ )Nr   )Úconvert_from_pathÚpng)ÚdpiÚfmtÚoutput_folderé   )Ústartzpage-Ú04dz.pngÚPNG)Ú	pdf2imager   ÚstrÚ	enumerateÚsaveÚappend)	Úsourcer   Úout_dirr   ÚimagesÚpathsÚiÚimgÚpaths	            Ú?/home/mande/repo/quber/src/quber/core/extractors/camelot_llm.pyÚrender_pagesr/   0   sl   € Ý+áœs 6›{°¸ÌcÐRYËlÑ[€FØ€EÜ˜F¨!Ô,‰ˆØ˜5  3  tÐ,Ñ,ˆØ�‰��uÔØ�‰�TÖñ -ð €Ló    c                  ó¦   • \ rS rSr% Sr\" SS9rS\S'   S\S'   \" S	S
9rS\S'   Sr	S\S'   \" SSSS9r
S\S'   \" \SS9rS\S'   \" SS9rS\S'   Srg)r   é<   a§  Serializable per-Camelot-table output. Crosses the spawn-process
boundary; only picklable primitives, no Camelot internals.

`cells` is the raw grid (rows of cell strings) straight from Camelot's
DataFrame; `markdown` is its rendering. The correspondence flow works
on `cells` so it can assemble, audit and fill at the grid level and
render markdown once at the end; the legacy classifier/unifier path
consumes `markdown`.
z1Stable id assigned by the parent; flavor-page-idx)Údescriptionr#   Úcandidate_idúLiteral['lattice', 'stream']Úflavorr   )ÚgeÚintÚpageNz+Optional[Tuple[float, float, float, float]]Úbboxç        g      Y@)Údefaultr7   ÚleÚfloatÚaccuracyz)Camelot's raw cell grid (rows of strings))Údefault_factoryr3   úList[List[str]]Úcellsz;Camelot's raw markdown for this table; rendering of `cells`Úmarkdown© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r4   Ú__annotations__r9   r:   r?   ÚlistrB   rC   Ú__static_attributes__rD   r0   r.   r   r   <   st   ‡ ññ Ð*]Ñ^€L�#Ó^Ø(Ó(Ù˜‘€Dˆ#ÓØ8<€DÐ
5Ó<Ù C¨C°EÑ:€HˆeÓ:Ù"ØÐ*Uñ€Eˆ?ó ñ Ð&cÑd€HˆcÖdr0   c                ó  ^^• U (       d  g[        S U  5       5      mSU4S jjmT" U S   5      SSR                  S [        T5       5       5      -   S-   /nUR                  U4S	 jU S
S  5       5        SR                  U5      $ )zÆRender a cell grid (rows of strings) to a markdown table. Row 0 is
the header; rows are padded to the widest row so the column count is
uniform. Single rendering point for the structured-grid flow.
Ú c              3  ó8   #   • U  H  n[        U5      v •  M     g 7f©N)Úlen)Ú.0Úrs     r.   Ú	<genexpr>Ú#grid_to_markdown.<locals>.<genexpr>Y   s   é € Ð&¢˜1”�A—�¢ùs   ‚c                óš   >• U  Vs/ s H  n[        U5      PM     snS/T[        U 5      -
  -  -   nSSR                  U5      -   S-   $ s  snf )NrN   ú| ú | ú |)r#   rQ   Újoin)ÚrowÚcÚpaddedÚwidths      €r.   ÚrenderÚ grid_to_markdown.<locals>.render[   sN   ø€ Ù"%Ó&¢#˜Q”#�a–&¡#Ñ&¨"¨°¼¸S»Ñ1AÑ)BÑBˆØ�e—j‘j Ó(Ñ(¨4Ñ/Ð/ùò 's   †Ar   rW   rX   c              3  ó&   #   • U  H  nS v •  M	     g7f)z---NrD   )rR   Ú_s     r.   rT   rU   _   s   é € Ð0MÂ¸1µÂùs   ‚rY   c              3  ó4   >#   • U  H  nT" U5      v •  M     g 7frP   rD   )rR   r[   r_   s     €r.   rT   rU   `   s   øé € Ð2ª	 ‘˜—�ª	ùó   ƒr   NÚ
)r[   ú	List[str]Úreturnr#   )ÚmaxrZ   ÚrangeÚextend)rB   Úlinesr_   r^   s     @@r.   Úgrid_to_markdownrl   R   sz   ù€ ö
 ØÜÑ&¡Ó&Ó&€E÷0ñ �E˜!‘HÓ˜t e§j¡jÑ0MÄÀeÄÓ0MÓ&MÑMÐPTÑTÐU€EØ	‡L�LÔ2¨¨a¨b©	Ó2Ô2Ø�9‰9�UÓÐr0   c           
     ó¤   • U R                   R                  5        VVs/ s H  o Vs/ s H  n[        U5      PM     snPM      snn$ s  snf s  snnf )z5Camelot DataFrame -> raw cell grid (rows of strings).)ÚvaluesÚtolistr#   )Údfr[   r\   s      r.   Údf_to_cellsrq   d   s?   € à-/¯Y©Y×-=Ñ-=Ô-?Ô@Ò-? c˜SÓ!šS˜ŒS�ŽV™SÔ!Ñ-?Ò@Ð@ùÒ!ùÓ@s   ž	A§A¼AÁAc                ó*   • [        [        U 5      5      $ rP   )rl   rq   )rp   s    r.   Údf_to_markdownrs   i   s   € ÜœK¨›OÓ,Ð,r0   c                ó  • SSK n/ nUR                  U SUS9n[        U5       HÙ  u  pV[        USS5      nUb  [	        U5      OSn[        US5      (       a&  UR                  (       a  [        UR                  5      OSn	[        US0 5      =(       d    0 n
[        U
R                  S	S
5      =(       d    S
5      n[        UR                  5      nUR                  [        U SU SU 3UUU	UU[        U5      S95        MÛ     U$ )z¥Top-level entrypoint for the spawned process. Imports camelot
fresh in the child so OpenCV initialization stays inside the worker
and never crosses a fork boundary.
r   NÚall)Úpagesr6   r9   r   Ú_bboxÚparsing_reportr?   r;   z-pÚ-)r4   r6   r9   r:   r?   rB   rC   )ÚcamelotÚread_pdfr$   Úgetattrr8   Úhasattrrw   Útupler>   Úgetrq   rp   r&   r   rl   )Ú
source_strr6   rz   ÚoutÚtablesÚidxÚtableÚraw_pager9   r:   Úreportr?   rB   s                r.   Úcamelot_workerr‡   m   s÷   € ó
 à"$€CØ×Ñ˜j°¸fÐÐE€FÜ Ö'‰
ˆÜ˜5 &¨!Ó,ˆØ (Ñ 4Œs�8Œ}¸!ˆÜ%,¨U°G×%<Ñ%<ÀÇÇŒu�U—[‘[Ô!ÐRVˆÜ˜Ð 0°"Ó5×;¸ˆÜ˜Ÿ™ J°Ó4×;¸Ó<ˆÜ˜EŸH™HÓ%ˆØ�
‰
ÜØ &˜x r¨$¨¨q°°Ð6ØØØØ!ØÜ)¨%Ó0ñö
	
ñ (ð$ €Jr0   c                óœ  • [         R                  " S5      n/ nSS/n[        SUS9 nU Vs0 s H#  ofUR                  [        [        U 5      U5      _M%     nnUR                  5        H$  u  ph UR                  UR                  US95        M&     SSS5        U(       d!  [        R                  " SU R                  5        U$ s  snf ! [         a5    [        R                  " SUUU R                  S9  UR                  5          M�  [         a,  n	[        R                  " S	UU R                  U	S
9   Sn	A	MÍ  Sn	A	ff = f! , (       d  f       N³= f)u	  Run lattice + stream concurrently in spawn-context subprocesses.

A flavor that times out or raises is logged ERROR and contributes
zero candidates; the other flavor's output is still returned. If
BOTH fail, returns an empty list â€” the caller decides what to do.
ÚspawnÚlatticeÚstreamé   )Úmax_workersÚ
mp_context)Útimeoutz7camelot {flavor} timed out after {timeout}s on {source})r6   r�   r'   z*camelot {flavor} raised on {source}: {exc})r6   r'   ÚexcNz5camelot produced 0 candidates from BOTH flavors on {})ÚmpÚget_contextr   Úsubmitr‡   r#   Úitemsrj   ÚresultÚFutureTimeoutErrorr   ÚerrorÚnameÚcancelÚ	Exception)
r'   Ú	timeout_sÚctxÚ
candidatesÚflavorsÚpoolr6   ÚfuturesÚfuturer�   s
             r.   Úrun_camelot_flavors_parallelr¢   ‹   s  € ô �.Š.˜Ó
!€CØ)+€JØ3<¸hÐ2G€Gä	¨°sÒ	;¸tÙZaÓbÒZaÐPV˜4Ÿ;™;¤~´s¸6³{ÀFÓKÒKÑZaˆÐbØ%Ÿm™mžo‰NˆFðØ×!Ñ! &§-¡-¸	 -Ð"BÖCñ .÷ 
<ö* Ü�ŠÐLÈfÏkÉkÔZØÐùò- cøô &ó  Ü—’ØMØ!Ø%Ø!Ÿ;™;ò	ð —‘—Üó Ü—’Ø@Ø!Ø!Ÿ;™;Ø÷	ð ûðú÷ 
<Õ	;úsR   §D=¬*CÁD=Á.CÂD=ÃD=Ã;D:ÄD=Ä	D:Ä!D5Ä/D=Ä5D:Ä:D=Ä=
Ec                ó0  • U R                  5       (       d  gU R                  5        Hg  nUR                  5       R                  S5      R                  S5       Vs/ s H  o"R                  5       PM     nn[        S U 5       5      (       d  Mg    g   gs  snf )zùA Camelot output is content-empty when every non-delimiter cell
is whitespace. Lattice's false-positive shells on whitespace-aligned
PDFs look like a 1-row grid of empty pipes; this catches them
before they reach the classifier or correction stage.
TÚ|c              3  óT   #   • U  H  o=(       a    [        U5      S S1::  + v •  M      g7f)ry   Ú N)Úset©rR   r\   s     r.   rT   Ú#is_content_empty.<locals>.<genexpr>½   s#   é € Ð=²u°!×-œ˜Q› C¨ :Ò-Ô-²uùs   ‚&(F)ÚstripÚ
splitlinesÚsplitÚany)rC   Úliner\   rB   s       r.   Úis_content_emptyr¯   ³   s|   € ð �>‰>×ÑØØ×#Ñ#Ö%ˆØ$(§J¡J£L×$6Ñ$6°sÓ$;×$AÑ$AÀ#Ô$FÓGÒ$F˜q—‘–Ñ$FˆÐGÜÑ=±uÓ=×=Ó=Ùñ &ð ùò Hs   ÁBc                  óª   • \ rS rSr% S\S'   S\S'   S\S'   S\S	'   S
\S'   S\S'   S\S'   SSSSSS\4               SS jjrSS jrSS jrSr	g)ÚCamelotLLMTableExtractoréÂ   r   Úllmr   Ú
classifierr   Úunifierr8   r   ÚboolÚrun_llm_correctionÚmax_concurrentr>   Úflavor_timeout_sNéÈ   Té   c                óÄ   • U=(       d
    [        5       U l        U=(       d
    [        5       U l        U=(       d
    [	        5       U l        X@l        XPl        X`l        Xpl	        g rP   )
r   r³   r   r´   r   rµ   r   r·   r¸   r¹   )ÚselfÚ
llm_clientr´   rµ   r   r·   r¸   r¹   s           r.   Ú__init__Ú!CamelotLLMTableExtractor.__init__Ë   sG   € ð ×1¤Ó!1ˆŒØ$×8¬Ó(8ˆŒØ×/¤+£-ˆŒØŒØ"4ÔØ,ÔØ 0Õr0   c           
   ƒ  óF  ^ ^^^^^^^^#   • [        T5      mTR                  5       (       d  [        T5      e[        R                  " SS9 n[        U5      n[        TT R                  US9m[        R                  " [        TT R                  5      I S h  v•N n[        R                  " S[        U5      [        S U 5       5      [        S U 5       5      TR                  5        U Vs/ s H!  n[!        UR"                  5      (       a  M  UPM#     nn[        U5      [        U5      -
  nU(       a  [        R                  " SU5        U(       d  / sS S S 5        $ [        R$                  " T R&                  5      mSUU 4S jjm[        R(                  " U4S	 jU 5       6 I S h  v•N n[+        XhS
S9 V	V
s/ s H  u  pšU
R,                  (       d  M  Xš4PM     nn	n
[        U5      [        U5      -
  n[        R                  " S[        U5      U5        U(       d  / sS S S 5        $ 0 nU H1  u  pšUR/                  U	R0                  / 5      R3                  Xš45        M3     [        R$                  " T R&                  5      m      SUU U4S jjm[        R(                  " U4S j[5        UR7                  5       5       5       6 I S h  v•N nU VVs/ s H  oÿ  H  nUPM     M     nnn[        R                  " S[        U5      [        U5      5        [        R$                  " T R&                  5      m          SUUU U4S jjm[        R(                  " U4S jU 5       6 I S h  v•N sS S S 5        $  GNàs  snf  GNØs  sn
n	f  N¿s  snnf  N&! , (       d  f       g = f7f)Nzquber-camelot-)Úprefix)r   r(   z>camelot produced {} candidates ({} lattice, {} stream) from {}c              3  óH   #   • U  H  oR                   S :X  d  M  Sv •  M     g7f)rŠ   r   N©r6   r¨   s     r.   rT   Ú:CamelotLLMTableExtractor.extract_tables.<locals>.<genexpr>ë   s   é € ÐCšz˜!¯X©X¸Ñ-B—A‘Ašzùó   ‚"™	"c              3  óH   #   • U  H  oR                   S :X  d  M  Sv •  M     g7f)r‹   r   NrÄ   r¨   s     r.   rT   rÅ   ì   s   é € ÐBšz˜!¯X©X¸Ñ-A—A‘AšzùrÆ   z2dropped {} content-empty candidates pre-classifierc              “  óÞ   >#   • T IS h  v•N   TR                   R                  U R                  5      I S h  v•N sS S S 5      IS h  v•N   $  NB N N	! , IS h  v•N  (       d  f       g = f7frP   )r´   ÚclassifyrC   )Ú	candidateÚclassify_semr½   s    €€r.   Úclassify_oneÚ=CamelotLLMTableExtractor.extract_tables.<locals>.classify_oneý   s=   øé € ß'š<Ø!%§¡×!9Ñ!9¸)×:LÑ:LÓ!M×M÷ (Ÿ<›<ÙM÷ (Ÿ<Ÿ<˜<üsS   ƒA-ŠA‹A-Ž)A·A¸A»A-ÁAÁA-ÁAÁA-ÁA*ÁAÁA*Á&A-c              3  ó4   >#   • U  H  nT" U5      v •  M     g 7frP   rD   )rR   r\   rÌ   s     €r.   rT   rÅ     s   øé € Ð.RÊ	À1©|¸A¯¨Ê	ùrd   F)Ústrictz$classifier accepted {} / rejected {}c           
   “  ó’  >#   • U S:  d  U [        T5      :”  a  [        R                  " SU 5        / $ [        U5      S:X  a"  US   u  p#X#UR                  UR                  /4/$ TU S-
     nU VVs/ s H.  u  p%[        UR                  UR                  UR                  S9PM0     nnnT IS h  v•N   TR                  R                  XF5      I S h  v•N nS S S 5      IS h  v•N   U VVs0 s H  u  p#UR                  X#4_M     nnn/ n	WR                   H  n
U
R                  (       a  U
R                  S   OS nU(       a  UR                  U5      OS nUc  US   nU	R                  US   US   U
R                  [        U
R                  5      45        M�     U	$ s  snnf  Nò NÑ NÃ! , IS h  v•N  (       d  f       NØ= fs  snnf 7f)Nr   z%unify: page {} out of range; skippingr   )r4   rC   r:   )rQ   r   ÚwarningrC   r4   r   r:   rµ   Úunifyr‚   Úsource_candidate_idsr   r&   rK   )r9   r”   ÚcandÚdecÚ
page_imagerb   Úunifier_inputr•   Ú
cand_by_idÚunified_outr„   Ú
primary_idÚprimaryÚpage_imagesr½   Ú	unify_sems                €€€r.   Ú
unify_pageÚ;CamelotLLMTableExtractor.extract_tables.<locals>.unify_page  sž  øé € ð ˜!“8˜t¤c¨+Ó&6Ó6Ü—N’NÐ#JÈDÔQØ�IÜ�u“: “?Ø % a¡‘I�DØ!¨¯©¸×8IÑ8IÐ7JÐKÐLÐLØ(¨°©Ñ2�
ñ $)ô!ò $)™˜ô #Ø%)×%6Ñ%6Ø!%§¡Ø!ŸY™Yôñ
 $)ð ñ !÷ %š9Ø#'§<¡<×#5Ñ#5°jÓ#P×P�F÷ %Ÿ9áNSÔTÊeÁÀ˜d×/Ñ/°$°Ò<Ée�
ÑTØ02�Ø#Ÿ]œ]�EØBG×B\×B\ ×!;Ñ!;¸AÒ!>Ðbf�JÞ<F˜jŸn™n¨ZÔ8ÈD�GØ‘Ø"'¨¡(˜Ø×&Ñ&Ø  ™ W¨Q¡Z°·±ÄÀe×F`ÑF`ÓAaÐböñ +ð #Ð"ùó)!ñ %ÙP÷ %Ÿ9Ÿ9˜9üãTùss   ƒA-GÁ05FÂ%	GÂ.F!Â/GÂ2F'ÃF#ÃF'ÃGÃ!F%Ã"	GÃ+GÄBGÆ#F'Æ%GÆ'F>Æ-F0Æ.F>Æ:Gc              3  ó8   >#   • U  H  u  pT" X5      v •  M     g 7frP   rD   )rR   Úpr”   rÞ   s      €r.   rT   rÅ   4  s   øé € ÐOÒ7N©8¨1‘*˜Q×&Ð&Ò7Nùs   ƒz1unifier combined {} accepted -> {} unified tablesc              “  ó   >#   • U R                   S:  d  U R                   [        T5      :”  a  S nOTU R                   S-
     nSnSn/ nUnSn	TR                  (       aÂ  Ub¿  [        U5      (       d¯  T IS h  v•N    TR                  R                  XB5      I S h  v•N n
S S S 5      IS h  v•N   W
bm  U
R                  nU
R                  n[        U
R                  5      nU
R                  (       a/  U
R                  R                  5       (       a  U
R                  nX‚:g  n	Un[!        UUUUU R                   U R"                  U R$                  ['        T5      U R(                  UU	S9$  Nî NÌ! [         a:  n[        R                  " SU R                   U R                  U5        S n
 S nAGN	S nAff = f GN! , IS h  v•N  (       d  f       GN= f7f)Nr   rN   Fz.LLM correction failed page={} candidate={}: {})ÚtitleÚsubtitlerC   Ú	footnotesr9   r:   r6   r'   Úcamelot_accuracyÚclassifier_decisionÚllm_corrected)r9   rQ   r·   r¯   r³   Úcorrect_structurerš   r   r—   r4   rã   rä   rK   rå   rC   rª   r   r:   r6   r#   r?   )rÔ   ÚdecisionÚ
unified_mdÚ
source_idsrÖ   rã   rä   rå   Úcorrected_mdrè   Ú
correctionr�   rb   Úcorrect_semrÜ   r½   r'   s                €€€€r.   Úcorrect_oneÚ<CamelotLLMTableExtractor.extract_tables.<locals>.correct_one?  s†  øé € ð —9‘9˜q“= D§I¡I´°KÓ0@Ó$@Ø!%‘Jà!,¨T¯Y©Y¸©]Ñ!;�Jà�Ø�Ø')�	Ø)�Ø %�à×*×*¨zÑ/EÔN^Ð_i×NjÑNjß*š{ð	.Ø/3¯x©x×/IÑ/IÈ*Ó/a×)a˜J÷  +Ÿ{ð "Ñ-Ø *× 0Ñ 0˜Ø#-×#6Ñ#6˜Ü$(¨×)=Ñ)=Ó$>˜	Ø%×.×.°:×3FÑ3F×3LÑ3L×3NÑ3NØ+5×+>Ñ+>˜LØ,8Ñ,F˜Mà�Ü%ØØ%Ø)Ø'ØŸ™ØŸ™ØŸ;™;Ü˜v›;Ø%)§]¡]Ø(0Ø"/ñð ñ)  +á)aøÜ(ó .Ü"ŸLšLØ PØ $§	¡	Ø $× 1Ñ 1Ø #ô	ð *.žJûð.ú÷  +Ÿ{Ÿ{š{üs   ƒA3GÁ6E%Á7GÁ:F3Á<E)ÂE'ÂE)ÂGÂ*F0Â+B;GÅ'E)Å)
F-Å3/F(Æ"F3Æ(F-Æ-F3Æ0GÆ3GÆ9F<Æ:GÇGc              3  ó<   >#   • U  H  u  pp4T" XX45      v •  M     g 7frP   rD   )rR   r\   ÚdÚmdÚsidsrð   s        €r.   rT   rÅ   s  s"   øé € Ð)iÒ\hÉ.È!ÐPR©+°a¸B×*EÐ*EÒ\hùs   ƒ)rÊ   r   )r9   r8   r”   z/List[Tuple[CamelotCandidate, ClassifierResult]]rg   zList[UnifiedRow])
rÔ   r   rê   r   rë   r#   rì   rf   rg   r   )r   ÚexistsÚFileNotFoundErrorÚtempfileÚTemporaryDirectoryr/   r   ÚasyncioÚ	to_threadr¢   r¹   r   ÚinforQ   Úsumr˜   r¯   rC   Ú	Semaphorer¸   ÚgatherÚzipÚis_tableÚ
setdefaultr9   r&   Úsortedr”   )r½   r'   ÚtmpdirÚtmpr�   r\   Ú	populatedÚdroppedÚ	decisionsrÔ   rÕ   ÚacceptedÚrejectedÚby_pageÚper_page_resultsÚ	page_rowsr[   Úunified_rowsrÌ   rË   rð   rï   rÜ   rÞ   rÝ   s   ``                @@@@@@@r.   Úextract_tablesÚ'CamelotLLMTableExtractor.extract_tablesÝ   s0  ÿøé € Ü�f“ˆØ�}‰}�‰Ü# FÓ+Ð+ä×(Ò(Ð0@ÒAÀVÜ�v“,ˆCÜ& v°4·8±8ÀSÑIˆKô  '×0Ò0Ô1MÈvÐW[×WlÑWlÓm×mˆJÜ�KŠKØPÜ�J“ÜÑC™zÓCÓCÜÑB™zÓBÓBØ—‘ôñ %/ÓS¢J˜qÔ6FÀqÇzÁz×6RŸ¡JˆIÐSÜ˜*“o¬¨I«Ñ6ˆGÞÜ—’ÐPÐRYÔZÞØ÷- BÑAô2 #×,Ò,¨T×-@Ñ-@ÓAˆL÷Nð Nô &ŸnšnÔ.RÉ	Ó.RÐS×SˆIä-0°ÈeÒ-TôIÚ-T¡	 ÐX[×XdÕXd“�“Ñ-Tð ñ Iô ˜9“~¬¨H«Ñ5ˆHÜ�KŠKÐ>ÄÀHÃÈxÔXÞØ÷M BÑAðT SUˆGÛ%‘	�Ø×"Ñ" 4§9¡9¨bÓ1×8Ñ8¸$¸ÖEñ &ô  ×)Ò)¨$×*=Ñ*=Ó>ˆIð#Øð#àFð#ð "÷#ñ #ôB &-§^¢^ÜO´v¸g¿m¹m»oÔ7NÓOð&÷  Ðñ 2BÔWÒ1A IËYÀc›CÉY™CÑ1AˆLÑWÜ�KŠKÐKÌSÐQYË]Ô\_Ð`lÓ\mÔnô "×+Ò+¨D×,?Ñ,?Ó@ˆKð2Ø&ð2à*ð2ð  ð2ð &ð	2ð
  ÷2ò 2ôh !ŸšÔ)iÑ\hÓ)iÐj×j÷c BÑAò
 nùò Tò TùóIñb ùó Xñz k÷c BÕAüs´   ‹A N!ÁA
NÂM5ÂANÃ+M8ÄM8Ä?NÅ
N!ÅA	NÆ%M=Æ&NÆ7N ÇN ÇANÈ
N!È&B NËNË	NËNË%BNÍ'NÍ(NÍ+
N!Í5NÍ8NÎ NÎNÎ
NÎN!c                óL   • [         R                  " U R                  U5      5      $ )uß   Sync entry point for callers without an event loop (CLI,
scripts). Wraps the async path with `asyncio.run`. Not callable
from inside an existing event loop â€” async callers should use
`await extract_tables(...)` directly.
)rú   Úrunr  )r½   r'   s     r.   Úextract_tables_syncÚ,CamelotLLMTableExtractor.extract_tables_syncu  s   € ô �{Š{˜4×.Ñ.¨vÓ6Ó7Ð7r0   )r´   r   r¹   r³   r¸   r·   rµ   )r¾   zOptional[LLMClient]r´   zOptional[TableClassifier]rµ   zOptional[TableUnifier]r   r8   r·   r¶   r¸   r8   r¹   r>   rg   ÚNone)r'   r   rg   zList[ExtractedTable])
rE   rF   rG   rH   rJ   ÚCAMELOT_FLAVOR_TIMEOUT_Sr¿   r  r  rL   rD   r0   r.   r±   r±   Â   s¡   ‡ Ø	ƒNØÓØÓØ	ƒHØÓØÓØÓð +/Ø04Ø*.ØØ#'ØØ":ð1à'ð1ð .ð1ð (ð	1ð
 ð1ð !ð1ð ð1ð  ð1ð 
õ1ô$Vk÷p8r0   r±   )r'   r   r   r8   r(   r   rg   z
List[Path])rB   rA   rg   r#   )rg   rA   )rg   r#   )r€   r#   r6   r5   rg   úList[CamelotCandidate])r'   r   r›   r>   rg   r  )rC   r#   rg   r¶   )0rI   Ú
__future__r   rú   Úmultiprocessingr‘   rø   Úconcurrent.futuresr   r   r–   Úpathlibr   Útypingr   r   r	   r
   Úlogurur   Úpydanticr   r   Úquber.agents.classifierr   r   r   Úquber.agents.llm_clientr   r   Úquber.agents.unifierr   r   r   Úquber.core.extractors.baser   r  r#   Ú
UnifiedRowr/   r   rl   rq   rs   r‡   r¢   r¯   r±   rD   r0   r.   Ú<module>r$     s½   ðñõ0 #ã Û Û Ý 2Ý AÝ ß 1Ó 1å ß %ç UÑ Uß =ß JÑ JÝ 5àÐ àÐ%Ð'7¸¸dÀ3¹iÐGÑH€
ô	ôe�yô eô,ô$Aô
-ôð@ 0ð%Øð%àð%ð õ%ôP÷y8ò y8r0   