ó
    ˆ<Œj4  ã                   ó$  • S r SSKr\R                  " S5      r\R                  " S5      r\R                  " S5      r\R                  " S5      r\R                  " S5      r\R                  " S5      rS	S
SSSSSSSSSSS.r	S r
S rS rS rS rg)aÐ  
LE Capital (LE Stocktrak Pro) stock funding reader.

LE Capital is the stocking loan (floorplan) facility funding Right Drive's
stock, a genuinely different kind of relationship to every other platform in
this project: it is not somewhere cars are bought, it is who lent the money
to buy them. Added 2026-08-24 (Mark: "LE captial is the source of truth as
this is the funding platform, i need DK funding to match the LE portal").

Two screens matter, both plain rendered lists (Angular, PrimeNG), read the
same way this project already reads Motorway's or Carwow's own screens, by
inner text, not an API:

- Current Stock (stocktrak.lecapital.co.uk/stock/current-stock): every car
  still actively funded right now. Each entry's own date group heading is
  the date the loan started (proven live: HG17NRF grouped under "21 Aug '26"
  read "3 days funded" on 24 Aug, 21 plus 3 is 24, exact).
- Stock History (stocktrak.lecapital.co.uk/stock/stock-history): every loan
  that has since been repaid, each entry's own group heading is the date it
  was SETTLED (the first group explicitly labelled "(Settled Date)" on the
  live page, every group after it the same field, just not relabelled).
  Each entry also carries its own "Funded: DD/MM/YYYY" text directly, the
  real date the loan started, so unlike Current Stock this needs no date
  group inference for that one.

A real export button exists on Current Stock, but it turned out to build its
CSV client side from data already on the page (a real blob: URL was seen,
not a server request), so it gives nothing text parsing does not already
have; not used here.

Never guesses: an entry with a reg that does not look like a real UK plate
is skipped rather than mangled into a wrong record.
é    Nz.^([A-Z]{2}\d{2}[A-Z]{3}|[A-Z]\d{1,3}[A-Z]{3})$z.^(\d{1,2} \w{3} '\d{2})(?: \(Settled Date\))?$z^\d{5}-\d{6}-\d{4}$z^(\d+) days funded$z3^Funded: (\d{2})/(\d{2})/(\d{4}) - \d+ days funded$u   ^Â£([\d,]+\.\d{2})$Ú01Ú02Ú03Ú04Ú05Ú06Ú07Ú08Ú09Ú10Ú11Ú12)ÚJanÚFebÚMarÚAprÚMayÚJunÚJulÚAugÚSepÚOctÚNovÚDecc                 ó�   • U R                  5       u  pnSUR                  [        S5      5       S[        U    S[	        U5      S 3$ )z‰"21 Aug '26" -> "2026-08-21". Assumes 20xx, true for every real date
on this account so far and for the foreseeable life of this project.Ú20é'   Ú-Ú02d)ÚsplitÚlstripÚchrÚ_MONTHSÚint)ÚtextÚdayÚmonÚyrs       Ú;/Users/stevendouglas/BidBrain/bidbrain/readers/lecapital.pyÚ_parse_group_dater*   8   sD   € ð —:‘:“<�L€CˆbØ�—	‘	œ#˜b›'Ó"Ð# 1¤W¨S¡\ N°!´C¸³H¸S°>ÐBÐBó    c                 óˆ  • U R                  5        Vs/ s H)  oR                  5       (       d  M  UR                  5       PM+     nn/ nSnSnU[        U5      :  Gaâ  [        R	                  X%   5      nU(       a!  [        UR                  S5      5      nUS-  nMO  [        R	                  X%   5      (       Gao  U(       Gag  X%   nUS-   [        U5      :  a  X%S-      OSnUS-   n	U	[        U5      :  a&  X)   S:w  a  U	S-  n	U	[        U5      :  a
  X)   S:w  a  M  U	S-  n	U	[        U5      :  a  X)   OSn
U	S-  n	U	[        U5      :  a   [        R	                  X)   5      (       a  X)   OSnU	S-  n	U	[        U5      :  a  [        R	                  X)   5      OSnU	S-  n	U	[        U5      :  a  [        R	                  X)   5      OSnU(       a]  U(       aV  U(       aO  U(       aH  UR                  UUU
UU[        UR                  S5      R                  SS5      5      S.5        U	S-   nGMÛ  US-  nU[        U5      :  a  GMâ  U$ s  snf )	aÔ  Pure function over already read body text, so the parsing itself can
be tested without a live page. Each real entry: an optional date group
heading, the reg, the VIN, a status word (Sold, In Stock, etc, ignored,
DealerKit's own stock status is what this project actually gates on
elsewhere), "View", the description, the funding reference, "N days
funded", the funded amount. Returns a list of dicts: reg, vin,
plan_starts_at ("YYYY-MM-DD"), funded_value, funding_ref.Nr   é   é   ÚViewÚ,Ú )ÚregÚvinÚdescriptionÚfunding_refÚplan_starts_atÚfunded_value)Ú
splitlinesÚstripÚlenÚ_DATE_GROUP_REÚmatchr*   ÚgroupÚ_REG_REÚ_FUNDING_REF_REÚ_DAYS_FUNDED_REÚ
_AMOUNT_REÚappendÚfloatÚreplace)r%   ÚlnÚlinesÚrecordsÚcurrent_dateÚiÚmr2   r3   Újr4   r5   Údays_mÚamt_ms                 r)   Ú_parse_current_stock_textrN   ?   s  € ð #'§/¡/Ô"3ÓBÒ"3˜B·x±x·z‹ZˆR�X‰XŽZÑ"3€EÐBØ€GØ€LØ	€AØ
Œc�%‹jŒ.Ü× Ñ  ¡Ó*ˆÞÜ,¨Q¯W©W°Q«ZÓ8ˆLØ�‰FˆAÙÜ�=‰=˜™×"Ò"§|Ø‘(ˆCØ"# a¡%¬#¨e«*Ó"4�%˜A™’,¸$ˆCØ�A‘ˆAà”c˜%“j“. U¡X°Ó%7Ø�Q‘�ð ”c˜%“j“. U¡X°Õ%7à�‰FˆAØ&'¬#¨e«*£n˜%š(¸$ˆKØ�‰FˆAØ&'¬#¨e«*£n¼×9NÑ9NÈuÉx×9XÑ9X˜%š(Ð^bˆKØ�‰FˆAØ89¼CÀ»J»”_×*Ñ*¨5©8Ô4ÈDˆFØ�‰FˆAØ23´c¸%³j³.”J×$Ñ$ U¡XÔ.ÀdˆEÞ–{¦v¶%Ø—‘ØØØ#.Ø#.Ø&2Ü$)¨%¯+©+°a«.×*@Ñ*@ÀÀbÓ*IÓ$Jñ ô ð ˜‘E�ÚØ	ˆQ‰ˆðA Œc�%‹jŽ.ðB €NùòK Cs
   “H?¯H?c                 óÂ  • U R                  5        Vs/ s H)  oR                  5       (       d  M  UR                  5       PM+     nn/ nSnSnU[        U5      :  Gaÿ  [        R	                  X%   5      nU(       a!  [        UR                  S5      5      nUS-  nMO  [        R	                  X%   5      (       GaŒ  U(       Ga„  X%   nUS-   [        U5      :  a  X%S-      OSnUS-   n	U	[        U5      :  a  X)   S:X  a  U	S-  n	U	[        U5      :  a  X)   OSn
U	S-  n	U	[        U5      :  a   [        R	                  X)   5      (       a  X)   OSnU	S-  n	U	[        U5      :  a  [        R	                  X)   5      OSnU	S-  n	U	[        U5      :  a  [        R	                  X)   5      OSnU(       a˜  U(       a‘  U(       aŠ  U(       aƒ  UR                  S5      UR                  S5      UR                  S5      npþUR                  UUU
UU SU SU 3U[        UR                  S5      R                  SS	5      5      S
.5        U	S-   nGMø  US-  nU[        U5      :  a  GMÿ  U$ s  snf )aC  Same shape as _parse_current_stock_text, but for Stock History:
the date group is the SETTLED date, and each entry's own "Funded:
DD/MM/YYYY" line gives the real loan start date directly, no group
based inference needed for that one. Returns a list of dicts: reg,
vin, plan_starts_at, settled_on, funded_value, funding_ref.Nr   r-   r.   r/   é   r   r0   r1   )r2   r3   r4   r5   r6   Ú
settled_onr7   )r8   r9   r:   r;   r<   r*   r=   r>   r?   Ú_FUNDED_ON_RErA   rB   rC   rD   )r%   rE   rF   rG   Úcurrent_settledrI   rJ   r2   r3   rK   r4   r5   Úfunded_mrM   ÚdÚmoÚys                    r)   Ú_parse_stock_history_textrX   o   s  € ð #'§/¡/Ô"3ÓBÒ"3˜B·x±x·z‹ZˆR�X‰XŽZÑ"3€EÐBØ€GØ€OØ	€AØ
Œc�%‹jŒ.Ü× Ñ  ¡Ó*ˆÞÜ/°·±¸³
Ó;ˆOØ�‰FˆAÙÜ�=‰=˜™×"Ò"§Ø‘(ˆCØ"# a¡%¬#¨e«*Ó"4�%˜A™’,¸$ˆCØ�A‘ˆAØ”3�u“:‹~ %¡(¨fÓ"4Ø�Q‘�Ø&'¬#¨e«*£n˜%š(¸$ˆKØ�‰FˆAØ&'¬#¨e«*£n¼×9NÑ9NÈuÉx×9XÑ9X˜%š(Ð^bˆKØ�‰FˆAØ89¼CÀ»J»”}×*Ñ*¨5©8Ô4ÈDˆHØ�‰FˆAØ23´c¸%³j³.”J×$Ñ$ U¡XÔ.ÀdˆEÞ–{¦x¶EØ#Ÿ>™>¨!Ó,¨h¯n©n¸QÓ.?ÀÇÁÐPQÓAR�q�2Ø—‘ØØØ#.Ø#.Ø)*¨¨1¨R¨D°°!° oØ"1Ü$)¨%¯+©+°a«.×*@Ñ*@ÀÀbÓ*IÓ$Jñ ô ð ˜‘E�ÚØ	ˆQ‰ˆðA Œc�%‹jŽ.ðB €NùòK Cs
   “I¯Ic                 ó6   • [        U R                  S5      5      $ )zùEvery car LE Capital is still actively funding right now. Reads the
already logged in page's own body text (page must already be on
stock/current-stock, this reader does not navigate itself, the same
convention as this project's other list readers).Úbody)rN   Ú
inner_text©Úpages    r)   Úread_current_stockr^   �   s   € ô
 % T§_¡_°VÓ%<Ó=Ð=r+   c                 ó6   • [        U R                  S5      5      $ )z—Every loan LE Capital has recorded as settled (repaid). Reads the
already logged in page's own body text (page must already be on
stock/stock-history).rZ   )rX   r[   r\   s    r)   Úread_stock_historyr`   ¥   s   € ô % T§_¡_°VÓ%<Ó=Ð=r+   )Ú__doc__ÚreÚcompiler>   r;   r?   r@   rR   rA   r#   r*   rN   rX   r^   r`   © r+   r)   Ú<module>re      s¯   ðñ óD 
ð �*Š*ÐFÓ
G€Ø—’Ø5ó7€à—*’*Ð3Ó4€Ø—*’*Ð3Ó4€Ø—
’
Ø:ó<€à�ZŠZÐ.Ó/€
ð ˜ T°$¸tÈDØ˜ T°$¸tÈDñ€òCò-ò`+ò\>ó>r+   