# Path: Lib/glyphsLib/builder/constants.py
# GLYPHLIB_PREFIX = GLYPHS_PREFIX + "Glyphs."
# 
# Path: Lib/glyphsLib/builder/glyph.py
# SCRIPT_LIB_KEY = GLYPHLIB_PREFIX + "script"
# ORIGINAL_WIDTH_KEY = GLYPHLIB_PREFIX + "originalWidth"
# BACKGROUND_WIDTH_KEY = GLYPHLIB_PREFIX + "backgroundWidth"
# def _clone_layer(layer, paths=None, components=None):
# def to_ufo_glyph(self, ufo_glyph, layer, glyph, do_color_layers=True):  # noqa: C901
# def to_glyphs_glyph(self, ufo_glyph, ufo_layer, master):  # noqa: C901
# def to_ufo_glyph_height_and_vertical_origin(self, ufo_glyph, layer):
# def _get_typo_ascender_descender(master):
# def to_ufo_glyph_background(self, glyph, layer):
# def _to_glyphs_color(color):
# def to_glyphs_glyph_height_and_vertical_origin(self, ufo_glyph, master, layer):


from collections import defaultdict
from glyphsLib import classes
from .constants import GLYPHLIB_PREFIX
from .glyph import BRACKET_GLYPH_RE
import os
import re
                    not glyph
                    or getattr(glyph, _glyph_kerning_attr(glyph, side)) == group_name
                ):
                    # The original grouping is still valid
                    groups[group].append(glyph_name)
                    # Remember not to add this glyph again later
                    # Thus the original position in the list is preserved
                    recovered.add((glyph_name, int(side)))

    # Read modified grouping values
    for glyph in self.font.glyphs.values():
        for side in 1, 2:
            if (glyph.name, side) not in recovered:
                attr = _glyph_kerning_attr(glyph, side)
                group = getattr(glyph, attr)
                if group:
                    group = f"public.kern{side}.{group}"
                    groups[group].append(glyph.name)

    # Update all UFOs with the same info
    for source in self._sources.values():
        for name, glyphs in groups.items():
            # Shallow copy to prevent unexpected object sharing
            source.font.groups[name] = glyphs[:]


def to_glyphs_groups(self):
    # Build the GSClasses from the groups of the first UFO.
    groups = []
    for source in self._sources.values():

# Path: Lib/glyphsLib/builder/constants.py
# GLYPHLIB_PREFIX = GLYPHS_PREFIX + "Glyphs."
# 
# Path: Lib/glyphsLib/builder/glyph.py
# SCRIPT_LIB_KEY = GLYPHLIB_PREFIX + "script"
# ORIGINAL_WIDTH_KEY = GLYPHLIB_PREFIX + "originalWidth"
# BACKGROUND_WIDTH_KEY = GLYPHLIB_PREFIX + "backgroundWidth"
# def _clone_layer(layer, paths=None, components=None):
# def to_ufo_glyph(self, ufo_glyph, layer, glyph, do_color_layers=True):  # noqa: C901
# def to_glyphs_glyph(self, ufo_glyph, ufo_layer, master):  # noqa: C901
# def to_ufo_glyph_height_and_vertical_origin(self, ufo_glyph, layer):
# def _get_typo_ascender_descender(master):
# def to_ufo_glyph_background(self, glyph, layer):
# def _to_glyphs_color(color):
# def to_glyphs_glyph_height_and_vertical_origin(self, ufo_glyph, master, layer):


# Path: Lib/glyphsLib/builder/groups.py
from collections import defaultdict
from glyphsLib import classes
from .constants import GLYPHLIB_PREFIX
from .glyph import BRACKET_GLYPH_RE
import os
import re

                    not glyph
                    or getattr(glyph, _glyph_kerning_attr(glyph, side)) == group_name
                ):
                    # The original grouping is still valid
                    groups[group].append(glyph_name)
                    # Remember not to add this glyph again later
                    # Thus the original position in the list is preserved
                    recovered.add((glyph_name, int(side)))

    # Read modified grouping values
    for glyph in self.font.glyphs.values():
        for side in 1, 2:
            if (glyph.name, side) not in recovered:
                attr = _glyph_kerning_attr(glyph, side)
                group = getattr(glyph, attr)
                if group:
                    group = f"public.kern{side}.{group}"
                    groups[group].append(glyph.name)

    # Update all UFOs with the same info
    for source in self._sources.values():
        for name, glyphs in groups.items():
            # Shallow copy to prevent unexpected object sharing
            source.font.groups[name] = glyphs[:]


def to_glyphs_groups(self):
    # Build the GSClasses from the groups of the first UFO.
    groups = []
    for source in self._sources.values():

        for name, glyphs in source.font.groups.items():