§
    éƒtjl}  ã                  óp  — d Z ddlmZ ddlZddlZddlmZmZmZ ddl	m
Z
 ddlmZmZ ddlZed         Zed         Ze G d	„ d
¦  «        ¦   «         Ze G d„ d¦  «        ¦   «         Z ej        dej        ¦  «        ZdZ ej        dez   ¦  «        Z ej        dez   ¦  «        Z ej        d¦  «        Z ej        d¦  «        ZdNd„ZdOd„ZdPd„ZdQd!„ZdRd#„ZdSd'„Z d(d(d(d)œdTd-„Z!dUdVd1„Z" ej        d2¦  «        Z# ej        d3¦  «        Z$d4Z%dWd6„Z&dXd8„Z'dYd<„Z(dZd@„Z)dAdBœd[dE„Z*d\dG„Z+dXdH„Z,d]d^dL„Z-d_d`dM„Z.dS )auþ   PDF extraction for accounting calculations.

Accuracy policy:
- Digital text PDFs â†’ extract tables, validate, may mark trusted
- Scanned PDFs â†’ OCR draft only; calculations blocked until user confirms
- Calculations never run on unconfirmed OCR data
é    )ÚannotationsN)ÚasdictÚ	dataclassÚfield)ÚPath)ÚAnyÚLiteral)ÚdigitalÚscannedÚmixedÚempty)Úbank_statementÚbalance_sheetÚunknownc                  ór   — e Zd ZU dZded<   dZded<   dZded<   dZded<   dZd	ed
<   dZ	d	ed<   dZ
ded<   dS )ÚExtractedRowÚ ÚstrÚdescriptionNúfloat | NoneÚdebitÚcreditÚamountú
str | NoneÚdateÚaccountÚraw)Ú__name__Ú
__module__Ú__qualname__r   Ú__annotations__r   r   r   r   r   r   © ó    ú+/var/www/html/CA-Chatbot/app/pdf/extract.pyr   r      sƒ   € € € € € € à€KÐÐÐÑØ€EÐÐÐÑØ€FÐÐÐÑØ€FÐÐÐÑØ€DÐÐÐÑØ€GÐÐÐÑØ€C€M€M€M�M€M€Mr#   r   c                  ó
  — e Zd ZU ded<   ded<   ded<   ded<   ded<    ee¬	¦  «        Zd
ed<   dZded<   dZded<    ee¬	¦  «        Z	ded<    ee
¬	¦  «        Zded<   dZded<   dZded<    ee
¬	¦  «        Zded<   dd„ZdS )ÚExtractionResultr   Újob_idÚfilenameÚ
SourceTypeÚsource_typeÚboolÚtrustedÚneeds_confirm)Údefault_factoryúlist[ExtractedRow]Úrowsr   Útext_previewÚdocument_textz	list[str]Úwarningsúdict[str, Any]Ú
validationFÚocr_usedr   ÚDocumentKindÚdocument_kindÚstatement_totalsÚreturnc                ó$   — t          | ¦  «        }|S ©N)r   )ÚselfÚdatas     r$   Úto_dictzExtractionResult.to_dict2   s   € Ý�d‰|Œ|ˆØˆr#   N)r:   r4   )r   r   r    r!   r   Úlistr0   r1   r2   r3   Údictr5   r6   r8   r9   r?   r"   r#   r$   r&   r&   "   s  € € € € € € à€K€K�KØ€M€M�MØÐÐÑØ€M€M�MØÐÐÑØ$˜u°TÐ:Ñ:Ô:€DÐ:Ð:Ð:Ñ:Ø€LÐÐÐÑØ€MÐÐÐÑØ˜%°Ð5Ñ5Ô5€HÐ5Ð5Ð5Ñ5Ø!& °tÐ!<Ñ!<Ô!<€JÐ<Ð<Ð<Ñ<Ø€HÐÐÐÑØ"+€MÐ+Ð+Ð+Ñ+Ø', u¸TÐ'BÑ'BÔ'BÐÐBÐBÐBÑBðð ð ð ð ð r#   r&   ux   (?<![\w.])([+-])?\s*(?:â‚¹|rs\.?|inr|usd|\$|â‚¬|Â£)?\s*(-?\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|-?\d+(?:\.\d{1,2})?)(?![\w.])u0   (?:â‚¹|rs\.?|inr|usd|\$|â‚¬|Â£)\s*([\d,]+\.?\d*)z«(?i)(?:total\s+(?:money\s+)?(?:paid|spent|debit(?:s|ed)?|withdrawal(?:s)?|payments?\s+made|outflow)|(?:money|amount)\s+paid|total\s+debits?|sum\s+of\s+debits?)\s*[:\-]?\s*z¶(?i)(?:total\s+(?:money\s+)?(?:received|credited|credit(?:s)?|deposit(?:s)?|payments?\s+received|inflow)|(?:money|amount)\s+received|total\s+credits?|sum\s+of\s+credits?)\s*[:\-]?\s*u`   (?i)-\s*(?:â‚¹|rs\.?|\$|â‚¬|Â£)\s*([\d,]+\.?\d*)\s*\+\s*(?:â‚¹|rs\.?|\$|â‚¬|Â£)\s*([\d,]+\.?\d*)z;(?i)(\d+)\s+payments?\s+made.*?(\d+)\s+payments?\s+receivedÚvaluer   r:   r   c                óf  — | €dS t          | t          t          f¦  «        rt          | ¦  «        S t          | ¦  «                             ¦   «         }|r|dv rdS d}|                     d¦  «        r3|                     d¦  «        rd}|dd…                              ¦   «         }d	}t          j        d
|¦  «        }|r5| 	                    d¦  «        dv rd}|| 
                    ¦   «         d…         }|                     dd¦  «                             dd¦  «                             dd¦  «                             dd¦  «                             dd¦  «        }t          j        dd|¦  «                             ¦   «         }|                     d¦  «        s|                     d¦  «        rd}|dd…                              ¦   «         }n1|                     d¦  «        r|dd…                              ¦   «         }	 t          |¦  «        }|rt          |¦  «         n|}||z  S # t          $ r Y dS w xY w)zJParse currency amounts, including signed values ('- Rs.381.93', '+ $528').N>   õ   â€“õ   â€”õ   âˆ’ú+ú-Fú(ú)Té   éÿÿÿÿg      ð?u   ^([+-]|âˆ’)\s*>   rF   rH   g      ð¿ú,r   u   â‚¹ú$u   â‚¬õ   Â£z(?i)^(rs\.?|inr|usd|eur|gbp)\s*rH   rF   rG   )Ú
isinstanceÚintÚfloatr   ÚstripÚ
startswithÚendswithÚreÚmatchÚgroupÚendÚreplaceÚsubÚabsÚ
ValueError)rB   ÚtextÚnegÚsignÚsign_mÚnums         r$   Ú_parse_moneyrc   R   s2  € à€}ØˆtÝ�%�#�u˜Ñ&Ô&ð Ý�U‰|Œ|ÐÝˆu‰:Œ:×ÒÑÔ€DØð �4Ð:Ð:Ð:Øˆtð €CØ‡‚�sÑÔð " §¢¨cÑ 2Ô 2ð "ØˆØ�A�b�DŒz×ÒÑ!Ô!ˆð €DÝŒXÐ'¨Ñ.Ô.€FØð $Ø�<Š<˜‰?Œ?˜lÐ*Ð*ØˆDØ�F—J’J‘L”L�N�NÔ#ˆØ�<Š<˜˜RÑ Ô ×(Ò(¨°Ñ3Ô3×;Ò;¸CÀÑDÔD×LÒLÈUÐTVÑWÔW×_Ò_Ð`dÐfhÑiÔi€DÝŒ6Ð4°b¸$Ñ?Ô?×EÒEÑGÔG€Dà‡‚�sÑÔð  ˜tŸš¨uÑ5Ô5ð  ØˆØ�A�B�BŒx�~Š~ÑÔˆˆØ	�Š˜Ñ	Ô	ð  Ø�A�B�BŒx�~Š~ÑÔˆðÝ�D‰kŒkˆØÐ'�s�3‰xŒxˆiˆi CˆØ�c‰zÐøÝð ð ð Øˆtˆtðøøøs   Ç:'H" È"
H0È/H0r^   r   ú$dict[str, float | int | None] | Nonec                ó  — | sdS | dd…         }dx}}t                                |¦  «        }t                               |¦  «        }|r"t          |                     d¦  «        ¦  «        }|r"t          |                     d¦  «        ¦  «        }|�|€dt
                               |¦  «        }|rH|€"t          |                     d¦  «        ¦  «        }|€"t          |                     d¦  «        ¦  «        }|�t          |¦  «        }|�t          |¦  «        }t                               |¦  «        }|r"t          |                     d¦  «        ¦  «        nd}|r"t          |                     d¦  «        ¦  «        nd}	|€|€dS ||||	ddœS )uÒ   Extract labeled money-in / money-out totals from statement text when present.

    Works across bank, card, and wallet statements â€” values always come from the PDF text,
    never from hardcoded amounts.
    Ni   rK   é   Ústatement_header)Ú	money_outÚmoney_inÚpayments_madeÚpayments_receivedÚsource)	Ú_LABELED_OUT_REÚsearchÚ_LABELED_IN_RErc   rX   Ú_SIGNED_PAIR_REr\   Ú_PAYMENT_COUNT_RErQ   )
r^   ÚheadÚpaidÚreceivedÚout_mÚin_mÚpairÚcountsÚpaid_nÚrecv_ns
             r$   Úparse_statement_header_totalsr{   z   s�  € ð ð ØˆtØ���Œ;€DØÐ€Dˆ8å×"Ò" 4Ñ(Ô(€EÝ× Ò  Ñ&Ô&€DØð ,Ý˜EŸKšK¨™NœNÑ+Ô+ˆØð /Ý §
¢
¨1¡¤Ñ.Ô.ˆð €|�xÐ'Ý×%Ò% dÑ+Ô+ˆØð 	7Øˆ|Ý# D§J¢J¨q¡M¤MÑ2Ô2�ØÐÝ'¨¯
ª
°1©¬Ñ6Ô6�àÐÝ�4‰yŒyˆØÐÝ�x‘=”=ˆå×%Ò% dÑ+Ô+€FØ%+Ð5�S�—’˜a‘”Ñ!Ô!Ð!°€FØ%+Ð5�S�—’˜a‘”Ñ!Ô!Ð!°€FØ€|˜Ð(ØˆtàØØØ#Ø$ðð ð r#   r+   c                óx   — |                       ¦   «         pd                     ¦   «         }t          |¦  «        dk    S )Nr   é(   )Úextract_textrS   Úlen)Úpager^   s     r$   Ú_page_has_textr�   ¨   s4   € Ø×ÒÑÔÐ% 2×,Ò,Ñ.Ô.€DÝˆt‰9Œ9˜Š?Ðr#   Úpdf_pathr   r)   c                óZ  — t          j        t          | ¦  «        ¦  «        5 }|j        s	 d d d ¦  «         dS t	          d„ |j        D ¦   «         ¦  «        }t          |j        ¦  «        }|dk    r	 d d d ¦  «         dS ||k    r	 d d d ¦  «         dS 	 d d d ¦  «         dS # 1 swxY w Y   d S )Nr   c              3  ó8   K  — | ]}t          |¦  «        ¯d V — ŒdS ©rK   N)r�   )Ú.0Úps     r$   ú	<genexpr>z%detect_source_type.<locals>.<genexpr>±   s/   è è € ÐCÐC˜qµÀÑ1BÔ1BÐC˜ÐCÐCÐCÐCÐCÐCr#   r   r   r
   r   )Ú
pdfplumberÚopenr   ÚpagesÚsumr   )r‚   ÚpdfÚ
text_pagesÚtotals       r$   Údetect_source_typer�   ­   sL  € Ý	Œ�˜X™œÑ	'Ô	'ð 	¨3ØŒyð 	Øð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	õ ÐCÐC C¤IÐCÑCÔCÑCÔCˆ
Ý�C”I‘”ˆØ˜Š?ˆ?Øð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð ˜ÒÐØð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s"   ¢	B ¸9B Á>B ÂB Â B$Â'B$Úcellc                ó”   — t          j        ddt          | pd¦  «                             ¦   «                              ¦   «         ¦  «        S )Nú\s+ú r   )rV   r[   r   rS   Úlower)r‘   s    r$   Ú_normalize_headerr–   º   s8   € ÝŒ6�&˜#�s 4 :¨2™œ×4Ò4Ñ6Ô6×<Ò<Ñ>Ô>Ñ?Ô?Ð?r#   Ú
header_rowú	list[Any]údict[str, int]c                óô  ‡— i }t          | ¦  «        D ]ä\  }}t          |¦  «        Š‰sŒt          ˆfd„dD ¦   «         ¦  «        s‰dv r||d<   Œ<t          ˆfd„dD ¦   «         ¦  «        s‰dv r||d<   Œat          ˆfd	„d
D ¦   «         ¦  «        r||d<   Œ‚‰dv sd‰v rd‰vr
d‰vr||d<   Œ˜d‰v sd‰v sd‰v sd‰v r||d<   Œ®d‰v sd‰v sd‰v sd‰v r||d<   ŒÄt          ˆfd„dD ¦   «         ¦  «        r||d<   Œå|S )Nc              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   ©r†   ÚkÚhs     €r$   rˆ   z%_map_table_headers.<locals>.<genexpr>Å   s;   øè è € ð 
ð 
àð �ˆFð
ð 
ð 
ð 
ð 
ð 
r#   )Ú
withdrawalÚwithdrawalsÚ	withdrawnr   z	dr amountz	money outzpaid outúpayment madez
money paidzamount paidzamount debited>   ÚdrÚwdlúwithdrawal amtr   c              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   rœ   s     €r$   rˆ   z%_map_table_headers.<locals>.<genexpr>Ï   s;   øè è € ð 
ð 
àð �ˆFð
ð 
ð 
ð 
ð 
ð 
r#   )
ÚdepositÚdepositsr   z	cr amountzmoney inzpaid inÚreceiptúpayment receivedúmoney receivedzamount credited>   Úcrr   c              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   rœ   s     €r$   rˆ   z%_map_table_headers.<locals>.<genexpr>Ø   s'   øè è € ÐKÐK˜A��a�ÐKÐKÐKÐKÐKÐKr#   )Úbalancezclosing balzrunning balr®   >   Úamtr�   rB   r   r   r£   r¬   r   ú
value dateztxn dateÚpostingr   Úledgerza/czyour accountc              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   rœ   s     €r$   rˆ   z%_map_table_headers.<locals>.<genexpr>â   s;   øè è € ð 
ð 
àð �ˆFð
ð 
ð 
ð 
ð 
ð 
r#   )ÚdescÚ
particularÚ	narrationÚdetailsÚitemÚremarkÚtransactionznarration / particularsr   )Ú	enumerater–   Úany)r—   ÚmappingÚidxr‘   rž   s       @r$   Ú_map_table_headersr¿   ¾   só  ø€ Ø €GÝ˜zÑ*Ô*ð ))ð ))‰	ˆˆTÝ˜dÑ#Ô#ˆØð 	Øåð 
ð 
ð 
ð 
ðð
ñ 
ô 
ñ 
ô 
ð $	)ð Ð1Ð1Ð1Ø"ˆG�GÑÐåð 
ð 
ð 
ð 
ðð
ñ 
ô 
ñ 
ô 
ð 	)ð �&ˆ[ˆ[Ø #ˆG�HÑÐÝÐKÐKÐKÐKÐ!JÐKÑKÔKÑKÔKð 	)Ø!$ˆG�IÑÐØÐ5Ð5Ð5Ø˜ˆMˆM˜d¨!˜m˜m°¸A°°à #ˆG�HÑÐØ�qˆ[ˆ[˜L¨AÐ-Ð-°¸q°°ÀIÐQRÀNÀNØ!ˆG�F‰OˆOØ˜!ˆ^ˆ^˜x¨1˜}˜}°¸°
°
¸nÐPQÐ>QÐ>QØ!$ˆG�IÑÐÝð 
ð 
ð 
ð 
ðð
ñ 
ô 
ñ 
ô 
ð 	)ð &)ˆG�MÑ"øØ€Nr#   r   ©r(   r^   Úheader_hintsr(   rÁ   r7   c                ó�  ‡‡— | › d|dd…         › d|› �                      ¦   «         Št          ˆfd„dD ¦   «         ¦  «        }t          ˆfd„dD ¦   «         ¦  «        }|                       ¦   «         Št          ˆfd„d	D ¦   «         ¦  «        r|d
z  }d‰v sd‰v sd‰v r|dz  }|d
k    r||k    rdS |dk    r||k    rdS |dk    rdS dS )z6Heuristic: bank statement vs balance sheet vs unknown.ú
Ni@  c              3  ó$   •K  — | ]
}|‰v ¯d V — ŒdS r…   r"   ©r†   r�   Úblobs     €r$   rˆ   z'detect_document_kind.<locals>.<genexpr>ö   s9   øè è € ð  ð  àð: �ˆ9ˆ9ð= 	
ð< ˆ9ˆ9ˆ9ð? ð  r#   )zbank statementzaccount statementústatement of accountzopening balanceúclosing balancerŸ   r§   r¶   ztransaction dater°   zavailable balanceza/c nozaccount numberÚifscÚupiÚneftÚimpsÚchequeÚchqÚpaytmÚphonepeÚgpayz
google payútotal money paidztotal money receivedzpayments madeúpassbook paymentsc              3  ó$   •K  — | ]
}|‰v ¯d V — ŒdS r…   r"   rÅ   s     €r$   rˆ   z'detect_document_kind.<locals>.<genexpr>  s9   øè è € ð ð àð �ˆ9ˆ9ð 	
ð ˆ9ˆ9ˆ9ðð r#   )	zbalance sheetzstatement of financial positionztotal assetsztotal liabilitieszshareholders' equityzstockholders' equityzretained earningszcurrent assetsznon-current assetsc              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   )r†   r�   Únames     €r$   rˆ   z'detect_document_kind.<locals>.<genexpr>(  s;   øè è € ð ð àð 	
ˆTˆ	ðð ð ð ð ð r#   )	ÚbankÚ	statementÚpassbookÚtxnrº   rÊ   ÚwalletÚcardr   rf   r   Úbalancesheetzbalance-sheeté   r   rK   r   )r•   rŒ   r¼   )r(   r^   rÁ   Ú	bank_hitsÚ
sheet_hitsrÆ   rÖ   s        @@r$   Údetect_document_kindrá   í   si  øø€ ð Ð7Ð7˜$˜u ˜uœ+Ð7Ð7¨Ð7Ð7×=Ò=Ñ?Ô?€Dåð  ð  ð  ð  ð
ð ñ  ô  ñ  ô  €IõB ð ð ð ð ð

ðñ ô ñ ô €Jð  �>Š>ÑÔ€DÝ
ð ð ð ð ð
ðñ ô ñ ô ð ð 	�Q‰ˆ	Ø˜$ÐÐ .°DÐ"8Ð"8¸OÈtÐ<SÐ<SØ�a‰ˆ
à�A‚~€~˜) jÒ0Ð0ØÐØ�Q‚€˜:¨Ò2Ð2Øˆà�A‚~€~ØÐØˆ9r#   r   r   r   c                óH  ‡— | › d|› �                      ¦   «         Št          j        d‰¦  «        rdS t          j        d‰¦  «        rdS d}d}t          ˆfd„|D ¦   «         ¦  «        rdS t          ˆfd	„|D ¦   «         ¦  «        rdS t          j        d
‰¦  «        rd‰vrdS dS )z?Return 'out', 'in', or None from Paytm/UPI/bank narration cues.r”   zA\b(?:neft|imps|rtgs)\s*cr\b|\bupi[-\s]?cr\b|\bcredit\s+interest\bÚinz+\b(?:neft|imps|rtgs)\s*dr\b|\bupi[-\s]?dr\bÚout)	zpaid toz
money sentztransferred tozsent tor   r¢   zrecharge ofÚwithdrawzpaid via)zreceived fromr«   r§   rª   ÚrefundÚsalaryc              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   rÅ   s     €r$   rˆ   z-_infer_direction_from_text.<locals>.<genexpr>M  s'   øè è € Ð
'Ð
'˜ˆ1�ˆ9Ð
'Ð
'Ð
'Ð
'Ð
'Ð
'r#   c              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   rÅ   s     €r$   rˆ   z-_infer_direction_from_text.<locals>.<genexpr>O  s'   øè è € Ð
&Ð
&˜ˆ1�ˆ9Ð
&Ð
&Ð
&Ð
&Ð
&Ð
&r#   z\bcredits?\bzcredit cardN)r•   rV   rn   r¼   )r   r   Úout_keysÚin_keysrÆ   s       @r$   Ú_infer_direction_from_textrì   =  sã   ø€ àÐ!Ð!˜CÐ!Ð!×'Ò'Ñ)Ô)€Då	„yÐUÐW[Ñ\Ô\ð ØˆtÝ	„yÐ?ÀÑFÔFð Øˆuð€Hð€Gõ Ð
'Ð
'Ð
'Ð
'˜hÐ
'Ñ
'Ô
'Ñ'Ô'ð ØˆuÝ
Ð
&Ð
&Ð
&Ð
&˜gÐ
&Ñ
&Ô
&Ñ&Ô&ð Øˆtå	„y� $Ñ'Ô'ð ¨MÀÐ,EÐ,EØˆtØˆ4r#   zq(?i)^(?:(?P<ref>\d{10,18})\s+)?(?P<vdate>\d{2}/\d{2}/\d{2})\s+(?P<amt>[\d,]+\.\d{2})\s+(?P<bal>[\d,]+\.\d{2})\s*$z^\d{2}/\d{2}/\d{2}\bg    „×‡Ar   c                ó¦   — | €dS t          t          | ¦  «        ¦  «        }|dk    rdS |t          k    rdS |dk    r|t          |¦  «        k    rdS dS )zCReject ID-like integers (account nos, UPI RRNs) mistaken for money.NFr   g    eÍÍAT)r\   rR   Ú_PLAUSIBLE_TXN_MAXrQ   )r   Úabs_amts     r$   Ú_is_plausible_txn_amountrð   c  sa   € à€~ØˆuÝ•%˜‘-”-Ñ Ô €GØ�!‚|€|ØˆuØÕ#Ò#Ð#Øˆuà�#‚~€~˜'¥S¨¡\¤\Ò1Ð1ØˆuØˆ4r#   r/   c                óš  ‡‡— | sg S |                       ¦   «         Št          ˆfd„dD ¦   «         ¦  «        sg S d„ |                      ¦   «         D ¦   «         }g }g }d}t          ¦   «         }d}d}|D �]Ù}|                      ¦   «         Št          ˆfd„|D ¦   «         ¦  «        rŒ3t	          j        d|                     d	d
¦  «        ¦  «        rŒ]t                               |¦  «        }	|	�rÏt          |	 
                    d¦  «        ¦  «        }
t          |	 
                    d¦  «        ¦  «        }|	 
                    d¦  «        }|
�|�t          |
¦  «        sg }d}Œëd	                     |¦  «                             ¦   «         }g }t	          j        dd
|¦  «                             ¦   «         }t	          j        dd	|¦  «        }d}|�?t          ||
z
  |z
  ¦  «        dk     }t          ||
z   |z
  ¦  «        dk     }|r|sd}n|r|sd}|€t!          ||¦  «        pd}|› d|
d›d|d›d|dd…         › �                      ¦   «         }||v r|}d}�ŒÜ|                     |¦  «         |                     t'          |pd|dk    r|
nd|dk    r|
ndd||› d|› �                     d¦  «        ¬¦  «        ¦  «         |}d}�ŒI|r!t(                               |¦  «        rd}|g}�Œlt(                               |¦  «        r|g}�Œ‹|r4t+          |¦  «        dk    r
|dd…         }|                     |¦  «         �ŒÁt	          j        d|¦  «        r|g}�ŒÛ|S )zGParse HDFC-style multi-line narrations ending in `date amount balance`.c              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   ©r†   r�   Úlows     €r$   rˆ   z5_extract_rows_from_hdfc_style_text.<locals>.<genexpr>x  s;   øè è € ð 
ð 
àð 	
ˆSˆð
ð 
ð 
ð 
ð 
ð 
r#   )r¥   rÈ   rÇ   zchq./refzvalue dtúdeposit amtc                ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S r"   ©rS   ©r†   Úlns     r$   ú
<listcomp>z6_extract_rows_from_hdfc_style_text.<locals>.<listcomp>…  ó-   € ÐBÐBÐB˜B°r·x²x±z´zÐBˆR�XŠX‰ZŒZÐBÐBÐBr#   NF)úpage z	hdfc bankzstatement ofz--------zdate narrationrõ   úfor any queriesz
**continuezaccount branchújoint holdersÚ
nominationÚcurrencyúcust idzod limitzbranch codezproduct codez	rtgs/neftza/c openzstatement fromÚaddresszphone noÚemailzcity :zstate :c              3  óB   •K  — | ]}‰                      |¦  «        V — Œd S r<   )rT   )r†   r‡   Úlow_lns     €r$   rˆ   z5_extract_rows_from_hdfc_style_text.<locals>.<genexpr>«  s1   øè è € Ð;Ð;¨ˆv× Ò  Ñ#Ô#Ð;Ð;Ð;Ð;Ð;Ð;r#   z-+r”   r   r¯   ÚbalÚvdateTz^\d{2}/\d{2}/\d{2}\s+r“   gš™™™™™©?rä   rã   ú|z.2féP   ÚTransactionú | z |©r   r   r   r   r   r   é   iúÿÿÿz/(?i)\b(?:upi|neft|imps|rtgs|ach|nach|pos|atm)\b)r•   r¼   Ú
splitlinesÚsetrV   Ú	fullmatchrZ   Ú_HDFC_AMT_BAL_RErW   rc   rX   rð   ÚjoinrS   r[   r\   rì   ÚaddÚappendr   Ú_HDFC_DATE_START_REr   rn   )r^   Úlinesr0   Únarr_bufÚprev_balÚseenÚ
skip_wrapsÚskip_prefixesrù   Úmr   r  r  r¶   Ú	directionÚas_outÚas_inÚkeyrô   r  s                     @@r$   Ú"_extract_rows_from_hdfc_style_textr!  r  sû  øø€ àð Øˆ	à
�*Š*‰,Œ,€CÝð 
ð 
ð 
ð 
ð
ð
ñ 
ô 
ñ 
ô 
ð ð ˆ	àBÐB $§/¢/Ñ"3Ô"3ÐBÑBÔB€EØ!€DØ€HØ!€HÝ‘U”U€Dð €Jð€Mð6 ð Fñ FˆØ—’‘”ˆÝÐ;Ð;Ð;Ð;¨]Ð;Ñ;Ô;Ñ;Ô;ð 	ØÝŒ<˜˜rŸzšz¨#¨rÑ2Ô2Ñ3Ô3ð 	Øå×"Ò" 2Ñ&Ô&ˆØñ -	Ý! !§'¢'¨%¡.¤.Ñ1Ô1ˆFÝ˜qŸwšw u™~œ~Ñ.Ô.ˆCØ—G’G˜GÑ$Ô$ˆEØˆ~  Õ4LÈVÑ4TÔ4T Ø�Ø!�
ØàŸš Ñ*Ô*×0Ò0Ñ2Ô2ˆIØˆHåœÐ7¸¸YÑGÔG×MÒMÑOÔOˆIÝœ˜v s¨IÑ6Ô6ˆIà$(ˆIØÐ#Ý˜h¨Ñ/°3Ñ6Ñ7Ô7¸$Ò>�Ý˜X¨Ñ.°#Ñ5Ñ6Ô6¸Ò=�Øð % %ð %Ø %�I�IØð % 6ð %Ø $�IØÐ Ý6°yÀ"ÑEÔEÐNÈ�	àÐDÐD˜VÐDÐDÐD¨#ÐDÐDÐD°I¸c¸r¸c´NÐDÐD×JÒJÑLÔLˆCØ�dˆ{ˆ{Ø�Ø!�
ÙØ�HŠH�S‰MŒMˆMà�KŠKÝØ )Ð :¨]Ø$-°Ò$6Ð$6˜&˜&¸DØ%.°$Ò%6Ð%6˜6˜6¸DØØØ$Ð-Ð-¨Ð-Ð-×3Ò3°DÑ9Ô9ðñ ô ñ	ô 	ð 	ð ˆHØˆJÙàð 	Ý"×(Ò(¨Ñ,Ô,ð  Ø"�
Ø˜4�áõ ×$Ò$ RÑ(Ô(ð 	Ø�tˆH‰HØð 	Ý�8‰}Œ}˜rÒ!Ð!Ø# B C Cœ=�Ø�OŠO˜BÑÔÐÑÝŒYÐIÈ2ÑNÔNð 	Ø�tˆHùà€Kr#   Úcellsr½   úExtractedRow | Nonec           	     óH  ‡ ‡‡— dˆ ˆfd„}t           |d¦  «        pd¦  «                             ¦   «         }t           |d¦  «        pd¦  «                             ¦   «         pd }t           |d	¦  «        pd¦  «                             ¦   «         pd }t           |d
¦  «        ¦  «        }t           |d¦  «        ¦  «        }t           |d¦  «        ¦  «        }d                     d„ ‰ D ¦   «         ¦  «        }	|€Ì|€Ê|€Èd                     d„ ‰ D ¦   «         ¦  «        }
g }t                               |
¦  «        D ]}|                     d¦  «        pd}t          |                     d¦  «        ¦  «        }|€Œ>|dk    rt          |¦  «         }n|dk    rt          |¦  «        }|                     |¦  «         Œ€|r	|d         }nd S |�g|€e|€ct          ||	¦  «        }|dk     s|dk    rt          |¦  «        }d }n5|dk    r|dk    rt          |¦  «        }d }n|dk     rt          |¦  «        }d }|s|pd}| 
                    ¦   «         Št          ˆfd„dD ¦   «         ¦  «        rd S t          j        d|	t          j        ¦  «        r|€|€d S t          |||||||	¬¦  «        S )Nr   r   r:   r   c                ól   •— ‰                      | ¦  «        }|�|t          ‰¦  «        k    rd S ‰|         S r<   )Úgetr   )r   r¾   r"  r½   s     €€r$   r&  z_row_from_cells.<locals>.getõ  s8   ø€ Ø�kŠk˜#ÑÔˆØˆ;˜#¥ U¡¤Ò+Ð+Ø�4Ø�SŒzÐr#   r   r   r   r   r   r   r   r  c              3  ó8   K  — | ]}|®t          |¦  «        V — Œd S r<   ©r   ©r†   Úcs     r$   rˆ   z"_row_from_cells.<locals>.<genexpr>  s(   è è € Ð<Ð< ¨a¨m•S˜‘V”V¨m¨m¨m¨mÐ<Ð<r#   r”   c              3  ó8   K  — | ]}|¯t          |¦  «        V — Œd S r<   r(  r)  s     r$   rˆ   z"_row_from_cells.<locals>.<genexpr>  s-   è è € Ð5Ð5 Q°1Ð5�#˜a™&œ&Ð5Ð5Ð5Ð5Ð5Ð5r#   rK   rf   rH   rG   rL   r   rä   rã   ú	Line itemc              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   )r†   r�   Údesc_ls     €r$   rˆ   z"_row_from_cells.<locals>.<genexpr>(  s;   øè è € ð ð àð 	
ˆVˆðð ð ð ð ð r#   )rÓ   r¢   rª   rÒ   rü   rý   z\(\d+\s+payments?\))r   r   r   r   r   r   r   )r   r   r:   r   )r   rS   rc   r  Ú	_MONEY_REÚfinditerrX   r\   r  rì   r•   r¼   rV   rn   Ú
IGNORECASEr   )r"  r½   r&  r   r   r   r   r   r   r   ÚjoinedÚmoneyr  Úsign_prefixrb   r  r.  s   ``              @r$   Ú_row_from_cellsr5  ô  s"  øøø€ ðð ð ð ð ð ð õ �c�c˜-Ñ(Ô(Ð.¨BÑ/Ô/×5Ò5Ñ7Ô7€KÝ�#�#�i‘.”.Ð& BÑ'Ô'×-Ò-Ñ/Ô/Ð7°4€GÝˆsˆs�6‰{Œ{Ð ˜bÑ!Ô!×'Ò'Ñ)Ô)Ð1¨T€DÝ˜˜˜W™œÑ&Ô&€EÝ˜#˜#˜h™-œ-Ñ(Ô(€FÝ˜#˜#˜h™-œ-Ñ(Ô(€FØ
�*Š*Ð<Ð< UÐ<Ñ<Ô<Ñ
<Ô
<€Cà€~˜%˜-¨F¨Nà—’Ð5Ð5¨%Ð5Ñ5Ô5Ñ5Ô5ˆØˆÝ×#Ò# FÑ+Ô+ð 		ð 		ˆAØŸ'š' !™*œ*Ð*¨ˆKÝ˜qŸwšw q™zœzÑ*Ô*ˆCØˆ{ØØ˜cÒ!Ð!Ý˜3‘x”x�i��Ø Ò#Ð#Ý˜#‘h”h�Ø�LŠL˜ÑÔÐÐØð 	Ø˜2”YˆFˆFà�4ð Ð˜e˜m°°Ý.¨{¸CÑ@Ô@ˆ	Ø�AŠ:ˆ:˜ eÒ+Ð+Ý˜‘K”KˆEØˆFˆFØ�aŠZˆZ˜I¨Ò-Ð-Ý˜‘[”[ˆFØˆFˆFØ�aŠZˆZÝ˜‘K”KˆEØˆFàð -ØÐ, ˆð ×ÒÑ Ô €FÝ
ð ð ð ð ð
ðñ ô ñ ô ð ð ˆtÝ	„yÐ'¨­b¬mÑ<Ô<ð ÀÀÐSYÐSaàˆtåØØØØØØØðñ ô ð r#   Útableúlist[list[Any]]útuple[int, dict[str, int]]c                óâ   — d}i }t          dt          | ¦  «        ¦  «        }t          |¦  «        D ];}t          | |         ¦  «        }t          |¦  «        t          |¦  «        k    r|}|}Œ<||fS )zTLocate the best header row in a pdfplumber table (title rows may sit above headers).r   é   )Úminr   Úranger¿   )r6  Úbest_iÚbest_mapÚscanÚir½   s         r$   Ú_find_table_header_indexrA  ?  st   € à€FØ!€HÝˆq•#�e‘*”*ÑÔ€DÝ�4‰[Œ[ð ð ˆÝ$ U¨1¤XÑ.Ô.ˆÝˆw‰<Œ<�#˜h™-œ-Ò'Ð'ØˆHØˆFøØ�8ÐÐr#   éà.  ©Ú	max_charsrD  rQ   c               óH  — g }t          j        t          | ¦  «        ¦  «        5 }t          |j        d¬¦  «        D ]J\  }}|                     ¦   «         pd                     ¦   «         }|r|                     d|› d|› �¦  «         ŒK	 ddd¦  «         n# 1 swxY w Y   d                     |¦  «                             ¦   «         }t          |¦  «        |k    rJ|dz  }||z
  d	z
  }	|d|…          
                    ¦   «         d
z   ||	 d…                              ¦   «         z   S |S )z:Pull readable text from the PDF pages for the LLM to read.rK   )Ústartr   z	--- Page z ---
Nú

rf   r}   u"   

â€¦[middle pages truncated]â€¦

)r‰   rŠ   r   r»   r‹   r~   rS   r  r  r   ÚrstripÚlstrip)
r‚   rD  Úbitsr�   r@  r€   Ú	page_textr^   rr   Útails
             r$   Úextract_document_textrM  L  sr  € à€DÝ	Œ�˜X™œÑ	'Ô	'ð >¨3Ý  ¤°!Ð4Ñ4Ô4ð 	>ð 	>‰GˆAˆtØ×*Ò*Ñ,Ô,Ð2°×9Ò9Ñ;Ô;ˆIØð >Ø—’Ð<¨Ð<Ð<°Ð<Ð<Ñ=Ô=Ð=øð	>ð>ð >ð >ñ >ô >ð >ð >ð >ð >ð >ð >øøøð >ð >ð >ð >ð
 �;Š;�tÑÔ×"Ò"Ñ$Ô$€DÝ
ˆ4�y„y�9ÒÐà˜A‰~ˆØ˜4Ñ "Ñ$ˆØ�E�T�EŒ{×!Ò!Ñ#Ô#Ð&NÑNÐQUÐW[ÐV[ÐV\ÐV\ÔQ]×QdÒQdÑQfÔQfÑfÐfØ€Ks   ¤A"BÂBÂBútuple[list[ExtractedRow], str]c                óž  ‡— g }g }t          ¦   «         }t          j        t          | ¦  «        ¦  «        5 }|j        D �]¹}|                     ¦   «         pd                     ¦   «         }|r|                     |¦  «         |                     ¦   «         pg }|D �]]}|rt          |¦  «        dk     rŒt          |¦  «        \  }	}
|
r|	dz   nd}|
sKdt          dt          |d         ¦  «        dz
  ¦  «        dœ}
t          |d         ¦  «        dk    rdddddœ}
d}||d …         D ]Ñ}|rt          d	„ |D ¦   «         ¦  «        rŒt          |¦  «        }|rt          |¦  «        d
k    rŒCt          t          |¦  «        |
¦  «        }|sŒct!          j        dd|j        ¦  «                             ¦   «                              ¦   «         }||v rŒ§|                     |¦  «         |                     |¦  «         ŒÒ�Œ_�Œ»	 d d d ¦  «         n# 1 swxY w Y   d                     |¦  «        }t          |¦  «        dk     r3|r1t-          |¦  «        }t          |¦  «        t          |¦  «        k    r|}t          |¦  «        dk     r3|r1t/          |¦  «        }t          |¦  «        t          |¦  «        k    r|}|�s�|�rŠ|                     ¦   «         D �]t}|                     ¦   «         }t          |¦  «        dk     rŒ+|                     ¦   «         Št3          ˆfd„dD ¦   «         ¦  «        rŒ[t          t!          j        d|¦  «        ¦  «        }|p#d„ t6                               |¦  «        D ¦   «         }|sŒ¦|d         }t9          |                     d¦  «        pd|                     d
¦  «        pdz   ¦  «        }|€"t9          |                     d
¦  «        ¦  «        }t=          |¦  «        s�Œt6                               d|¦  «                             d¦  «        }|                     t?          |pd||¬¦  «        ¦  «         �Œv|d d…         }||fS )Nr   rK   r   )r   r   é   rÞ   r:  )r   r   r   r   c              3  óh   K  — | ]-}|d u p$t          |¦  «                             ¦   «         dk    V — Œ.d S )Nr   )r   rS   r)  s     r$   rˆ   z)extract_digital_tables.<locals>.<genexpr>{  s?   è è € Ð)]Ð)]ÐPQ¨!¨t¨)Ð*Kµs¸1±v´v·|²|±~´~ÈÒ7KÐ)]Ð)]Ð)]Ð)]Ð)]Ð)]r#   rf   r“   r”   rG  é   c              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   ró   s     €r$   rˆ   z)extract_digital_tables.<locals>.<genexpr>ž  s;   øè è € ð ð àð �S�ðð ð ð ð ð r#   )z
account nor  ÚphoneÚmicrrÉ   zpin coderþ   zpage nouU   (?i)([+-])?\s*(?:â‚¹|rs\.?|inr)\s*(-?\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|-?\d+\.\d{1,2})c                óD   — g | ]}d |                      d¦  «        pdv ¯|‘ŒS )ú.rf   r   )rX   )r†   r  s     r$   rú   z*extract_digital_tables.<locals>.<listcomp>­  s<   € ð $ð $ð $àØ˜1Ÿ7š7 1™:œ:Ð+¨Ð,Ð,ð à,Ð,Ð,r#   rL   õ
    -â€“â€”|	r,  ©r   r   r   rB  ) r  r‰   rŠ   r   r‹   r~   rS   r  Úextract_tablesr   rA  ÚmaxÚallr¿   r5  r@   rV   r[   r   r•   r  r  r!  Ú!_extract_rows_from_statement_textr  r¼   r0  r/  rc   rX   rð   r   )r‚   r0   Ú	text_bitsÚseen_rawr�   r€   rK  Útablesr6  Úheader_ir½   rF  Úraw_rowÚrow_mapÚparsedr   Ú	full_textÚ	hdfc_rowsÚ	text_rowsÚlineÚcur_matchesr3  r  r   r´   Úpreviewrô   s                             @r$   Úextract_digital_tablesrk  ]  sô  ø€ Ø!€DØ€IÝ™œ€Hå	Œ�˜X™œÑ	'Ô	'ð &(¨3Ø”Ið %	(ñ %	(ˆDØ×*Ò*Ñ,Ô,Ð2°×9Ò9Ñ;Ô;ˆIØð ,Ø× Ò  Ñ+Ô+Ð+à×(Ò(Ñ*Ô*Ð0¨bˆFØð (ñ (�Øð ¥ E¡
¤
¨Q¢ ØÝ$<¸UÑ$CÔ$CÑ!�˜'Ø(/Ð6˜ 1™˜°Q�Øð à./½3¸qÅ#ÀeÈAÄhÁ-Ä-ÐRSÑBSÑ;TÔ;TÐUÐU�Gå˜5 œ8‘}”}¨Ò)Ð)à$%Ø+,Ø'(Ø&'ð	#ð #˜ð �EØ$ U V Vœ}ð (ð (�GØ"ð !¥cÐ)]Ð)]ÐU\Ð)]Ñ)]Ô)]Ñ&]Ô&]ð !Ø å0°Ñ9Ô9�GØð !¥3 w¡<¤<°1Ò#4Ð#4Ø Ý,­T°'©]¬]¸GÑDÔD�FØ!ð !Ø Ýœ& ¨¨f¬jÑ9Ô9×?Ò?ÑAÔA×GÒGÑIÔI�CØ˜h��Ø Ø—L’L Ñ%Ô%Ð%Ø—K’K Ñ'Ô'Ð'Ð'ñ(ñ#(ð%	(ð&(ð &(ð &(ñ &(ô &(ð &(ð &(ð &(ð &(ð &(ð &(øøøð &(ð &(ð &(ð &(ðP —’˜IÑ&Ô&€Iå
ˆ4�y„y�2‚~€~˜)€~Ý6°yÑAÔAˆ	Ýˆy‰>Œ>�C ™IœIÒ%Ð%ØˆDõ ˆ4�y„y�2‚~€~˜)€~Ý5°iÑ@Ô@ˆ	Ýˆy‰>Œ>�C ™IœIÒ%Ð%ØˆDð ñ )�Iñ )Ø×(Ò(Ñ*Ô*ð (	ñ (	ˆDØ—:’:‘<”<ˆDÝ�4‰yŒy˜1Š}ˆ}ØØ—*’*‘,”,ˆCÝð ð ð ð ððñ ô ñ ô ð ð åÝ”ØlØñô ñô ˆKð  ð ð $ð $å"×+Ò+¨DÑ1Ô1ð$ñ $ô $ˆEð
 ð ØØ�b”	ˆAÝ! 1§7¢7¨1¡:¤:Ð#3°¸¿ºÀ¹
¼
Ð8HÀbÑ"IÑJÔJˆFØˆ~Ý% a§g¢g¨a¡j¤jÑ1Ô1�Ý+¨FÑ3Ô3ð ÙÝ—=’=  TÑ*Ô*×0Ò0°Ñ?Ô?ˆDØ�KŠKÝØ $Ð 3¨Ø!Øðñ ô ñô ð ñ ð ˜˜˜Ô€GØ�ˆ=Ðs   µGHÈH	ÈH	c                óZ  ‡— g }d„ |                       ¦   «         D ¦   «         }d}g }|D �]}|                     ¦   «         Š‰                     d¦  «        s*‰                     d¦  «        s‰                     d¦  «        r|r|                     |¦  «         d}Œpt	          j        d|¦  «        s t	          j        d|t          j        ¦  «        r|r|                     |¦  «         |}Œ¿|r|› d|› �}t          ˆfd	„d
D ¦   «         ¦  «        s t	          j        d|t          j        ¦  «        r|r|                     |¦  «         d}�Œ|r|                     |¦  «         t          ¦   «         }|D �]¼}t	          j        d| 
                    ¦   «         ¦  «        }|st	          j        d|¦  «        }|sŒDt          |                     d¦  «        ¦  «        }	|	€Œit          |	¦  «        }	|                     d¦  «        }
|d|                     ¦   «         …          
                    ¦   «         }d}t	          j        d|t          j        ¦  «        }|rC|                     d¦  «        }||                     ¦   «         d…          
                    ¦   «         }|
dk    rdnd}t!          |¦  «        }|r|}t	          j        dd|¦  «                             ¦   «         }||v r�Œm|                     |¦  «         |                     t'          |pd|dk    r|	nd|dk    r|	ndd||¬¦  «        ¦  «         �Œ¾|S )zAParse statement lines from plain text when tables are fragmented.c                ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S r"   r÷   rø   s     r$   rú   z5_extract_rows_from_statement_text.<locals>.<listcomp>Ë  rû   r#   r   rü   rý   znote:z^\d{1,2}\s+[A-Za-z]{3}\bz^\d{1,2}:\d{2}\s*(AM|PM)\br”   c              3  ó    •K  — | ]}|‰v V — Œ	d S r<   r"   ró   s     €r$   rˆ   z4_extract_rows_from_statement_text.<locals>.<genexpr>Ý  s;   øè è € ð 
ð 
àð �ˆHð
ð 
ð 
ð 
ð 
ð 
r#   )zupi refzref noztxn idztransaction idrË   rÌ   Úrtgsu    [+-]\s*(?:â‚¹|rs\.?|\$)\s*[\d,]+uC   (?i)(?P<signed>[+-])\s*(?:â‚¹|rs\.?|\$)\s*(?P<amt>[\d,]+\.?\d*)\s*$u?   (?i)(?P<signed>[+-])\s*(?:â‚¹|rs\.?|\$)\s*(?P<amt>[\d,]+\.?\d*)r¯   NÚsignedz9^(\d{1,2}\s+[A-Za-z]{3}(?:\s+\d{1,2}:\d{2}\s*(?:AM|PM))?)rK   rH   rä   rã   r“   r
  r  )r  r•   rT   r  rV   rW   ÚIr¼   rn   r  rS   rc   rX   r\   rF  rY   rì   r[   r  r   )r^   r0   r  ÚbufÚ
candidatesrù   r  Úcandr  r   rp  Úbodyr   Údmr  Únarr_dirr   rô   s                    @r$   r]  r]  Ç  sŽ  ø€ à!€DàBÐB $§/¢/Ñ"3Ô"3ÐBÑBÔB€Eà
€CØ€JØð ñ ˆØ�hŠh‰jŒjˆØ�>Š>˜'Ñ"Ô"ð 	 c§n¢nÐ5FÑ&GÔ&Gð 	È3Ï>Ê>ÐZaÑKbÔKbð 	Øð Ø×!Ò! #Ñ&Ô&Ð&Ø�ØÝŒ8Ð/°Ñ4Ô4ð 	½¼ÐA^Ð`bÕdfÔdhÑ8iÔ8ið 	Øð 'Ø×!Ò! #Ñ&Ô&Ð&ØˆCØØð 	 Ø�-�-˜2�-�-ˆCÝð 
ð 
ð 
ð 
à^ð
ñ 
ô 
ñ 
ô 
ð 	õ ŒYÐ:¸BÅÄÑEÔEð	ð ð Ø×!Ò! #Ñ&Ô&Ð&Ø�ùØ
ð Ø×Ò˜#ÑÔÐå‘U”U€DØð (
ñ (
ˆÝŒIØRØ�JŠJ‰LŒLñ
ô 
ˆð ð 	Ý”	ØRØñô ˆAð ð 	ØÝ˜aŸgšg e™nœnÑ-Ô-ˆØˆ>ØÝ�V‘”ˆØ—’˜Ñ"Ô"ˆØ�K�a—g’g‘i”i�KÔ ×&Ò&Ñ(Ô(ˆØˆÝŒXÐRÐTXÕZ\ÔZ^Ñ_Ô_ˆØð 	,Ø—8’8˜A‘;”;ˆDØ˜Ÿš™œ˜
˜
Ô#×)Ò)Ñ+Ô+ˆDØ# sš]˜]�E�E°ˆ	Ý-¨dÑ3Ô3ˆØð 	!Ø ˆIÝŒf�V˜S $Ñ'Ô'×-Ò-Ñ/Ô/ˆØ�$ˆ;ˆ;ÙØ�Š�‰ŒˆØ�ŠÝØ Ð1 MØ )¨UÒ 2Ð 2�f�f¸Ø!*¨dÒ!2Ð!2�v�v¸ØØØðñ ô ñ		
ô 		
ð 		
ñ 		
ð €Kr#   rP  Ú	max_pagesú)tuple[list[ExtractedRow], str, list[str]]c           	     óâ  — g }	 ddl m} n# t          $ r	 g ddgfcY S w xY w	 ddl}n# t          $ r	 g ddgfcY S w xY w	  |t	          | ¦  «        dd|¬	¦  «        }n # t
          $ r}g dd
|› �gfcY d}~S d}~ww xY wg }g }|D �]�}		 |                     |	¦  «        pd}
n/# t
          $ r"}|                     d|› �¦  «         Y d}~ŒCd}~ww xY w|
                     ¦   «         }
|
r|                     |
¦  «         |
 	                    ¦   «         D �]}|                     ¦   «         }t          t                               |¦  «        ¦  «        }|sŒA|d         }t          |                     d¦  «        pd|                     d¦  «        pdz   ¦  «        }|€"t          |                     d¦  «        ¦  «        }|€Œ¬t                               d|¦  «                             d¦  «        }|                     t!          |pd||¬¦  «        ¦  «         �Œ�Œ�|                     d¦  «         t#          |¦  «        |k    r|                     d|› d�¦  «         |d                     |¦  «        dd…         |fS )z;OCR draft for scanned PDFs. Never trusted for calculations.r   )Úconvert_from_pathr   z¡OCR packages not installed. Install: pip install pdf2image pytesseract and system packages poppler-utils + tesseract-ocr. Or enter numbers manually after upload.Nzapytesseract not installed. Run: pip install pytesseract and install system package tesseract-ocr.éÈ   rK   )ÚdpiÚ
first_pageÚ	last_pagez6Could not render PDF for OCR (is poppler installed?): zTesseract failed: rL   rf   rX  zOCR linerY  zLOCR output is a draft only. Confirm or edit every amount before calculating.zOCR limited to first z pages for speed.rG  rB  )Ú	pdf2imager{  ÚImportErrorÚpytesseractr   Ú	ExceptionÚimage_to_stringr  rS   r  r@   r/  r0  rc   rX   r[   r   r   r  )r‚   rx  r3   r{  r‚  ÚimagesÚexcr^  r0   Úimgr^   rh  r3  r  r   r´   s                   r$   Úextract_ocr_draftrˆ    s;  € à€Hð
Ø/Ð/Ð/Ð/Ð/Ð/Ð/øÝð 
ð 
ð 
Ø�2ð6ð
ð 
ð 	
ð 	
ð 	
ð
øøøð
ØÐÐÐÐøÝð 
ð 
ð 
Ø�2ð8ð
ð 
ð 	
ð 	
ð 	
ð
øøøðXØ"Ð"¥3 x¡=¤=°cÀaÐS\Ð]Ñ]Ô]ˆˆøÝð Xð Xð XØ�2ÐVÐQTÐVÐVÐWÐWÐWÐWÐWÐWÐWÐWøøøøðXøøøð €IØ!€DØð _ñ _ˆð	Ø×.Ò.¨sÑ3Ô3Ð9°rˆDˆDøÝð 	ð 	ð 	Ø�OŠOÐ6°Ð6Ð6Ñ7Ô7Ð7ØˆHˆHˆHˆHøøøøð	øøøð �zŠz‰|Œ|ˆØð 	#Ø×Ò˜TÑ"Ô"Ð"Ø—O’OÑ%Ô%ð 	_ñ 	_ˆDØ—:’:‘<”<ˆDÝ�×+Ò+¨DÑ1Ô1Ñ2Ô2ˆEØð ØØ�b”	ˆAÝ! 1§7¢7¨1¡:¤:Ð#3°¸¿ºÀ¹
¼
Ð8HÀbÑ"IÑJÔJˆFØˆ~Ý% a§g¢g¨a¡j¤jÑ1Ô1�Øˆ~ØÝ—=’=  TÑ*Ô*×0Ò0°Ñ?Ô?ˆDØ�KŠK�°Ð1C¸ÈFÐX\Ð]Ñ]Ô]Ñ^Ô^Ð^Ñ^ñ	_ð ‡O‚OØVñô ð õ ˆ6�{„{�iÒÐØ�ŠÐL°	ÐLÐLÐLÑMÔMÐMà�—’˜YÑ'Ô'¨¨¨Ô/°Ð9Ð9sM   „ ‹�¢' §:¹:¾A Á
A8Á%A3Á-A8Á3A8ÂBÂ
C	Â'CÃC	c                ó¤  — t          t          j        ¦   «         ¦  «        }|p| j        }t	          | ¦  «        }g }g }d}d}|dv r-t          | ¦  «        \  }}|dk    r|                     d¦  «         |dk    s|dk    rP|sNt          | ¦  «        \  }	}
}|                     |¦  «         |	r	|	}d}|s|
}n|dk    r|                     d¦  «         |d	k    r|                     d
¦  «         d}|dv rt          | d¬¦  «        }|s|}t          ||p|d                     d„ |d d…         D ¦   «         ¦  «        ¬¦  «        }t          |p|¦  «        pi }|r|dk    rd}|                     d¦  «         |dk    r|                     d¦  «         nm|dk    rgt          |¦  «        dk    rTt          d„ |D ¦   «         ¦  «        }|t          dt          |¦  «        dz  ¦  «        k    rd}|                     d¦  «         |dk    ot!          |¦  «        o| }| }|sd}d}|s|r|dk    o| }| }t#          |||||||p|d d…         |p|||||¬¦  «        }|S )Nr   F>   r   r
   r   zDPDF has mixed text/image pages. Prefer confirming extracted amounts.r   TzKNo amounts extracted. Enter line items manually, then confirm to calculate.r   zPDF appears empty.iÀ]  rC  r”   c              3  ó8   K  — | ]}|j         pd dd…         V — ŒdS )r   Nr}   )r   ©r†   Úrs     r$   rˆ   zextract_pdf.<locals>.<genexpr>w  s2   è è € ÐLÐL¸Q˜qœ}Ð2°°C°R°CÔ8ÐLÐLÐLÐLÐLÐLr#   é   rÀ   r   r   zCDetected wallet/UPI statement totals (money paid / money received).zpDetected as a bank / account statement. Totals use money-in vs money-out (not balance-sheet assets/liabilities).é   c              3  ó(   K  — | ]}|j         ¯	d V — ŒdS r…   )r   r‹  s     r$   rˆ   zextract_pdf.<locals>.<genexpr>…  s)   è è € Ð.Ð.˜! q¤vÐ.�AÐ.Ð.Ð.Ð.Ð.Ð.r#   rP  zGTreating this PDF as a transaction statement based on dated line items.r
   i¸  )r'   r(   r*   r,   r-   r0   r1   r2   r3   r6   r8   r9   )r   ÚuuidÚuuid4rÖ   r�   rk  r  rˆ  ÚextendrM  rá   r  r{   r   rŒ   r[  r+   r&   )r‚   r(   r'   rÖ   rl   r3   r0   rj  r6   Úocr_rowsÚocr_previewÚocr_warningsr2   Úkindr9   Údatedr,   r-   Úresults                      r$   Úextract_pdfr™  O  s8  € Ý•”‘”ÑÔ€FØÐ$�x”}€DÝ Ñ)Ô)€FØ€HØ!€DØ€GØ€HàÐ%Ð%Ð%Ý.¨xÑ8Ô8‰ˆˆgØ�WÒÐØ�OŠOÐbÑcÔcÐcà�ÒÐ˜v¨Ò0Ð0¸Ð0Ý.?ÀÑ.IÔ.IÑ+ˆ�+˜|Ø�Š˜Ñ%Ô%Ð%Øð 	ØˆDØˆHØð &Ø%�øØ�yÒ Ð Ø�OŠOØ]ñô ð ð �ÒÐØ�ŠÐ,Ñ-Ô-Ð-ð €MØÐ%Ð%Ð%Ý-¨hÀ%ÐHÑHÔHˆØð  ØˆåØØÐ%˜gØ—X’XÐLÐLÀ$ÀsÈÀsÄ)ÐLÑLÔLÑLÔLðñ ô €Dõ
 5°]Ð5MÀgÑNÔNÐTÐRTÐØð 
˜D IÒ-Ð-ØˆØ�ŠØQñ	
ô 	
ð 	
ð ÐÒÐØ�Šð6ñ	
ô 	
ð 	
ð 	
ð 
�Ò	Ð	�s 4™yœy¨Bš˜ÝÐ.Ð.˜tÐ.Ñ.Ô.Ñ.Ô.ˆØ•C˜�3˜t™9œ9¨™>Ñ*Ô*Ò*Ð*Ø#ˆDØ�OŠOØYñô ð ð
 ˜	Ò!ÐA¥d¨4¡j¤jÐA¸°\€GØ�K€Màð ØˆØˆð ð $Ð$ð $Ø˜IÒ%Ð6¨h¨,ˆØ#˜ˆåØØØØØ#ØØÐ. °°°Ô6Ø#Ð. wØØØØ)ðñ ô €Fð €Mr#   )rB   r   r:   r   )r^   r   r:   rd   )r:   r+   )r‚   r   r:   r)   )r‘   r   r:   r   )r—   r˜   r:   r™   )r(   r   r^   r   rÁ   r   r:   r7   )r   )r   r   r   r   r:   r   )r   r   r:   r+   )r^   r   r:   r/   )r"  r˜   r½   r™   r:   r#  )r6  r7  r:   r8  )r‚   r   rD  rQ   r:   r   )r‚   r   r:   rN  )rP  )r‚   r   rx  rQ   r:   ry  r<   )r‚   r   r(   r   r:   r&   )/Ú__doc__Ú
__future__r   rV   r�  Údataclassesr   r   r   Úpathlibr   Útypingr   r	   r‰   r)   r7   r   r&   Úcompiler1  r/  Ú_CUR_AMTrm   ro   rp   rq   rc   r{   r�   r�   r–   r¿   rá   rì   r  r  rî   rð   r!  r5  rA  rM  rk  r]  rˆ  r™  r"   r#   r$   ú<module>r¡     s’  ððð ð #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø €€€Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ð Ð à Ð Ð Ð àÐ;Ô<€
ØÐCÔD€ð ðð ð ð ð ñ ô ñ „ðð ðð ð ð ð ñ ô ñ „ðð( ˆBŒJØØ„Mñô €	ð ?€Ø�"”*ð7à9AñBñô €ð
 �”ð9à;CñDñô €ð �"”*Øgñô €ð �B”JØBñô Ð ð
%ð %ð %ð %ðP+ð +ð +ð +ð\ð ð ð ð

ð 
ð 
ð 
ð@ð @ð @ð @ð,ð ,ð ,ð ,ðb ØØð	Mð Mð Mð Mð Mð Mð`ð ð ð ð ð8 �2”:ð"ñô Ð ð !�b”jÐ!8Ñ9Ô9Ð Ø!Ð ðð ð ð ðð ð ð ðDHð Hð Hð HðV
ð 
ð 
ð 
ð ?Dð ð ð ð ð ð ð"gð gð gð gðTJð Jð Jð JðZ8:ð 8:ð 8:ð 8:ð 8:ðvXð Xð Xð Xð Xð Xð Xr#   