Ë
    ^ãj~�  ã                   ó  — U d Z ddlZddlZddlZddlZddlZddlmZm	Z	m
Z
mZmZ ddlmZ ddlmZ eeeef   eee   eeeeef   f   f   f   Zi dd“dd“d	d
“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“d#d$“d%d&“d'd(d)d*d+d,d-d.d/d0d1d2d3d4œ¥Zeeef   ed5<   ej3                  «       D � �ci c]  \  } }|| “Œ
 c}} Zeeef   ed6<   d7ed8efd9„Zej:                  d8efd:„«       Zi dd“dd“d
d“dd“dd“dd“dd“dd“dd“dd“d d“d"d“d$d“d&d“d'd“d)d“d(d“dddddd	dddddddd;œ¥Zeeef   ed<<   d	Z dZ!d	Z"d=Z#dZ$ej:                  d>ed8efd?„«       Z%d@edAedBedCed8ef
dD„Z&d7edEedFedGee   dHeeeeef   f   d8eedz  eeef   fdI„Z' e«       fd7edJedKedLee   d8edz  f
dM„Z(d7edEedFedGee   dHeeeeef   f   d8edz  fdN„Z)ej:                  dGee   d8eeef   fdO„«       Z*eZ+ej:                  dPed8ee   fdQ„«       Z,dEedFedLee   d8ee   dz  fdR„Z-dSe	dTeee.eedz  eef      f   dPedLee   dz  d8e/f
dU„Z0d7edGee   d8e	dz  fdV„Z1 e«       fd7edEedFedGee   dLee   d8edz  fdW„Z2ej:                  dEedFed8ee   fdX„«       Z3ej:                  dEedFedGee   d8eeeeef   f   fdY„«       Z4d7edEedFedGee   dZee   dz  d[ee   dz  d8edz  fd\„Z5d]edEedFed8eeef   dz  fd^„Z6d_Z7d`Z8daZ9dbZ:d7edce.e   d8e.e   fdd„Z;yc c}} w )ea  Confusion group resolution for similar single-byte encodings.

At runtime, loads pre-computed distinguishing byte maps from confusion.bin
and uses them to resolve statistical scoring ties between similar encodings.

Build-time computation (``compute_confusion_groups``, ``compute_distinguishing_maps``,
``serialize_confusion_data``) lives in ``scripts/confusion_training.py``.

Note: ``from __future__ import annotations`` is intentionally omitted because
this module is compiled with mypyc, which does not support PEP 563 string
annotations.
é    N)ÚART_LANGUAGEÚBigramProfileÚget_enc_indexÚget_idf_weightsÚscore_with_profile)ÚDetectionResult)Úlookup_encodingÚLué   ÚLlé   ÚLté   ÚLmé   ÚLoé   ÚMné   ÚMcé   ÚMeé   ÚNdé	   ÚNlé
   ÚNoé   ÚPcé   ÚPdé   ÚPsé   ÚPeé   ÚPié   ÚPfÚPoÚSmÚScÚSkÚSoÚZsÚZlÚZpÚCcÚCfÚCsÚCoÚCn)é   é   é   é   é   é   é   é   é   é   é   é   é   Ú_INT_TO_CATEGORYÚCATEGORY_TO_INTÚdataÚreturnc                 óž  — i }d}t        j                  d| |«      \  }|dz  }t        |«      D �]  }t        j                  d| |«      \  }|dz  }| |||z    j                  d«      }||z  }t        j                  d| |«      \  }|dz  }| |||z    j                  d«      }||z  }t        j                  d| |«      \  }	|dz  }g }
i }t        |	«      D ]b  }t        j                  d| |«      \  }}}|dz  }|
j	                  |«       t
        j                  |d	«      t
        j                  |d	«      f||<   Œd t        |
«      |f|||f<   �Œ |S )
z¿Load confusion group data from raw bytes.

    :param data: The raw binary content of a confusion.bin file.
    :returns: A :data:`DistinguishingMaps` dictionary keyed by encoding pairs.
    r   z!Hr   z!Br   zutf-8z!BBBr   r7   )ÚstructÚunpack_fromÚrangeÚdecodeÚappendrE   ÚgetÚ	frozenset)rG   ÚresultÚoffsetÚ	num_pairsÚ_Ú
name_a_lenÚname_aÚ
name_b_lenÚname_bÚ	num_diffsÚdiff_bytes_listÚ
categoriesÚbvÚ	cat_a_intÚ	cat_b_ints                  ú\/var/www/html/metafoliadorv2/venv/lib/python3.12/site-packages/chardet/pipeline/confusion.pyÚ%deserialize_confusion_data_from_bytesr`   N   s‰  € ð "$€FØ€FÜ×%Ñ% d¨D°&Ó9�L€YØ
ˆa�K€Fä�9Óó LˆÜ×*Ñ*¨4°°vÓ>‰ˆØ�!‰ˆØ�f˜v¨
Ñ2Ð3×:Ñ:¸7ÓCˆØ�*Ñˆä×*Ñ*¨4°°vÓ>‰ˆØ�!‰ˆØ�f˜v¨
Ñ2Ð3×:Ñ:¸7ÓCˆØ�*Ñˆä×)Ñ)¨$°°fÓ=‰ˆØ�!‰ˆà%'ˆØ13ˆ
Ü�yÓ!ò 	ˆAÜ'-×'9Ñ'9¸&À$ÈÓ'OÑ$ˆB�	˜9Ø�a‰KˆFØ×"Ñ" 2Ô&ä ×$Ñ$ Y°Ó5Ü ×$Ñ$ Y°Ó5ðˆJ�rŠNð		ô %.¨oÓ$>À
Ð#Kˆ�˜ÐÓ ð1Lð4 €Mó    c                  óÂ  — t         j                  j                  d«      j                  d«      } | j	                  «       }|st        j                  dt        d¬«       i S 	 t        |«      }i }|j                  «       D ]-  \  \  }}}t        |«      xs |}	t        |«      xs |}
|||	|
f<   Œ/ |S # t        j                  t        f$ r}d|› �}t        |«      |‚d}~ww xY w)z“Load confusion group data from the bundled confusion.bin file.

    :returns: A :data:`DistinguishingMaps` dictionary keyed by encoding pairs.
    zchardet.modelszconfusion.binuZ   chardet confusion.bin is empty â€” confusion resolution disabled; reinstall chardet to fixr   )Ú
stacklevelzcorrupt confusion.bin: N)Ú	importlibÚ	resourcesÚfilesÚjoinpathÚ
read_bytesÚwarningsÚwarnÚRuntimeWarningr`   rJ   ÚerrorÚUnicodeDecodeErrorÚ
ValueErrorÚitemsr	   )ÚrefÚrawÚraw_mapsÚeÚmsgÚ
normalizedÚaÚbÚvalueÚnorm_aÚnorm_bs              r_   Úload_confusion_datar{   v   sð   € ô ×
Ñ
×
#Ñ
#Ð$4Ó
5×
>Ñ
>¸Ó
O€CØ
�.‰.Ó
€CÙÜ�‰ð'äØõ		
ð ˆ	ð%Ü8¸Ó=ˆð
 &(€JØ!Ÿ™Ó)ò -‰‰ˆˆA�Ü  Ó#Ò( qˆÜ  Ó#Ò( qˆØ',ˆ
�F˜FÐ#Ò$ð-ð Ðøô �L‰LÔ,Ð-ò %Ø'¨ sÐ+ˆÜ˜‹o 1Ð$ûð%ús   Á B/ Â/CÃCÃC)r.   r/   r0   r1   r2   r4   r3   r6   r5   r7   r   r   r   Ú_CATEGORY_PREFERENCEé   Úencodingc                 ó&  — t        d«      }t        d«      D ]_  }	 t        |g«      j                  | «      }t        |«      dk7  rŒ.t        j                  |«      }|dk(  rd||<   ŒN|d   dk(  s|dv sŒ[d||<   Œa t        |«      S # t        $ r Y Œxw xY w)u£  256-entry table: 0 = non-letter, 1 = uppercase letter, 2 = other letter.

    Combining marks count as letters: in decomposed text (Vietnamese under
    windows-1258) a base letter's neighbor is its diacritic, which is
    word-internal, not a word boundary.  Whitespace deliberately counts as
    a plain non-letter: exempting space-adjacent letters from the
    isolated-letter demotion (to spare one-letter words like French ``Ã ``)
    was tried and falsified by the accuracy suite â€” Irish/Finnish po files
    and the EBCDIC record set depend on space-adjacent demotions, so the
    cross-family decisive-override gate handles the ``Ã `` failure mode
    instead.
    r}   r   r
   r   ÚL)r   r   r   )Ú	bytearrayrL   ÚbytesrM   rm   ÚlenÚunicodedataÚcategory)r~   Útablerw   ÚchÚcats        r_   Ú_letter_case_tabler‰   ×   s¦   € ô �c‹N€EÜ�3‹Zò ˆð	Ü˜�s“×"Ñ" 8Ó,ˆBô ˆr‹7�aŠ<ØÜ×"Ñ" 2Ó&ˆØ�$Š;ØˆE�!ŠHØ�‰V�sŠ]˜c \Ò1ØˆE�!ŠHðô �‹<Ðøô "ò 	Ùð	ús   ›BÂ	BÂBrˆ   ÚleftÚrightÚ
case_tablec                 óš   — t         j                  | d«      }| d   dk7  r|S ||   }||   }|dk(  r|dk(  rt        S | dk(  r|dk(  rt        S |S )a¤  Preference for reading a byte as *cat*, adjusted for word shape.

    A letter reading only deserves its high preference when its neighbors
    make it look like part of a word under the same encoding: a letter with
    no letter neighbors is quoted/isolated punctuation in disguise, and a
    lowercase letter immediately followed by an uppercase one is not a word
    shape any of the supported languages produce.
    r   r€   r   r   )r|   rO   Ú_IMPLAUSIBLE_LETTER_PREFERENCE)rˆ   rŠ   r‹   rŒ   ÚprefÚ	left_kindÚ
right_kinds          r_   Ú_context_preferencer’   ø   se   € ô  ×#Ñ# C¨Ó+€DØ
ˆ1�v�‚}ØˆØ˜4Ñ €IØ˜EÑ"€JØ�A‚~˜*¨š/Ü-Ð-Ø
ˆd‚{�z Q’Ü-Ð-Ø€Kra   Úenc_aÚenc_bÚ
diff_bytesr[   c                 ó0  — t        |«      \  }}t        | j                  d|«      «      }|syt        |«      }t        |«      }	d}
d}d}d}d}d}t	        | «      dz
  }|D �]  }||   \  }}t        |f«      }| j                  |«      }d}|dk\  sŒ1|t        k  sŒ;|dkD  r| |dz
     nd}||k  r| |dz      nd}t        ||||«      }t        ||||	«      }||kD  r8|d   dk(  r	|d   dk(  rnc|
||z
  z  }
|d   dk(  rS|t        k(  rJ|||z
  z  }|dz  }n<||kD  r7|d   dk(  r	|d   dk(  rn&|||z
  z  }|d   dk(  r|t        k(  r|||z
  z  }|dz  }|dz  }| j                  ||dz   «      }|dk\  s�Œ|t        k  rŒÞ�Œ |
|kD  r	||
|z
  ||fS ||
kD  r	|||
z
  ||fS y)uS  Context-aware category voting.

    Returns ``(winner, margin, demotion_margin, demotion_events)``.

    For each occurrence of a distinguishing byte, compare the two
    encodings' readings: Unicode category preference, adjusted for word
    shape (see :func:`_context_preference`).  The reading that makes more
    linguistic sense of the byte *in its context* collects the vote;
    occurrences vote independently, so repeated evidence counts.

    ``demotion_margin`` counts only the winner's votes earned where the
    *losing* side's letter reading was word-shape-implausible â€” evidence
    against an impossible reading, which is far stronger than the naive
    letters-beat-symbols preference.  ``demotion_events`` counts how many
    distinct occurrences contributed to it, so callers can tell repeated
    evidence from one loud byte.
    N)Nr   r   r   r   r   r€   ÚP)
Ú_pair_byte_tablesrP   Ú	translater‰   rƒ   r‚   ÚfindÚ_MAX_VOTE_OCCURRENCESr’   rŽ   )rG   r“   r”   r•   r[   Únon_diffrT   ÚrelevantÚtable_aÚtable_bÚvotes_aÚvotes_bÚ
demotion_aÚ
demotion_bÚevents_aÚevents_bÚendr\   Úcat_aÚcat_bÚneedleÚposÚexaminedrŠ   r‹   Úpref_aÚpref_bs                              r_   Ú_vote_with_marginr®     s  € ô8 $ JÓ/�K€HˆaÜ˜Ÿ™¨¨hÓ7Ó8€HÙØÜ  Ó'€GÜ  Ó'€GØ€GØ€GØ€JØ€JØ€HØ€HÜ
ˆd‹)�a‰-€CØó "-ˆØ! "‘~‰ˆˆuÜ˜�u“ˆØ�i‰i˜ÓˆØˆØ�Q‹h˜8Ô&;Ó;Ø$'¨!¢G�4˜˜a™’=°ˆDØ%(¨3¢Y�D˜˜q™’M°AˆEÜ(¨°°e¸WÓEˆFÜ(¨°°e¸WÓEˆFð ˜ŠØ˜‘8˜s’? u¨Q¡x°3¢Øà˜v¨™Ñ.�GØ˜Q‘x 3’¨6Ô5SÒ+SØ" f¨v¡oÑ5˜
Ø  A™™Ø˜&’Ø˜‘8˜s’? u¨Q¡x°3¢Øà˜v¨™Ñ.�GØ˜Q‘x 3’¨6Ô5SÒ+SØ" f¨v¡oÑ5˜
Ø  A™˜Ø˜‰MˆHØ—)‘)˜F C¨!¡GÓ,ˆCð; �QŒh˜8Ô&;Õ;ð"-ðF �ÒØ�g Ñ'¨°XÐ=Ð=Ø�ÒØ�g Ñ'¨°XÐ=Ð=Øra   Úenc_xÚenc_yÚ	languagesc                 ó*  — t        «       }t        |||«      }|€y||   \  }}|\  }}	t        | ||	||«      \  }
}}}|
�&|t        k\  r|t        k\  rt        |«      t        k  r|
S t        | ||	||«      }t        |«      t        k\  r
|�||
k(  r|S y|�|S |
S )u  Return the byte-evidence winner between two encodings, or ``None``.

    Mirrors the in-band pairwise rule of :func:`resolve_confusion_groups`
    (decisive demotion vote, else bigram rescore, else category vote) for
    callers outside the ranked-results scan â€” e.g. the classic-Mac
    line-ending promotion, whose platform prior must not override
    distinguishing-byte evidence.  Returns ``None`` when the pair has no
    distinguishing map or the evidence is inconclusive.

    *languages* must carry what the two results being compared report, or
    the mirror breaks: the rescore would arbitrate the same pair under a
    different rule than the confusion stage just did, and a veto built on
    that answer can reverse a promotion the stage had settled.
    N)r{   Ú_find_pair_keyr®   Ú_DECISIVE_VOTE_MARGINÚ_DECISIVE_MIN_EVENTSrƒ   Ú_CROSS_FAMILY_MIN_DIFFSÚresolve_by_bigram_rescore)rG   r¯   r°   r±   ÚmapsÚpair_keyr•   r[   r“   r”   Ú
cat_winnerÚ_marginÚdemotion_marginÚdemotion_eventsÚbigram_winners                  r_   Úconfusion_pair_winnerr¿   `  sÌ   € ô( Ó €DÜ˜d E¨5Ó1€HØÐØØ! (™^Ñ€J�
Ø�L€Eˆ5Ü<MØˆe�U˜J¨
ó=Ñ9€J�˜¨/ð 	ÐØÔ4Ò4ØÔ3Ò3Ü�
‹OÔ5Ò5àÐÜ-¨d°E¸5À*ÈiÓX€MÜ
ˆ:ƒÔ1Ò1ð Ð$¨¸*Ò)DØ Ð ØØ)Ð5ˆ=ÐE¸:ÐEra   c                 ó.   — t        | ||||«      \  }}}}|S )z†Resolve between two encodings using context-aware category voting.

    :returns: The winning encoding name, or ``None`` if tied.
    )r®   )	rG   r“   r”   r•   r[   Úwinnerr»   Ú	_demotionÚ_eventss	            r_   Úresolve_by_category_votingrÄ   Ž  s)   € ô +<Øˆe�U˜J¨
ó+Ñ'€FˆG�Y ð €Mra   c                 ó†   ‡— t        d«      Š| D ]  }d‰|<   Œ	 t        ˆfd„t        d«      D «       «      }|t        ‰«      fS )a­  Return ``(non_diff_delete, membership)`` byte tables for a pair.

    ``non_diff_delete`` holds every byte value *not* in *diff_bytes* (for
    ``bytes.translate`` deletion) and ``membership`` is a 256-entry table
    with 1 at each distinguishing byte (native indexing under mypyc, where
    frozenset probes are boxed).  Cached because *diff_bytes* comes from
    the fixed per-pair confusion maps loaded once per process.
    r}   r   c              3   ó.   •K  — | ]  }‰|   rŒ	|–— Œ y ­w©N© )Ú.0rw   Úmembers     €r_   ú	<genexpr>z$_pair_byte_tables.<locals>.<genexpr>¬  s   øè ø€ Ò<˜1°&¸³)”QÑ<ùs   ƒ
Ž)r�   r‚   rL   )r•   rw   rœ   rÊ   s      @r_   r˜   r˜   Ÿ  sI   ø€ ô �s‹^€FØò ˆØˆˆqŠ	ðäÓ<¤ c£
Ô<Ó<€HØ”U˜6“]Ð"Ð"ra   Úencc                 óV   — t        d„ t        «       j                  | g «      D «       «      S )z'Languages *enc* has a bigram model for.c              3   ó.   K  — | ]  \  }}}|€Œ
|–— Œ y ­wrÇ   rÈ   )rÉ   ÚlangrT   s      r_   rË   z&_modelled_languages.<locals>.<genexpr>¹  s    è ø€ ò Ù��q˜!¸tÑ?OŒñùs   ‚Ž)rP   r   rO   )rÌ   s    r_   Ú_modelled_languagesrÐ   ¶  s-   € ô ñ Ü,›×2Ñ2°3¸Ó;ôó ð ra   c                 ó‚   — |syt        | «      }t        |«      }||z  }||k  syt        |v st        |v r
|t        hz  S |S )u�  Languages to score *enc_a* and *enc_b* under, or ``None`` for all.

    ``None`` means *unrestricted* â€” score every variant, the original
    max-over-models comparison.  It is not an abstention.

    An encoding should not win on language coverage the other side lacks.
    On a Hungarian document the u-double-acute bytes score 0.014 against
    iso8859-2's *Czech* model (which reads them as a common r-hacek) and
    only 0.006 against iso8859-16's Hungarian one, so max-over-variants
    hands Hungarian text to the Czech reading.  Dropping the languages
    only one side models removes that particular unfairness.

    This is deliberately a narrow rule, and two tempting generalisations
    were measured and rejected against the accuracy suite:

    * Restricting to *languages* themselves rather than the shared set
      costs 12 tests.  As a consequence the restriction is a no-op for
      pairs whose language coverage already matches (67 of the 236
      confusion pairs), which is accepted â€” those pairs have no coverage
      asymmetry to correct in the first place.
    * Restricting when *languages* is not wholly inside the shared set
      costs 6 tests: cp1125 models only Ukrainian, so a Belarusian cp866
      document shares just ``uk`` with it, and scoring the *right*
      encoding under the *wrong* language loses to cp1125.  Falling back
      to unrestricted is also what keeps a Vietnamese windows-1258
      document, whose rival cp1252 models no Vietnamese, resolving
      correctly.  The cost is that pairs modelling disjoint languages
      (koi8-r/koi8-u, mac-roman/mac-turkish) never restrict at all â€”
      about 20% of calls over the corpus.
    N)rÐ   Ú_ART_LANGUAGE)r“   r”   r±   Úlangs_aÚlangs_bÚshareds         r_   Ú_comparable_languagesrÖ   ¾  sW   € ñF ØÜ! %Ó(€GÜ! %Ó(€GØ�wÑ€FØ˜ÒØô ˜Ñ¤=°GÑ#;Øœ˜Ñ'Ð'Ø€Mra   ÚprofileÚindexc                 ó\   ‡ ‡— |j                  |«      }|syt        ˆˆ fd„|D «       d¬«      S )aŠ  Return the best bigram score for *enc*, restricted to *languages*.

    *languages* of ``None`` means every variant, the unrestricted
    max-over-models comparison.  The ``default`` guards a caller-supplied
    set that names no variant of *enc*; note that scoring 0.0 hands the
    comparison to the rival rather than abstaining, so callers wanting an
    abstention must not rely on it.
    g        c              3   óL   •K  — | ]  \  }}}‰�|‰v rt        ‰||«      –— Œ y ­wrÇ   )r   )rÉ   rÏ   ÚmodelÚ	model_keyr±   r×   s       €€r_   rË   z&_best_variant_score.<locals>.<genexpr>  s5   øè ø€ ò 	
á&��e˜YØÐ  D¨IÑ$5ô ˜w¨¨y×9ñ	
ùs   ƒ!$)Údefault)rO   Úmax)r×   rØ   rÌ   r±   Úvariantss   `  ` r_   Ú_best_variant_scorerà   ó  s7   ù€ ð �y‰y˜‹~€HÙØÜô	
à*2ô	
ð
 ôð ra   c                 ó.  — t        | «      dk  ryt        |«      \  }}t        | j                  d|«      «      }|syt        «       }i }t        | «      dz
  }|t        z  t        | «      k  rÈt        «       }t        | j                  d|«      «      D ]l  }	t        |	f«      }
| j                  |
«      }|dk\  sŒ&|r|j                  |dz
  «       ||k  r|j                  |«       | j                  |
|dz   «      }|dk\  rŒGŒn |D ].  }| |   dz  | |dz      z  }|j                  |d«      ||   z   ||<   Œ0 nLt        |«      D ]>  }| |   }| |dz      }||   ||   z  sŒ|dz  |z  }|j                  |d«      ||   z   ||<   Œ@ |syt        j                  |«      S )a  Build the bigram profile of *data* restricted to *diff_bytes* context.

    The profile holds only bigrams where at least one byte is in
    *diff_bytes*, weighted by IDF like the full-input profile, so scoring a
    model against it asks how well that model explains the bytes two
    encodings read differently, and nothing else.  Returns ``None`` when
    *data* cannot form a bigram or contains no distinguishing byte.

    :param data: The raw byte data to examine.
    :param diff_bytes: Byte values where the two encodings differ.
    r   Nr   r   r   )rƒ   r˜   r™   r   Ú_DENSE_HIT_DIVISORÚsetrP   r‚   rš   ÚaddrO   rL   r   Úfrom_weighted_freq)rG   r•   rœ   Úis_diffÚhitsÚidfÚfreqÚlimitÚstartsr\   r©   rª   ÚiÚidxÚb1Úb2s                   r_   Úbuild_focused_profilerð     s½  € ô ˆ4ƒy�1‚}Øô *¨*Ó5Ñ€HˆgÜˆt�~‰~˜d HÓ-Ó.€DÙØä
Ó
€CØ€DÜ�‹I˜‰M€EØÔ Ñ ¤3 t£9Ò,ô ›5ˆÜ˜DŸN™N¨4°Ó:Ó;ò 	1ˆBÜ˜B˜5“\ˆFØ—)‘)˜FÓ#ˆCØ˜“(ÙØ—J‘J˜s Q™wÔ'Ø˜’;Ø—J‘J˜s”OØ—i‘i ¨¨a©Ó0�ð ˜”(ð	1ð ò 	4ˆAØ˜‘7˜a‘< 4¨¨A©¡;Ñ.ˆCØŸ™  aÓ(¨3¨s©8Ñ3ˆD�ŠIñ	4ô �u“ò 	4ˆAØ�a‘ˆBØ�a˜!‘e‘ˆBØ˜B‘K '¨"¡+Ò-ØØ˜‘7˜b‘.ˆCØŸ™  aÓ(¨3¨s©8Ñ3ˆD�ŠIð	4ñ Øä×+Ñ+¨DÓ1Ð1ra   c                 ó¤   — t        | |«      }|€yt        |||«      }t        «       }t        ||||«      }t        ||||«      }	||	kD  r|S |	|kD  r|S y)uþ  Resolve between two encodings by re-scoring only distinguishing bigrams.

    Builds a focused bigram profile containing only bigrams where at least one
    byte is a distinguishing byte, then scores both encodings under the
    languages they can be compared in (see :func:`_comparable_languages`).

    There is no abstention path here: when the pair has no comparable
    language the comparison widens to every variant rather than declining
    to answer.  That is why a Danish mac-roman/mac-turkish document, whose
    pair models disjoint languages, is still decided by the Turkish model
    the rescore has no business consulting â€” the caller's category vote is
    better placed on such evidence, and overriding this to abstain was
    measured as costing more accuracy than it recovers.

    :param data: The raw byte data to examine.
    :param enc_a: First encoding name.
    :param enc_b: Second encoding name.
    :param diff_bytes: Byte values where the two encodings differ.
    :param languages: Languages the ranked results report for this pair;
        empty when the caller has no ranking to draw on, which scores
        every variant.
    :returns: The winning encoding name, or ``None`` if tied or if no
        distinguishing byte occurs in *data*.
    N)rð   rÖ   r   rà   )
rG   r“   r”   r•   r±   r×   Ú
comparablerØ   Úbest_aÚbest_bs
             r_   r·   r·   R  sh   € ô> $ D¨*Ó5€GØ€Øä& u¨e°YÓ?€Jä‹O€EÜ  ¨%°¸
ÓC€FÜ  ¨%°¸
ÓC€Fà�‚ØˆØ�‚ØˆØra   c                 ó   — t        «       }t        dd«      D ]I  }t        |f«      }	 |j                  | «      }	 |j                  |«      }||k7  sŒ9|j                  |«       ŒK t        |«      S # t        $ r d}Y ŒCw xY w# t        $ r d}Y ŒBw xY w)aƒ  Byte values >= 0x80 that *enc_a* and *enc_b* decode to different text.

    The distinguishing set for a pair the confusion maps do not cover,
    computed from the codecs themselves.  A byte only one side can decode
    counts as differing.  Bytes below 0x80 are left out: the callers ask
    about high-byte evidence, and every single-byte Latin family agrees
    on ASCII anyway.
    é€   r}   N)rã   rL   r‚   rM   rm   rä   rP   )r“   r”   Úoutrw   rq   Útext_aÚtext_bs          r_   Údiffering_high_bytesrú   ‚  sž   € ô “E€CÜ�4˜Óò ˆÜ�Q�D‹kˆð	Ø!$§¡¨EÓ!2ˆFð	Ø!$§¡¨EÓ!2ˆFð �VÓØ�G‰G�A�Jðô �S‹>Ðøô "ò 	ØŠFð	ûô "ò 	ØŠFð	ús"   §A.¹A?Á.A<Á;A<Á?BÂBc                 ó(  — i }|D ]j  }g }| |fD ]R  }	 t        |g«      j                  |«      }|j                  t	        |«      dk(  rt        j                  |«      nd«       ŒT |d   |d   f||<   Œl |S # t        $ r |j                  d«       Y Œ‚w xY w)a›  Unicode general categories of each distinguishing byte under both encodings.

    The confusion maps carry this table for their own pairs; callers that
    arbitrate a pair the maps do not cover (the niche-Latin demotion's
    candidate against its swap target) build it here.  A byte one side
    cannot decode reads as unassigned (``Cn``), which the vote treats as
    the least plausible reading of all.
    r7   r   r   )r‚   rM   rm   rN   rƒ   r„   r…   )r“   r”   r•   r†   rw   ÚcatsrÌ   r‡   s           r_   Ú_pair_categoriesrý   œ  s±   € ð )+€EØò 	&ˆØˆØ˜5�>ò 	LˆCðÜ˜A˜3“Z×&Ñ& sÓ+�ð �K‰K´C¸³G¸q²Lœ×,Ñ,¨RÔ0ÀdÕKð	Lð ˜‘G˜T !™WÐ%ˆˆaŠð	&ð €Løô &ò Ø—‘˜DÔ!Ùðús   ’A4Á4BÂBÚlanguages_aÚlanguages_bc                óÈ   — t        | |«      }|�4t        «       }t        ||||«      }t        ||||«      }	||	kD  r|S |	|kD  r|S t        | |||t	        |||«      «      \  }
}}}|
S )aû  Decide a pair on its distinguishing bytes: model rescore, then context.

    The in-band rule of :func:`resolve_confusion_groups` for a pair the
    confusion maps do not cover, with one difference: each side is scored
    under the languages the caller names for it rather than the shared
    set.  The bigram rescore decides when the models have an opinion; when
    they score the distinguishing bigrams equally (usually both at zero,
    a byte neither model has seen in that context), the category vote
    reads word shape instead, so a letter between letters still beats a
    superscript between letters.  Returns ``None`` when neither step can
    tell the two apart.

    :param data: The raw byte data to examine.
    :param enc_a: First encoding name.
    :param enc_b: Second encoding name.
    :param diff_bytes: Byte values where the two encodings differ.
    :param languages_a: Variants of *enc_a* to score; ``None`` for all.
    :param languages_b: Variants of *enc_b* to score; ``None`` for all.
    )rð   r   rà   r®   rý   )rG   r“   r”   r•   rþ   rÿ   r×   rØ   ró   rô   rÁ   r»   rÂ   rÃ   s                 r_   Úarbitrate_distinguishing_bytesr  ¶  s„   € ô8 $ D¨*Ó5€GØÐÜ“ˆÜ$ W¨e°U¸KÓHˆÜ$ W¨e°U¸KÓHˆØ�FŠ?ØˆLØ�FŠ?ØˆLÜ*;Øˆe�U˜JÔ(8¸ÀÀzÓ(Ró+Ñ'€FˆG�Y ð €Mra   r¸   c                 ó,   — ||f| v r||fS ||f| v r||fS y)zEFind the canonical key for a pair of encodings in the confusion maps.NrÈ   )r¸   r“   r”   s      r_   r³   r³   á  s3   € ð 	ˆu€~˜ÑØ�uˆ~ÐØˆu€~˜ÑØ�uˆ~ÐØra   é4   g{®Gázt?g      à?gš™™™™™É?Úresultsc                 óè  — t        |«      dk  r|S |d   }|j                  €|S |j                  t        k(  r|S t	        «       }|j
                  }|t        z  }d}|}|j                  }t        dt        |«      «      D �]Œ  }	||	   }
|
j                  €Œ|	dk(  xs ||
j
                  z
  t        k  }|s|t        k\  s|
j
                  |k  r �n@t        |||
j                  «      }|€Œj||   \  }}|\  }}t        | ||||«      \  }}}}|�'|t        k\  r|t        k\  rt        |«      t        k  r|}n^t        d„ |j                  |
j                  fD «       «      }t!        | ||||«      }|rt        |«      t        k  r|�|n|}n|�||k(  r|}nd}|�||
j                  k7  r�Œ%|rVt#        |
j                  ||
j                  |
j$                  «      }t'        |«      D ��cg c]  \  }}||	k7  sŒ|‘Œ }}}|g|¢c S |	}|
}|
j                  }�Œ� |dk(  r|S t#        |j                  ||j                  |j$                  «      }t'        |«      D ��cg c]  \  }}||k7  sŒ|‘Œ }}}|g|¢S c c}}w c c}}w )a  Resolve confusion between similar encodings in the top results.

    Checks the top result against each candidate within a confidence band.
    Always checks position 1 (preserving original top-2 behavior); for
    positions 2+ only checks within the band.  Uses bigram re-scoring
    with category voting as fallback.

    :param data: The raw byte data to examine.
    :param results: Detection results sorted by confidence descending.
    :returns: A reordered list of :class:`DetectionResult` with the winner first.
    r   r   Nr   c              3   ó$   K  — | ]  }|�|–— Œ
 y ­wrÇ   rÈ   )rÉ   rÏ   s     r_   rË   z+resolve_confusion_groups.<locals>.<genexpr>q  s   è ø€ ò àØÐ#ô ñùs   ‚)rƒ   r~   ÚlanguagerÒ   r{   Ú
confidenceÚCONFUSION_FLOOR_RATIOrL   ÚCONFUSION_BANDÚSTRICT_TIER_MAX_CONFr³   r®   r´   rµ   r¶   rP   r·   r   Ú	mime_typeÚ	enumerate)rG   r  Útopr¸   Útop_confÚfloorÚchampion_idxÚchampionÚchampion_encrì   Ú	candidateÚin_bandr¹   r•   r[   r“   r”   rº   Ú_vote_marginr¼   r½   rÁ   Úlangsr¾   ÚpromotedÚjÚrÚrests                               r_   Úresolve_confusion_groupsr    sÜ  € ô ˆ7ƒ|�aÒØˆà
�!‰*€CØ
‡|�|ÐØˆð ‡|�|”}Ò$ØˆäÓ €DØ�~‰~€HØÔ,Ñ,€Eà€LØ€Hð
 —<‘<€LÜ�1”c˜'“lÓ#ó \*ˆØ˜A‘Jˆ	Ø×ÑÐ%Øð �q‘&ÒM˜H y×';Ñ';Ñ;¼~ÑMˆÙØÔ,Ò,°	×0DÑ0DÀuÒ0Lâä! $¨°i×6HÑ6HÓIˆØÐØà!% h¡Ñˆ
�JØ‰ˆˆuäEVØ�%˜ 
¨JóF
ÑBˆ
�L /°?ð( Ð"ØÔ#8Ò8ØÔ#7Ò7Ü�J“Ô"9Ò9à‰Fô
 ñ à%×.Ñ.°	×0BÑ0BÐCôó ˆEô
 6Ø�e˜U J°óˆMñ œ3˜z›?Ô-DÒDØ*7Ð*C™È‘ð
 Ð*¨}À
Ò/JØ&‘à�àˆ>˜V y×'9Ñ'9Ò9ÙÙô 'Ø×"Ñ"ØØ×"Ñ"Ø×#Ñ#ó	ˆHô #,¨GÓ"4×?™$˜!˜Q¸¸Q»’AÐ?ˆDÑ?ØÐ$˜tÐ$Ò$ð ˆØˆØ ×)Ñ)Šðy\*ð| �qÒØˆô Ø×ÑØØ×ÑØ×Ñó	€Hô $ GÓ,×B‘$�!�Q°°\Ó0AŠAÐB€DÑBØÐ�tÐÐùó5 @ùó2 Cs   ÇI(Ç,I(ÉI.ÉI.)<Ú__doc__Ú	functoolsÚimportlib.resourcesrd   rJ   r„   ri   Úchardet.modelsr   r   r   r   r   Úchardet.pipeliner   Úchardet.registryr	   ÚdictÚtupleÚstrrP   ÚintÚDistinguishingMapsrE   Ú__annotations__ro   rF   r‚   r`   Úcacher{   r|   rŽ   r´   rµ   r›   râ   r‰   r’   r®   r¿   rÄ   r˜   rÒ   rÐ   rÖ   ÚlistÚfloatrà   rð   r·   rú   rý   r  r³   r¶   r
  r	  r  r  )ÚkÚvs   00r_   ú<module>r.     sO  ðòó Û Û Û Û ÷õ õ -Ý ,ð Ø	ˆ#ˆsˆ(�OØ	ˆ)�C‰.˜$˜s E¨#¨s¨(¡OÐ3Ñ4Ð
4Ñ5ð7ñÐ ð$Ø€tð$à€tð$ð €tð$ð €tð	$ð
 €tð$ð €tð$ð €tð$ð €tð$ð €tð$ð €tð$ð ˆð$ð ˆð$ð ˆð$ð ˆð$ð ˆð$ð  ˆð!$ð" ˆð#$ð$ 	ØØØØØØØØØØØØò=$Ð �$�s˜C�x‘.ó ðH 5E×4JÑ4JÓ4L×"M©D¨A¨q 1 a¡4Ó"M€��c˜3�h‘Ó Mð%°ð %Ð:Ló %ðP ‡�ðÐ/ò ó ðð>(Øˆ"ð(àˆ"ð(ð 	ˆ"ð(ð 	ˆ!ð	(ð
 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð 	ˆ!ð(ð  	ˆ!ð!(ð" 	ˆ!ð#(ð$ Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
ò=(Ð �d˜3 ˜8‘nó ðH "#Ð ð Ð ð Ð ð Ð ð Ð ð ‡�ð ð ¨ò ó ðð@˜Sð ¨ð °Cð ÀUð Èsó ð*PØ
ðPàðPð ðPð ˜#‘ð	Pð
 �S˜%  S ™/Ð)Ñ*ðPð ˆ3�‰:�s˜C Ð$Ñ%óPñn !*£ñ	+FØ
ð+Fàð+Fð ð+Fð ˜‰~ð	+Fð
 	ˆ4�Zó+Fð\Ø
ðàðð ðð ˜#‘ð	ð
 �S˜%  S ™/Ð)Ñ*ðð 	ˆ4�Zóð" ‡�ð# )¨C¡.ð #°U¸5À%¸<Ñ5Hò #ó ð#ð& €ð ‡�ð˜Sð  Y¨s¡^ò ó ðð2Øð2àð2ð ˜‰~ð2ð ˆs�^�dÑó	2ðjØðà��T˜%  d¡
¨E°3Ð 6Ñ7Ñ8Ð8Ñ9ðð 
ðð ˜‰~ Ñ$ð	ð
 óð6A2Ø
ðA2Ø& s™^ðA2à�TÑóA2ñR !*£ñ-Ø
ð-àð-ð ð-ð ˜#‘ð	-ð
 ˜‰~ð-ð 	ˆ4�Zó-ð` ‡�ð ð ¨Cð °I¸c±Nò ó ðð2 ‡�ðØðØðØ(1°#©ðà	ˆ#ˆu�S˜#�X‰Ð
Ñòó ðð2(Ø
ð(àð(ð ð(ð ˜#‘ð	(ð ˜3‘ $Ñ&ð(ð ˜3‘ $Ñ&ð(ð 	ˆ4�Zó(ðV
Ø
ð
àð
ð ð
ð ˆ3�ˆ8�_�tÑó	
ð( Ð ð €ð Ð ð Ð ðWØ
ðWà�/Ñ"ðWð 
ˆ/ÑôWùóO #Ns   Â2L