§
    |ØjÙ9  ã                   ó¦  — d Z ddlZddlZddlZddlZddlmZ dZdZdZ	dZ
dZ ej        d¦  «        j        Z ej        d	¦  «        j        Z	 d!dededee         dedeeef         f
d„Zdedeeeef         eeef         f         fd„Zdededee         deeef         dz  fd„Zdededee         deeef         dz  fd„Zdededefd„Zdedefd„Zdedeeeeeef         ef         f         fd„Zdeeeeeef         ef         f         defd„Zdeeeeeef         ef         f         dedeeef         fd„Zdee         dedefd „Z dS )"a  Owner of the model-artifacts file format, write side and read side.

The model artifacts are the digest-locked file set the trainer produces as
one unit: ``models.bin`` (``CMD2``: per-model names and L2 norms, then
zlib-compressed dense bigram tables), ``rowmax.bin`` (``CRM1``: per-model
row maxima for upper-bound prescreening, digest-locked to the
``models.bin`` they were computed from), ``idf.bin`` (a 65536-byte
quantized IDF table), and ``langnorm.bin`` (``CLN1``: per-model norms
under the IDF-weighted metric the language tiers score in, digest-locked
like ``rowmax.bin``).  Keeping both directions in one module means a
format change cannot land on one side only: ``scripts/train.py`` calls
:func:`write_model_artifacts` and :func:`read_models`, while
:mod:`chardet.models` calls :func:`parse_models_bin` and
:func:`parse_rowmax_bin` behind its cached accessors.

Note: ``from __future__ import annotations`` is intentionally omitted
because this module is compiled with mypyc, which does not support PEP 563
string annotations.
é    N)ÚPaths   CMD2s   CRM1é$   s   CLN1z>Iz>dé   ÚdataÚoffsetÚnamesÚ
chunk_sizeÚreturnc                 óÐ  — t          |¦  «        }|dz  }t          j        ¦   «         }i }t          ¦   «         }d}	|}
t          | ¦  «        }d}t          |¦  «        |k     �rdt          |¦  «        z
  }|j        r|                     |j        |¦  «        }nY|
|k     r6| |
|
|z   …         }|
t          |¦  «        z  }
|                     ||¦  «        }n|sd}|                     ¦   «         }|snŽnnŒ|	t          |¦  «        z  }	||z  }t          |¦  «        dk    r:t          |¦  «        ||t          |¦  «                 <   |                     ¦   «          nt          |¦  «        dk    rnt          |¦  «        |k     �°t          |¦  «        |k    r¨d}|j        r|                     |j        d¦  «        }|sQ|j	        sJ|
|k     rD| |
|
|z   …         }|
t          |¦  «        z  }
|                     |d¦  «        }|s|j	        s|
|k     °D|s|j	        s|s|                     ¦   «         }|	t          |¦  «        z  }	|	|k    st          |¦  «        |k    rd|	› d|› �}t          |¦  «        ‚|S )	uû  Decompress the model tables from ``data[offset:]``, one per name.

    Each model is stored as its own bytes object rather than a memoryview
    slice of one big blob: mypyc compiles bytes indexing in the scoring hot
    loop to a native C array access, while memoryview indexing goes through
    a boxed generic call.  Decompression is incremental, one 64 KB table at
    a time â€” materializing the whole multi-megabyte blob and slicing it
    would transiently double the allocation and strand the freed pages in
    process RSS.  Trailing compressed bytes are ignored, as with whole-blob
    ``zlib.decompress``; the decompressed size is validated instead.

    :raises ValueError: If the decompressed size is not exactly
        ``len(names) * 65536``.
    é   r   FTó    é   z&corrupt models.bin: decompressed size z != expected )ÚlenÚzlibÚdecompressobjÚ	bytearrayÚunconsumed_tailÚ
decompressÚflushÚbytesÚclearÚeofÚ
ValueError)r   r   r   r	   Ú
num_modelsÚexpected_sizeÚdecompÚmodelsÚtableÚproducedÚposÚendÚflushedÚneedÚpieceÚchunkÚextraÚmsgs                     ú‹/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/chardet/models/_format.pyÚ_decompress_tablesr)   ,   s¸  € õ" �U‘”€JØ Ñ&€MÝÔÑ!Ô!€FØ!€FÝ‰KŒK€EØ€HØ
€CÝ
ˆd‰)Œ)€CØ€GÝ
ˆf‰+Œ+˜
Ò
"Ñ
"Ø•s˜5‘z”zÑ!ˆØÔ!ð 	Ø×%Ò% fÔ&<¸dÑCÔCˆEˆEØ�3ŠYˆYØ˜˜s ZÑ/Ð/Ô0ˆEØ•3�u‘:”:ÑˆCØ×%Ò% e¨TÑ2Ô2ˆEˆEØð 	ØˆGØ—L’L‘N”NˆEØð Øðð Ø•C˜‘J”JÑˆØ�‰ˆÝˆu‰:Œ:˜ÒÐÝ).¨u©¬ˆF�5�˜V™œÔ%Ñ&Ø�KŠK‰MŒMˆMˆMõ �‰ZŒZ˜%ÒÐØõ5 ˆf‰+Œ+˜
Ò
"Ñ
"õ6 ˆ6�{„{�jÒ Ð ð
 ˆØÔ!ð 	AØ×%Ò% fÔ&<¸aÑ@Ô@ˆEØð 	0 ¤
ð 	0¨s°Sªy¨yØ˜˜s ZÑ/Ð/Ô0ˆEØ•3�u‘:”:ÑˆCØ×%Ò% e¨QÑ/Ô/ˆEð ð 	0 ¤
ð 	0¨s°Sªy¨yð ð 	#˜VœZð 	#°ð 	#Ø—L’L‘N”NˆEØ•C˜‘J”JÑˆØ�=Ò Ð ¥C¨¡K¤K°:Ò$=Ð$=ð+°Xð +ð +Ø(ð+ð +ð 	õ ˜‰oŒoÐØ€Mr   c                 óÐ  — 	 | dd…         t           k    rd}t          |¦  «        ‚d}t          | |¦  «        \  }|dz  }|dk    rd|› d�}t          |¦  «        ‚g }i }t          |¦  «        D ]Š}t          | |¦  «        \  }|dz  }|dk    rd|› d	�}t          |¦  «        ‚| |||z   …                              d
¦  «        }||z  }t          | |¦  «        \  }	|dz  }|                     |¦  «         |	||<   Œ‹t          | ||¦  «        }
nZ# t          j	        $ r}d|› �}t          |¦  «        |‚d}~wt          j	        t          f$ r}d|› �}t          |¦  «        |‚d}~ww xY w|
|fS )záParse the v2 dense zlib-compressed models.bin format.

    :param data: Raw bytes of models.bin (must be non-empty).
    :returns: A ``(models, norms)`` tuple.
    :raises ValueError: If the data is corrupt or truncated.
    Né   z&corrupt models.bin: missing CMD2 magici'  zcorrupt models.bin: num_models=z exceeds limité   zcorrupt models.bin: name_len=z exceeds 256úutf-8é   zcorrupt models.bin: )ÚMODELS_MAGICr   Ú_unpack_uint32ÚrangeÚdecodeÚ_unpack_float64Úappendr)   r   ÚerrorÚstructÚUnicodeDecodeError)r   r'   r   r   r   ÚnormsÚ_Úname_lenÚnameÚnormr   Úes               r(   Úparse_models_binr>   y   sÈ  € ð#%Ø���Œ8•|Ò#Ð#Ø:ˆCÝ˜S‘/”/Ð!àˆÝ& t¨VÑ4Ô4‰ˆØ�!‰ˆà˜ÒÐØN°JÐNÐNÐNˆCÝ˜S‘/”/Ð!àˆØ"$ˆÝ�zÑ"Ô"ð 	ð 	ˆAÝ(¨¨vÑ6Ô6‰KˆXØ�a‰KˆFØ˜#Š~ˆ~ØL°hÐLÐLÐL�Ý  ‘o”oÐ%Ø˜ ¨(Ñ!2Ð2Ô3×:Ò:¸7ÑCÔCˆDØ�hÑˆFÝ% d¨FÑ3Ô3‰GˆTØ�a‰KˆFØ�LŠL˜ÑÔÐØˆE�$‰KˆKå# D¨&°%Ñ8Ô8ˆˆøåŒ:ð %ð %ð %Ø( QÐ(Ð(ˆÝ˜‰oŒo 1Ð$øøøøÝŒLÕ,Ð-ð %ð %ð %Ø( QÐ(Ð(ˆÝ˜‰oŒo 1Ð$øøøøð%øøøð �5ˆ=Ðs$   ‚DD
 Ä
E!ÄD.Ä.E!ÅEÅE!Úmodels_digestÚ
model_keysc                 óà   ‡ — ‰ dd…         t           k    rY‰ dt          …         |k    rFt          ‰ ¦  «        t          t          |¦  «        dz  z   k    rˆ fd„t          |¦  «        D ¦   «         S dS )u  Parse rowmax.bin into per-model row-maxima tables.

    :param data: Raw bytes of rowmax.bin.
    :param models_digest: SHA-256 digest of the current models.bin bytes.
    :param model_keys: Model keys in models.bin header order.
    :returns: Mapping of model key to its 256-byte row-maxima table, or
        ``None`` when the magic, digest, or size does not match â€” a stale
        or mismatched file would silently under-estimate row maxima and
        break the upper bound that prescreening depends on.
    Nr+   r,   c                 ó^   •— i | ])\  }}|‰t           |d z  z   t           |dz   d z  z   …         “Œ*S )r,   r   )ÚROWMAX_HEADER_SIZE©Ú.0ÚiÚkeyr   s      €r(   ú
<dictcomp>z$parse_rowmax_bin.<locals>.<dictcomp>¼   sR   ø€ ð 
ð 
ð 
á��3ð �Õ(¨1¨s©7Ñ2Õ5GÈ1ÈqÉ5ÐTWÉ-Ñ5WÐWÔXð
ð 
ð 
r   )ÚROWMAX_MAGICrC   r   Ú	enumerate©r   r?   r@   s   `  r(   Úparse_rowmax_binrL   ª   sŠ   ø€ ð 	ˆRˆaˆRŒ•LÒ Ð Ø�Õ%Ð%Ô&¨-Ò7Ð7Ý�‰IŒIÕ+­c°*©o¬oÀÑ.CÑCÒCÐCð
ð 
ð 
ð 
å# JÑ/Ô/ð
ñ 
ô 
ð 	
ð ˆ4r   c                 óà   ‡ — ‰ dd…         t           k    rY‰ dt          …         |k    rFt          ‰ ¦  «        t          t          |¦  «        dz  z   k    rˆ fd„t          |¦  «        D ¦   «         S dS )a  Parse langnorm.bin into per-model language-scoring norms.

    :param data: Raw bytes of langnorm.bin.
    :param models_digest: SHA-256 digest of the current models.bin bytes.
    :param model_keys: Model keys in models.bin header order.
    :returns: Mapping of model key to its IDF-weighted norm, or ``None``
        when the magic, digest, or size does not match -- a stale file
        would normalize every language score against the wrong length and
        silently tilt the comparison between languages.
    Nr+   r.   c           	      óZ   •— i | ]'\  }}|t          ‰t          |d z  z   ¦  «        d         “Œ(S )r.   r   )r3   ÚLANGNORM_HEADER_SIZErD   s      €r(   rH   z&parse_langnorm_bin.<locals>.<dictcomp>Õ   sH   ø€ ð 
ð 
ð 
á��3ð • Õ';¸aÀ!¹eÑ'CÑDÔDÀQÔGð
ð 
ð 
r   )ÚLANGNORM_MAGICrO   r   rJ   rK   s   `  r(   Úparse_langnorm_binrQ   Ã   sŠ   ø€ ð 	ˆRˆaˆRŒ•NÒ"Ð"Ø�Õ'Ð'Ô(¨MÒ9Ð9Ý�‰IŒIÕ-µ°J±´À!Ñ0CÑCÒCÐCð
ð 
ð 
ð 
å# JÑ/Ô/ð
ñ 
ô 
ð 	
ð ˆ4r   r   Úidfc                 óˆ   — d}t          d¦  «        D ]}| |         }|r|||z  ||         z  z  }Œt          j        |¦  «        S )a›  Derive one model's norm under the language-scoring metric.

    The language tiers compare an input profile weighted by IDF against
    models weighted by the square root of IDF, so a model's length in that
    space is the root of the sum of ``weight**2 * idf`` over its bigrams.
    Scoring folds the model-side factor into the profile and divides by
    this norm, so the table itself is never rescaled.
    r   r   )r1   ÚmathÚsqrt)r   rR   ÚtotalrF   Úvs        r(   Úlangnorm_from_tablerX   Ü   sV   € ð €EÝ�5‰\Œ\ð $ð $ˆØ�!ŒHˆØð 	$Ø�Q˜‘U˜S œV‘^Ñ#ˆEøÝŒ9�UÑÔÐr   c                 óX   ‡ — t          ˆ fd„t          ddd¦  «        D ¦   «         ¦  «        S )z»Derive the 256-byte row-maxima table of one dense model table.

    Entry ``b1`` holds the maximum weight in the model's row for lead byte
    ``b1``; a row with no bigrams yields 0.
    c              3   óL   •K  — | ]}t          ‰||d z   …         ¦  «        V — ŒdS )r,   N)Úmax)rE   Ústartr   s     €r(   ú	<genexpr>z$rowmax_from_table.<locals>.<genexpr>ó   s9   øè è € ÐSÐS°U•�U˜5 5¨3¡;Ð.Ô/Ñ0Ô0ÐSÐSÐSÐSÐSÐSr   r   r   r,   )r   r1   )r   s   `r(   Úrowmax_from_tabler^   í   s4   ø€ õ ÐSÐSÐSÐS½eÀAÀuÈcÑ>RÔ>RÐSÑSÔSÑSÔSÐSr   Úmodels_pathc                 ó&  — |                       ¦   «         si S |                      ¦   «         }|si S t          |¦  «        \  }}i }|                     ¦   «         D ]9\  }}i }t	          d¦  «        D ]}||         }	|	dk    r|	||dz	  |dz  f<   Œ|||<   Œ:|S )a¼  Read models.bin into the sparse per-model bigram dicts training uses.

    The inverse of :func:`write_model_artifacts`'s models.bin output: only
    non-zero weights appear in the dicts.  A missing or empty file reads as
    no models, so a first-ever training run and a full retrain look the
    same to the caller.

    :returns: Mapping of model key to ``{(b1, b2): weight}``.
    :raises ValueError: If the file exists but is corrupt.
    r   r   r.   éÿ   )Úis_fileÚ
read_bytesr>   Úitemsr1   )
r_   r   ÚtablesÚ_normsr   r;   r   ÚbigramsÚidxÚweights
             r(   Úread_modelsrj   ö   sÀ   € ð ×ÒÑ Ô ð Øˆ	Ø×!Ò!Ñ#Ô#€DØð Øˆ	Ý% dÑ+Ô+�N€FˆFØ46€FØ—|’|‘~”~ð ð ‰ˆˆeØ.0ˆÝ˜‘<”<ð 	9ð 	9ˆCØ˜3”ZˆFØ˜ŠzˆzØ28�˜ ™ 3¨¡:Ð.Ñ/øØˆˆt‰ˆØ€Mr   r   c                 óê  — t          | ¦  «        }dgdz  }|                      ¦   «         D ] }|D ]\  }}||dz  |z  xx         dz  cc<   ŒŒ!|dk    rt          j        |¦  «        nd}|dk    rd|z  nd}t	          d¦  «        }t          d¦  «        D ]S}	||	         }
|
dk    r>t          j        ||
z  ¦  «        }t          dt          ||z  ¦  «        dz   ¦  «        ||	<   ŒNd||	<   ŒTt          |¦  «        S )aA  Compute the 65536-byte quantized IDF table over all models.

    For each bigram index the byte holds a scaled inverse document
    frequency: bigrams present in every model score 1 (minimal signal),
    bigrams in exactly one model score 255 (maximum signal), and bigrams
    in no model score 1 (unknown, neutral).
    r   r   r.   r   g      ð?g     Ào@g        )	r   ÚvaluesrT   Úlogr   r1   r[   Úroundr   )r   r   Údoc_freqrg   Úb1Úb2Úmax_idfÚscaleÚ	idf_tablerh   ÚdfÚidf_vals               r(   Ú
_idf_tablerw     s'  € õ �V‘”€JØˆs�U‰{€HØ—=’=‘?”?ð *ð *ˆØð 	*ð 	*‰FˆB�Ø�b˜A‘g ‘^Ð$Ð$Ô$¨Ñ)Ð$Ð$Ñ$Ð$ð	*à&0°1¢n n�dŒh�zÑ"Ô"Ð"¸#€GØ&¨š{˜{ˆE�G‰OˆO°€EÝ˜%Ñ Ô €IÝ�U‰|Œ|ð ð ˆØ�cŒ]ˆØ�Š6ˆ6Ý”h˜z¨B™Ñ/Ô/ˆGÝ  ¥E¨'°E©/Ñ$:Ô$:¸QÑ$>Ñ?Ô?ˆI�c‰NˆNàˆI�c‰NˆNÝ�ÑÔÐr   c                 óÎ  — |j                              dd¬¦  «         t          | ¦  «        }t          | ¦  «        }t	          t
          ¦  «        }|t          j        dt          |¦  «        ¦  «        z  }t	          ¦   «         }g }g }|D �]
}t	          d¦  «        }	d}
| |          	                    ¦   «         D ]\  \  }}}||	|dz  |z  <   |
||z  z  }
Œ| 
                    d¦  «        }|t          j        dt          |¦  «        ¦  «        |z   z  }|t          j        dt          j        |
¦  «        ¦  «        z  }t          |	¦  «        }||z  }|                     t          |¦  «        ¦  «         |                     t!          ||¦  «        ¦  «         �Œt          |¦  «        t#          j        t          |¦  «        d	¦  «        z   }|                     |¦  «         t)          j        |¦  «                             ¦   «         }|                     d
¦  «                             |¦  «         t	          t0          ¦  «        }||z  }|D ]}||z  }Œ|                     d¦  «                             |¦  «         t3          ||¦  «        }|                     d¦  «                             |¦  «         t          |¦  «        t          |¦  «        t          |¦  «        t          |¦  «        dœS )aE  Write the model artifacts as one digest-locked set.

    ``models.bin`` is written at *models_path* (whatever its basename);
    ``rowmax.bin`` and ``idf.bin`` are written beside it under their fixed
    names.  ``rowmax.bin`` embeds the SHA-256 of the exact ``models.bin``
    bytes written here and is deliberately written **last**: it is the
    commit marker for the whole set, so an interrupted run leaves a digest
    mismatch that :func:`parse_rowmax_bin` rejects at load time instead of
    a silently stale sibling (``idf.bin`` is validated by size only).

    :param models: Mapping of model key to sparse ``{(b1, b2): weight}``.
    :param models_path: Destination path for models.bin.
    :returns: Sizes in bytes, keyed by canonical artifact name
        (``models.bin``, ``rowmax.bin``, ``idf.bin``, ``langnorm.bin``).
    T)ÚparentsÚexist_okz!Ir   r   r.   r-   ú!dé	   úidf.binú
rowmax.binúlangnorm.bin)z
models.binr~   r}   r   )ÚparentÚmkdirÚsortedrw   r   r/   r6   Úpackr   rd   ÚencoderT   rU   r   r4   r^   rX   r   ÚcompressÚwrite_bytesÚhashlibÚsha256ÚdigestÚ	with_namerI   Úlangnorm_blob_for)r   r_   Úsorted_namesrt   Úheaderre   Úrowmax_rowsÚ	langnormsr;   r   Úsq_sumrp   rq   ri   Ú
name_bytesÚfrozenÚmodels_blobr?   Úrowmax_blobÚrowÚlangnorm_blobs                        r(   Úwrite_model_artifactsr—   ,  s¾  € ð& Ô×Ò T°DÐÑ9Ô9Ð9Ý˜&‘>”>€LÝ˜6Ñ"Ô"€Iå•|Ñ$Ô$€FØ
�fŒk˜$¥ LÑ 1Ô 1Ñ2Ô2Ñ2€FÝ‰[Œ[€FØ!€KØ€IØð Añ Aˆå˜%Ñ Ô ˆØˆØ & t¤× 2Ò 2Ñ 4Ô 4ð 	&ð 	&Ñ‰HˆR��fØ$*ˆE�2˜‘7˜b‘.Ñ!Ø�f˜v‘oÑ%ˆFˆFØ—[’[ Ñ)Ô)ˆ
Ø•&”+˜d¥C¨
¡O¤OÑ4Ô4°zÑAÑAˆØ•&”+˜d¥D¤I¨fÑ$5Ô$5Ñ6Ô6Ñ6ˆõ �u‘”ˆØ�&ÑˆØ×ÒÕ,¨VÑ4Ô4Ñ5Ô5Ð5Ø×ÒÕ,¨V°YÑ?Ô?Ñ@Ô@Ð@Ñ@å˜‘-”-¥$¤-µ°f±´¸qÑ"AÔ"AÑA€KØ×Ò˜KÑ(Ô(Ð(Ý”N ;Ñ/Ô/×6Ò6Ñ8Ô8€Mà×Ò˜)Ñ$Ô$×0Ò0°Ñ;Ô;Ð;å�LÑ)Ô)€KØ�=Ñ €KØð ð ˆØ�sÑˆˆØ×Ò˜,Ñ'Ô'×3Ò3°KÑ@Ô@Ð@å% i°Ñ?Ô?€MØ×Ò˜.Ñ)Ô)×5Ò5°mÑDÔDÐDõ ˜+Ñ&Ô&Ý˜+Ñ&Ô&Ý�y‘>”>Ý˜MÑ*Ô*ð	ð ð r   r�   c                 óŒ   — t          t          ¦  «        }||z  }| D ]}|t          j        d|¦  «        z  }Œt	          |¦  «        S )z<Serialize langnorm.bin for norms in models.bin header order.r{   )r   rP   r6   rƒ   r   )r�   r?   Úblobr<   s       r(   r‹   r‹   p  sL   € å•^Ñ$Ô$€DØˆMÑ€DØð (ð (ˆØ•”˜D $Ñ'Ô'Ñ'ˆˆÝ�‰;Œ;Ðr   )r   )!Ú__doc__r‡   rT   r6   r   Úpathlibr   r/   rI   rC   rP   rO   ÚStructÚunpack_fromr0   r3   r   ÚintÚlistÚstrÚdictr)   ÚtupleÚfloatr>   rL   rQ   rX   r^   rj   rw   r—   r‹   © r   r(   ú<module>r¥      s  ððð ð( €€€Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð ð €ð €ØÐ ð
 €ØÐ à�”˜tÑ$Ô$Ô0€Ø�&”- Ñ%Ô%Ô1€ð CIðJð JØ
ðJØðJØ%)¨#¤YðJØ<?ðJà	ˆ#ˆuˆ*ÔðJð Jð Jð JðZ.Ø
ð.à
ˆ4��U�
Ô˜T # u *Ô-Ð-Ô.ð.ð .ð .ð .ðbØ
ðØ %ðØ37¸´9ðà	ˆ#ˆuˆ*Ô˜Ñðð ð ð ð2Ø
ðØ %ðØ37¸´9ðà	ˆ#ˆuˆ*Ô˜Ñðð ð ð ð2˜uð ¨5ð °Uð ð ð ð ð"T˜Uð T uð Tð Tð Tð Tð˜Tð  d¨3°°U¸3À¸8´_ÀcÐ5IÔ0JÐ+JÔ&Kð ð ð ð ð8�t˜C  e¨C°¨H¤o°sÐ&:Ô!;Ð;Ô<ð Àð ð ð ð ð4AØ��d˜5  c œ?¨CÐ/Ô0Ð0Ô1ðAàðAð 
ˆ#ˆsˆ(„^ðAð Að Að AðH  e¤ð ¸Uð Àuð ð ð ð ð ð r   