+
    i4                        ^ RI Ht ^ RIHtHt ^ RIHt ^ RIHt  RR R llt	R R lt
RR	 R
 lltR t]R8X  d   ^ RIt]P                  ! 4        R# R# )    )annotations)MappingAny)	Container)KerningNestedc               (    V ^8  d   QhRRRRRRRR/# )	   kerningr   groupszdict[str, list[str]]glyphSetzContainer[str]returnzEtuple[KerningNested, dict[str, list[str]], dict[str, dict[str, str]]] )formats   "{/Users/tonyclaw/.openclaw/workspace/skills/math-calculator/venv/lib/python3.14/site-packages/fontTools/ufoLib/converters.py__annotate__r      s8     JY JYJY$8JYDRJYJJY    c                   \        V4      w  r4\        V P                  4       4       F  w  rVWQ9   d/   WR9  d)   VP                  R4      '       g   VP	                  V4       \        VP                  4       4       F=  pWq9   g   K  Wr9  g   K  VP                  R4      '       d   K,  VP	                  V4       K?  	  K  	  / pV Fd  p\        VP                  4       4      \        VP                  4       4      ,           p	VP                  RR4      p
RV
,           p
\        W4      p
WV&   Kf  	  / pV Fd  p\        VP                  4       4      \        VP                  4       4      ,           p	VP                  RR4      p
RV
,           p
\        W4      p
WV&   Kf  	  / p\        V P                  4       4       FS  w  rVVP                  WU4      p/ p\        VP                  4       4       F  w  r~VP                  Ww4      pWV&   K  	  WV&   KU  	  \        VP                  4       4      pV\        VP                  4       4      ,          pV F  w  pp
\        VV,          4      pVW&   K  	  W\        WR7      3# )ao  Convert kerning data in UFO1 or UFO2 syntax into UFO3 syntax.

Args:
  kerning:
      A dictionary containing the kerning rules defined in
      the UFO font, as used in :class:`.UFOReader` objects.
  groups:
      A dictionary containing the groups defined in the UFO
      font, as used in :class:`.UFOReader` objects.
  glyphSet:
    Optional; a set of glyph objects to skip (default: None).

Returns:
  1. A dictionary representing the converted kerning data.
  2. A copy of the groups dictionary, with all groups renamed to UFO3 syntax.
  3. A dictionary containing the mapping of old group names to new group names.

zpublic.kern1.zpublic.kern2.@MMK_L_ @MMK_R_)side1side2)
findKnownKerningGroupslistitems
startswithaddkeysreplacemakeUniqueGroupNamegetdict)r
   r   r   firstReferencedGroupssecondReferencedGroupsfirstsecondssecondfirstRenamedGroupsexistingGroupNamesnewNamesecondRenamedGroups
newKerning
newSecondsvalueallRenamedGroupsoldNamegroups   &&&               r   %convertUFO1OrUFO2KerningToUFO3Kerningr2      s,   , 5K64R1w}}/?u4##O44%))%07<<>*FF$:((99*..v6 +	 0 *,&!&++-048J8O8O8Q3RR--	2.!G+%gB$+5! ' +-(!&++-048K8P8P8R3SS..B/!G+%gB&-F# ) Jw}}/"&&u4
!'--/2MF(,,V<F!&v 3 '5 0 .4467066899,VG_% - t*<XXXr   c                    V ^8  d   QhRRRR/# )r	   r   zMapping[str, Any]r   ztuple[set[str], set[str]]r   )r   s   "r   r   r   `   s     ?% ?%#4 ?%9R ?%r   c                J   R.pR.p\        4       p\        4       p\        V P                  4       4       Fj  pV F-  pVP                  V4      '       g   K  VP	                  V4        M	  V F.  pVP                  V4      '       g   K  VP	                  V4        Kh  	  Kl  	  W43# )a  Find all kerning groups in a UFO1 or UFO2 font that use known prefixes.

In some cases, not all kerning groups will be referenced
by the kerning pairs in a UFO. The algorithm for locating
groups in :func:`convertUFO1OrUFO2KerningToUFO3Kerning` will
miss these unreferenced groups. By scanning for known prefixes,
this function will catch all of the prefixed groups.

The prefixes and sides by this function are:

@MMK_L_ - side 1
@MMK_R_ - side 2

as defined in the UFO1 specification.

Args:
    groups:
      A dictionary containing the groups defined in the UFO
      font, as read by :class:`.UFOReader`.

Returns:
    Two sets; the first containing the names of all
    first-side kerning groups identified in the ``groups``
    dictionary, and the second containing the names of all
    second-side kerning groups identified.

    "First-side" and "second-side" are with respect to the
    writing direction of the script.

    Example::

      >>> testGroups = {
      ...     "@MMK_L_1" : None,
      ...     "@MMK_L_2" : None,
      ...     "@MMK_L_3" : None,
      ...     "@MMK_R_1" : None,
      ...     "@MMK_R_2" : None,
      ...     "@MMK_R_3" : None,
      ...     "@MMK_l_1" : None,
      ...     "@MMK_r_1" : None,
      ...     "@MMK_X_1" : None,
      ...     "foo" : None,
      ... }
      >>> first, second = findKnownKerningGroups(testGroups)
      >>> sorted(first) == ['@MMK_L_1', '@MMK_L_2', '@MMK_L_3']
      True
      >>> sorted(second) == ['@MMK_R_1', '@MMK_R_2', '@MMK_R_3']
      True
r   r   )setr   r   r   r   )r   knownFirstGroupPrefixesknownSecondGroupPrefixesfirstGroupssecondGroups	groupNamefirstPrefixsecondPrefixs   &       r   r   r   `   s    d  )k ){%K5L&++-(	2K##K00	* 3 5L##L11  + 5 ) $$r   c               (    V ^8  d   QhRRRRRRRR/# )r	   namestr
groupNamesz	list[str]counterintr   r   )r   s   "r   r   r      s(      c y 3 s r   c                ^    T pV^ 8  d   RW23,          pW19   d   \        WV^,           4      # V# )a  Make a kerning group name that will be unique within the set of group names.

If the requested kerning group name already exists within the set, this
will return a new name by adding an incremented counter to the end
of the requested name.

Args:
    name:
      The requested kerning group name.
    groupNames:
      A list of the existing kerning group names.
    counter:
      Optional; a counter of group names already seen (default: 0). If
      :attr:`.counter` is not provided, the function will recurse,
      incrementing the value of :attr:`.counter` until it finds the
      first unused ``name+counter`` combination, and return that result.

Returns:
    A unique kerning group name composed of the requested name suffixed
    by the smallest available integer counter.
z%s%d)r    )r>   r@   rA   r*   s   &&& r   r    r       s9    . G{G--"4Wq[AANr   c                     R# )a2  
Tests for :func:`.convertUFO1OrUFO2KerningToUFO3Kerning`.

No known prefixes.

>>> testKerning = {
...     "A" : {
...         "A" : 1,
...         "B" : 2,
...         "CGroup" : 3,
...         "DGroup" : 4
...     },
...     "BGroup" : {
...         "A" : 5,
...         "B" : 6,
...         "CGroup" : 7,
...         "DGroup" : 8
...     },
...     "CGroup" : {
...         "A" : 9,
...         "B" : 10,
...         "CGroup" : 11,
...         "DGroup" : 12
...     },
... }
>>> testGroups = {
...     "BGroup" : ["B"],
...     "CGroup" : ["C"],
...     "DGroup" : ["D"],
... }
>>> kerning, groups, maps = convertUFO1OrUFO2KerningToUFO3Kerning(
...     testKerning, testGroups, [])
>>> expected = {
...     "A" : {
...         "A": 1,
...         "B": 2,
...         "public.kern2.CGroup": 3,
...         "public.kern2.DGroup": 4
...     },
...     "public.kern1.BGroup": {
...         "A": 5,
...         "B": 6,
...         "public.kern2.CGroup": 7,
...         "public.kern2.DGroup": 8
...     },
...     "public.kern1.CGroup": {
...         "A": 9,
...         "B": 10,
...         "public.kern2.CGroup": 11,
...         "public.kern2.DGroup": 12
...     }
... }
>>> kerning == expected
True
>>> expected = {
...     "BGroup": ["B"],
...     "CGroup": ["C"],
...     "DGroup": ["D"],
...     "public.kern1.BGroup": ["B"],
...     "public.kern1.CGroup": ["C"],
...     "public.kern2.CGroup": ["C"],
...     "public.kern2.DGroup": ["D"],
... }
>>> groups == expected
True

Known prefixes.

>>> testKerning = {
...     "A" : {
...         "A" : 1,
...         "B" : 2,
...         "@MMK_R_CGroup" : 3,
...         "@MMK_R_DGroup" : 4
...     },
...     "@MMK_L_BGroup" : {
...         "A" : 5,
...         "B" : 6,
...         "@MMK_R_CGroup" : 7,
...         "@MMK_R_DGroup" : 8
...     },
...     "@MMK_L_CGroup" : {
...         "A" : 9,
...         "B" : 10,
...         "@MMK_R_CGroup" : 11,
...         "@MMK_R_DGroup" : 12
...     },
... }
>>> testGroups = {
...     "@MMK_L_BGroup" : ["B"],
...     "@MMK_L_CGroup" : ["C"],
...     "@MMK_L_XGroup" : ["X"],
...     "@MMK_R_CGroup" : ["C"],
...     "@MMK_R_DGroup" : ["D"],
...     "@MMK_R_XGroup" : ["X"],
... }
>>> kerning, groups, maps = convertUFO1OrUFO2KerningToUFO3Kerning(
...     testKerning, testGroups, [])
>>> expected = {
...     "A" : {
...         "A": 1,
...         "B": 2,
...         "public.kern2.CGroup": 3,
...         "public.kern2.DGroup": 4
...     },
...     "public.kern1.BGroup": {
...         "A": 5,
...         "B": 6,
...         "public.kern2.CGroup": 7,
...         "public.kern2.DGroup": 8
...     },
...     "public.kern1.CGroup": {
...         "A": 9,
...         "B": 10,
...         "public.kern2.CGroup": 11,
...         "public.kern2.DGroup": 12
...     }
... }
>>> kerning == expected
True
>>> expected = {
...     "@MMK_L_BGroup": ["B"],
...     "@MMK_L_CGroup": ["C"],
...     "@MMK_L_XGroup": ["X"],
...     "@MMK_R_CGroup": ["C"],
...     "@MMK_R_DGroup": ["D"],
...     "@MMK_R_XGroup": ["X"],
...     "public.kern1.BGroup": ["B"],
...     "public.kern1.CGroup": ["C"],
...     "public.kern1.XGroup": ["X"],
...     "public.kern2.CGroup": ["C"],
...     "public.kern2.DGroup": ["D"],
...     "public.kern2.XGroup": ["X"],
... }
>>> groups == expected
True

>>> from .validators import kerningValidator
>>> kerningValidator(kerning)
(True, None)

Mixture of known prefixes and groups without prefixes.

>>> testKerning = {
...     "A" : {
...         "A" : 1,
...         "B" : 2,
...         "@MMK_R_CGroup" : 3,
...         "DGroup" : 4
...     },
...     "BGroup" : {
...         "A" : 5,
...         "B" : 6,
...         "@MMK_R_CGroup" : 7,
...         "DGroup" : 8
...     },
...     "@MMK_L_CGroup" : {
...         "A" : 9,
...         "B" : 10,
...         "@MMK_R_CGroup" : 11,
...         "DGroup" : 12
...     },
... }
>>> testGroups = {
...     "BGroup" : ["B"],
...     "@MMK_L_CGroup" : ["C"],
...     "@MMK_R_CGroup" : ["C"],
...     "DGroup" : ["D"],
... }
>>> kerning, groups, maps = convertUFO1OrUFO2KerningToUFO3Kerning(
...     testKerning, testGroups, [])
>>> expected = {
...     "A" : {
...         "A": 1,
...         "B": 2,
...         "public.kern2.CGroup": 3,
...         "public.kern2.DGroup": 4
...     },
...     "public.kern1.BGroup": {
...         "A": 5,
...         "B": 6,
...         "public.kern2.CGroup": 7,
...         "public.kern2.DGroup": 8
...     },
...     "public.kern1.CGroup": {
...         "A": 9,
...         "B": 10,
...         "public.kern2.CGroup": 11,
...         "public.kern2.DGroup": 12
...     }
... }
>>> kerning == expected
True
>>> expected = {
...     "BGroup": ["B"],
...     "@MMK_L_CGroup": ["C"],
...     "@MMK_R_CGroup": ["C"],
...     "DGroup": ["D"],
...     "public.kern1.BGroup": ["B"],
...     "public.kern1.CGroup": ["C"],
...     "public.kern2.CGroup": ["C"],
...     "public.kern2.DGroup": ["D"],
... }
>>> groups == expected
True
Nr   r   r   r   testrE      s    r   __main__N)r   )r   )
__future__r   typingr   r   collections.abcr   fontTools.annotationsr   r2   r   r    rE   __name__doctesttestmodr   r   r   <module>rN      sM    "  % /JYZ?%DBNb zOO r   