@yahoo/uds-create-cli 5.75.0 → 5.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70521,6 +70521,16 @@ var buildFields = external_exports.strictObject({
70521
70521
  title: "React version",
70522
70522
  description: `The React major the app this repo builds for runs. \`18\` wraps each emitted web component in \`forwardRef\`, so a call site's \`ref\` reaches its element. Unset, \`${BUILD_DEFAULTS.react}\`.`,
70523
70523
  default: BUILD_DEFAULTS.react
70524
+ }).optional(),
70525
+ /**
70526
+ * Whether the component modules `uds build` writes carry the component data attributes:
70527
+ * `data-uds-component`, `data-uds-layer` and `data-uds-slot`, which Create's tools read to map an
70528
+ * app's rendered markup back to its components. Unset, off; `uds build --debug` turns it on for
70529
+ * one build.
70530
+ */
70531
+ debug: external_exports.boolean().meta({
70532
+ title: "Debug",
70533
+ description: "Have `uds build` write the component data attributes (`data-uds-component`, `data-uds-layer`, `data-uds-slot`) on the elements components render. Create's tools read them to map the app's rendered markup back to its components, such as the canvas capture rebuilding a page as components. Unset, off; `uds build --debug` turns it on for one build."
70524
70534
  }).optional()
70525
70535
  }, { error: (issue2) => issue2.code === "unrecognized_keys" && issue2.keys.includes("include") ? "`settings.build.include` was removed: every source file under `inputDir` now ships by default. Delete it, and list any file to keep out in `settings.build.exclude`." : void 0 });
70526
70536
 
@@ -82258,6 +82268,10 @@ function classLeaf(leaf) {
82258
82268
  const spaced = leaf.replace(/\s+/g, "-");
82259
82269
  return /^\d+\/\d+$/.test(spaced) ? spaced : spaced.replaceAll("/", "-");
82260
82270
  }
82271
+ function arbitraryClassName({ config: config2, path: path2, value }) {
82272
+ const inner = value.slice(1, -1).replace(/\s+/g, "_");
82273
+ return `${stylePropClassBase(config2, path2)}-[${inner}]`;
82274
+ }
82261
82275
  function stylePropClasses(config2, path2) {
82262
82276
  const out = /* @__PURE__ */ new Map();
82263
82277
  for (const leaf of stylePropValueLeaves(config2, path2)) if (!out.has(leaf)) out.set(leaf, stylePropClassName(config2, path2, leaf));
@@ -86386,7 +86400,7 @@ var ComponentEntity = defineEntity({
86386
86400
  input: external_exports.object({ path: pathInput("component") }),
86387
86401
  readOnly: false,
86388
86402
  label: "Create blank",
86389
- description: 'Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Studio\'s "+" creates. Takes only `path`. Use it for "a new component", "a blank component" or "start a component from nothing"; `create` is for a component whose body is already known.',
86403
+ description: 'Create an empty component at a new qualified `path`, to design on the canvas first: one `div` root layer and the node that renders it, with no props, no variants, no slot, no styles and no preview content. This is exactly what Create\'s "+" creates. Takes only `path`. Use it for "a new component", "a blank component" or "start a component from nothing"; `create` is for a component whose body is already known.',
86390
86404
  scope: "item",
86391
86405
  creates: true,
86392
86406
  title: (entity) => `Create blank ${entity}`,
@@ -86405,7 +86419,7 @@ var ComponentEntity = defineEntity({
86405
86419
  example: ({ config: config2 }) => forwardsCreateExample(config2)
86406
86420
  },
86407
86421
  "sub-upsert/forwards": { description: `Set what one layer forwards, added when absent and replaced whole when present. ${FORWARDS_DESCRIPTION}` },
86408
- "sub-update/forwards": { description: `Replace what one layer forwards: the member is \`'*'\` or a list, so \`data\` is the whole new value. ${FORWARDS_DESCRIPTION}` },
86422
+ "sub-update/forwards": { description: `Replace what one layer forwards: the member is a list of prop names, so \`data\` is the whole new list. ${FORWARDS_DESCRIPTION}` },
86409
86423
  /**
86410
86424
  * Add an element to a composition — a layer and the node that targets it, together.
86411
86425
  *
@@ -86704,7 +86718,7 @@ var ComponentEntity = defineEntity({
86704
86718
  }),
86705
86719
  readOnly: false,
86706
86720
  label: "Forward layer props",
86707
- description: 'Expose a layer\'s props at the component\'s top level ("forward everything from the root but icon", "also forward width"): `props` is `"*"` for every prop the layer\'s element takes, or a list added to what the layer forwards now, or that replaces it with `replace`; `except` leaves props out of either. A prop the element lacks, one the component declares itself, and one a sibling layer already forwards are refused. Read `component/get` for what a layer forwards now.',
86721
+ description: 'Expose a layer\'s props at the component\'s top level ("also forward width", "forward onClick from the root"): `props` is a list of prop names, added to what the layer forwards now, or replacing it with `replace`. A prop the element lacks, one the component declares itself, and one a sibling layer already forwards are refused. Read `component/get` for what a layer forwards now.',
86708
86722
  scope: "item",
86709
86723
  title: (entity) => `Forward ${entity} layer props`,
86710
86724
  handler: (input2, config2) => {
@@ -87657,6 +87671,200 @@ function renderBoundProp(value) {
87657
87671
  return name.length > 0 && !name.includes("/") ? name : void 0;
87658
87672
  }
87659
87673
 
87674
+ // ../config/dist/entities/system/Icon.js
87675
+ var iconVariantAs = external_exports.union([external_exports.strictObject({ prop: external_exports.string().min(1) }), external_exports.strictObject({ export: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)) })]);
87676
+ var Icon = defineEntity({
87677
+ kind: "icon",
87678
+ label: "Icon",
87679
+ labelPlural: "Icons",
87680
+ fields: iconMemberMetadata,
87681
+ groupFields: external_exports.strictObject({
87682
+ /** The package the glyphs come from — a REF to the `Package` item, which owns the module
87683
+ * specifier (its path) and the pinned version. A generated module imports the glyphs it renders
87684
+ * from it, and a render that imports a member of it is placing a glyph of this set. */
87685
+ package: Package.optional().describe("The npm package the set comes from."),
87686
+ /** Where member metadata comes from and how to read it — `{ from, format }`. The build resolves
87687
+ * the source and bakes each member's fields; see `icon-metadata.ts`. */
87688
+ metadata: iconMetadataDeclaration.optional().describe("Catalogue metadata read from the package."),
87689
+ /** Named sizes the set ships (`sm: 16`).
87690
+ * @deprecated How a glyph is sized is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
87691
+ sizes: external_exports.record(external_exports.string(), external_exports.number()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
87692
+ /** Weights/styles the set ships (`regular`, `fill`).
87693
+ * @deprecated Which styles a glyph takes is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
87694
+ variants: external_exports.array(external_exports.string()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
87695
+ /** How a variant reaches the glyph; see {@link iconVariantAs}. Absent, a variant is dropped at
87696
+ * render.
87697
+ * @deprecated Only the framework's raw-draw path read it; the icon tool's component passes a
87698
+ * variant the way its package wants, and a set whose styles are separate exports lists them as
87699
+ * members. TODO: remove with `sizes` and `variants`. */
87700
+ variantAs: iconVariantAs.optional().describe("Deprecated. The icon tool's component passes a variant the way its package wants.")
87701
+ }),
87702
+ groupComputed: {
87703
+ /** The glyphs the set ships, by leaf name. */
87704
+ members: ({ config: config2, path: path2 }) => config2.members("icon", path2).map((member) => member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path),
87705
+ /** The module the glyphs import from: the named package's path. `pathOf` drops a source
87706
+ * qualifier, so a borrowed set's module is still the bare specifier. */
87707
+ module: ({ meta: meta3 }) => isRef2(meta3.package) ? pathOf2(meta3.package) : void 0,
87708
+ /** The version the named package pins, resolved through the ref in whichever config holds the
87709
+ * package row. */
87710
+ version: ({ config: config2, meta: meta3 }) => {
87711
+ if (!isRef2(meta3.package)) return void 0;
87712
+ const pinned = config2.resolveRef(meta3.package)?.toJSON();
87713
+ return typeof pinned?.version === "string" ? pinned.version : void 0;
87714
+ }
87715
+ },
87716
+ groupInputs: {
87717
+ /**
87718
+ * The package's module namespace. The set's members are its glyph exports, named by the rule
87719
+ * the metadata format declares (`glyphExportRule`), so an alias pair is one member and the
87720
+ * package's infrastructure exports are none; `items` lays facts over members that exist, and a
87721
+ * key naming no member is refused so a typo cannot invent a glyph. Each member's identity is
87722
+ * recorded by reference, so an authored glyph (`name={StarIcon}`) is matched to its member by
87723
+ * the object rather than by anything the component says about itself, and an alias resolves to
87724
+ * the member it is. Read once while the config file is evaluated and never stored.
87725
+ */
87726
+ glyphs: ({ input: input2, body }) => {
87727
+ if (!isRef2(body.package)) throw new Error("Icon.group: `glyphs` needs `package` on the same group, since a glyph is identified as an export of that module.");
87728
+ const format = iconMetadataFormat.safeParse(body.metadata?.format);
87729
+ const members2 = glyphMembersOf({
87730
+ namespace: input2,
87731
+ format: format.success ? format.data : void 0
87732
+ });
87733
+ const overlay = body.items ?? {};
87734
+ const unknown2 = Object.keys(overlay).filter((name) => !members2.includes(name));
87735
+ if (unknown2.length > 0) throw new Error(`Icon.group: \`items\` names ${spellValues(unknown2)}, which ${unknown2.length === 1 ? "is not a glyph export" : "are not glyph exports"} of \`glyphs\`${members2.length === 0 ? " (the namespace has no glyph components; the package may not be installed)" : ""}. \`items\` lays facts over the members the package exports; it cannot add one.`);
87736
+ recordGlyphIdentities({
87737
+ namespace: input2,
87738
+ names: members2,
87739
+ specifier: pathOf2(body.package)
87740
+ });
87741
+ return { items: Object.fromEntries(members2.map((name) => [name, overlay[name] ?? {}])) };
87742
+ }
87743
+ },
87744
+ /**
87745
+ * A value bound to a library may be the glyph component itself, or the `package:` export ref the
87746
+ * open-bag pass turned it into. Either is answered as the member name when the export is one of
87747
+ * this library's and comes from the module its `package` names.
87748
+ */
87749
+ authoredValue: ({ config: config2, target: target2, leaves: leaves2 }) => glyphOfLibrary(libraryGlyphFacts({
87750
+ config: config2,
87751
+ target: target2,
87752
+ leaves: leaves2
87753
+ })),
87754
+ invariants: (config2) => iconDomainInvariants(config2)
87755
+ });
87756
+
87757
+ // ../config/dist/entities/system/icon-library.js
87758
+ var EMPTY_CATEGORIES = Object.freeze([]);
87759
+ var EMPTY_SIZES = Object.freeze({});
87760
+ var EMPTY_VARIANTS = Object.freeze([]);
87761
+ var NO_LIBRARIES = [];
87762
+ function iconLibrary(config2, path2) {
87763
+ if (!config2) return void 0;
87764
+ const cache = librariesOf(config2);
87765
+ if (cache.has(path2)) return cache.get(path2);
87766
+ const library = readIconLibrary(config2, path2);
87767
+ cache.set(path2, library);
87768
+ return library;
87769
+ }
87770
+ var librariesOf = createSliceMemo({
87771
+ kinds: [
87772
+ "icon",
87773
+ "component",
87774
+ "package"
87775
+ ],
87776
+ compute: (_config) => /* @__PURE__ */ new Map()
87777
+ });
87778
+ function readIconLibrary(config2, path2) {
87779
+ const group = Icon.groups(config2).find((entry) => entry.path === path2);
87780
+ if (!group) return void 0;
87781
+ const { items: _items, sizes, variants: variants2, ...meta3 } = group.meta;
87782
+ const set2 = setMembers({
87783
+ config: config2,
87784
+ path: path2,
87785
+ declared: variants2
87786
+ });
87787
+ return {
87788
+ ...meta3,
87789
+ path: path2,
87790
+ members: set2.members,
87791
+ sizes: sizes ?? EMPTY_SIZES,
87792
+ variants: variants2 ?? EMPTY_VARIANTS,
87793
+ ...set2.memberVariants ? { memberVariants: set2.memberVariants } : {},
87794
+ ...componentDefaults({
87795
+ config: config2,
87796
+ library: path2
87797
+ })
87798
+ };
87799
+ }
87800
+ function componentDefaults({ config: config2, library }) {
87801
+ const bound = glyphComponentOf(config2, library);
87802
+ if (!bound) return {};
87803
+ const defaults = Component.get(config2, bound.path)?.defaultProps;
87804
+ const variant = defaults?.variant;
87805
+ const size = defaults?.size;
87806
+ return {
87807
+ ...typeof variant === "string" ? { defaultVariant: variant } : {},
87808
+ ...typeof size === "string" ? { defaultSizeKey: size } : {}
87809
+ };
87810
+ }
87811
+ var membersOf = createSliceMemo({
87812
+ kinds: ["icon"],
87813
+ compute: (_config) => /* @__PURE__ */ new Map()
87814
+ });
87815
+ function setMembers({ config: config2, path: path2, declared: declared2 }) {
87816
+ const walked = membersOf(config2);
87817
+ const hit = walked.get(path2);
87818
+ if (hit) return hit;
87819
+ const members2 = [];
87820
+ const memberVariants = {};
87821
+ for (const member of config2.members("icon", path2)) {
87822
+ const leaf = member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path;
87823
+ members2.push(leaf);
87824
+ const own2 = ownVariantsOf(member.body);
87825
+ if (own2 && own2.length > 0 && !sameVariants({
87826
+ own: own2,
87827
+ declared: declared2
87828
+ })) memberVariants[leaf] = own2;
87829
+ }
87830
+ const set2 = {
87831
+ members: members2,
87832
+ ...Object.keys(memberVariants).length > 0 ? { memberVariants } : {}
87833
+ };
87834
+ walked.set(path2, set2);
87835
+ return set2;
87836
+ }
87837
+ function ownVariantsOf(body) {
87838
+ const declared2 = body.variants;
87839
+ if (!Array.isArray(declared2)) return void 0;
87840
+ return declared2.filter((variant) => typeof variant === "string");
87841
+ }
87842
+ function sameVariants({ own: own2, declared: declared2 }) {
87843
+ if (!declared2 || declared2.length !== own2.length) return false;
87844
+ const set2 = new Set(declared2);
87845
+ return own2.every((variant) => set2.has(variant));
87846
+ }
87847
+ function iconLibraries(config2) {
87848
+ if (!config2) return NO_LIBRARIES;
87849
+ return allLibrariesOf(config2);
87850
+ }
87851
+ var allLibrariesOf = createSliceMemo({
87852
+ kinds: [
87853
+ "icon",
87854
+ "component",
87855
+ "package"
87856
+ ],
87857
+ compute: (config2) => Icon.groups(config2).map(({ path: path2 }) => iconLibrary(config2, path2)).filter((library) => library !== void 0)
87858
+ });
87859
+ var boundLibrariesOf = createSliceMemo({
87860
+ kinds: [
87861
+ "component",
87862
+ "icon",
87863
+ "package"
87864
+ ],
87865
+ compute: (_config) => /* @__PURE__ */ new Map()
87866
+ });
87867
+
87660
87868
  // ../config/dist/capture/captured-tree.js
87661
87869
  var CapturedNode = external_exports.lazy(() => external_exports.object({
87662
87870
  tag: external_exports.string().min(1),
@@ -87819,15 +88027,53 @@ function compound(selector3) {
87819
88027
 
87820
88028
  // ../config/dist/capture/class-grammar.js
87821
88029
  var VIEWPORT_UNIT = /\d(vh|vw|dvh|dvw|svh|svw|lvh|lvw|vmin|vmax)\b/;
88030
+ var COLOR_PROPERTY = /(^|-)(color|fill|stroke)$|^background$/;
88031
+ function isColorValue(value) {
88032
+ const v = value.trim().toLowerCase();
88033
+ if (/^(#|rgba?\(|hsla?\(|oklch\(|oklab\(|lab\(|lch\(|color\(|color-mix\()/.test(v)) return true;
88034
+ if (/^(color|colour):/.test(v)) return true;
88035
+ if (/^[-\d.]/.test(v) || /^(calc|min|max|clamp|var)\(/.test(v)) return false;
88036
+ return /^[a-z]+$/.test(v) && v !== "auto" && v !== "none";
88037
+ }
87822
88038
  function normalizeCssValue(value) {
87823
88039
  return value.trim().replace(/\s+/g, " ").replace(/(^|[\s,(])0(?:px|rem|em|%)(?=$|[\s,)])/g, "$10").toLowerCase();
87824
88040
  }
87825
88041
  function classGrammar(config2) {
87826
88042
  const styleProps = /* @__PURE__ */ new Map();
87827
- for (const entity of config2.list("style-property")) for (const [leaf, cls] of stylePropClasses(config2, entity.path)) if (!styleProps.has(cls)) styleProps.set(cls, {
87828
- path: entity.path,
87829
- leaf
87830
- });
88043
+ const arbitraryStems = /* @__PURE__ */ new Map();
88044
+ for (const entity of config2.list("style-property")) {
88045
+ for (const [leaf, cls] of stylePropClasses(config2, entity.path)) if (!styleProps.has(cls)) styleProps.set(cls, {
88046
+ path: entity.path,
88047
+ leaf
88048
+ });
88049
+ if (entity.toJSON().arbitrary) {
88050
+ const stem = arbitraryClassName({
88051
+ config: config2,
88052
+ path: entity.path,
88053
+ value: "[x]"
88054
+ }).slice(0, -3);
88055
+ arbitraryStems.set(stem, [...arbitraryStems.get(stem) ?? [], entity.path]);
88056
+ }
88057
+ }
88058
+ const arbitraryMatch = (cls) => {
88059
+ const open2 = cls.indexOf("[");
88060
+ if (open2 <= 0) return void 0;
88061
+ const close = cls.indexOf("]", open2);
88062
+ if (close === -1) return void 0;
88063
+ const rest = cls.slice(close + 1);
88064
+ if (rest !== "" && !/^\/(?:\[[^\]]+\]|[\w.-]+)$/.test(rest)) return void 0;
88065
+ const paths = arbitraryStems.get(cls.slice(0, open2)) ?? [];
88066
+ const inner = cls.slice(open2 + 1, close);
88067
+ if (!inner || paths.length === 0) return void 0;
88068
+ return {
88069
+ path: paths.length === 1 ? paths[0] : paths.find((each) => writesColor(each) === isColorValue(inner)) ?? paths[0],
88070
+ leaf: `[${inner}]`
88071
+ };
88072
+ };
88073
+ function writesColor(path2) {
88074
+ const { properties = [] } = config2.resolve("style-property", path2)?.toJSON() ?? {};
88075
+ return properties.some((property) => COLOR_PROPERTY.test(property));
88076
+ }
87831
88077
  const composites = config2.list("composite").map((entity) => ({
87832
88078
  path: entity.path,
87833
88079
  cls: className(config2, "composite", entity.path)
@@ -87940,7 +88186,7 @@ function classGrammar(config2) {
87940
88186
  };
87941
88187
  };
87942
88188
  return {
87943
- styleProp: (cls) => styleProps.get(cls),
88189
+ styleProp: (cls) => styleProps.get(cls) ?? arbitraryMatch(cls),
87944
88190
  stylePropsFor: (cssProperty2) => byCss.get(cssProperty2.toLowerCase()) ?? [],
87945
88191
  viewportLeaf(path2, leaf) {
87946
88192
  return (valuesOf(path2).get(leaf) ?? []).some((v) => VIEWPORT_UNIT.test(v));
@@ -88053,6 +88299,8 @@ function specFromCapture(options) {
88053
88299
  };
88054
88300
  }
88055
88301
  var FOLD = "data-uds-fold";
88302
+ var EMBED_SPACE_ATTR = "data-uds-embed";
88303
+ var COMPUTED_STYLE_ATTR = "data-uds-computed";
88056
88304
  var ORPHAN_LAYER = "data-uds-orphan-layer";
88057
88305
  function markOrphanLayers(tree) {
88058
88306
  const visit2 = (node2, open2) => {
@@ -88108,10 +88356,38 @@ var Converter = class {
88108
88356
  counter = 0;
88109
88357
  childCap;
88110
88358
  ruled = /* @__PURE__ */ new Map();
88359
+ /** Each component that draws a glyph by name → the prop that names it. */
88360
+ glyphDrawers;
88361
+ /** Each breakpoint's class prefix (`lg`) → whether it applied at the capture's width, and its rank. */
88362
+ breakpoints;
88363
+ /** Each modifier's class prefix (`md`) → the prop key its bag is written under (`_md`). */
88364
+ modifierKeys;
88111
88365
  constructor(options, grammar) {
88112
88366
  this.options = options;
88113
88367
  this.grammar = grammar;
88114
88368
  this.childCap = options.childCap ?? DEFAULT_CHILD_CAP;
88369
+ const drawers = /* @__PURE__ */ new Map();
88370
+ for (const library of iconLibraries(options.config)) {
88371
+ const drawer = glyphComponentOf(options.config, library.path);
88372
+ if (drawer) drawers.set(drawer.path, drawer.prop);
88373
+ }
88374
+ this.glyphDrawers = drawers;
88375
+ const width = options.width ?? DEFAULT_CAPTURE_WIDTH;
88376
+ const breakpoints = /* @__PURE__ */ new Map();
88377
+ for (const modifier of options.config.list("modifier")) {
88378
+ const { type, value } = modifier.toJSON();
88379
+ if (type !== "media-query" || typeof value !== "string") continue;
88380
+ const min2 = /min-width:\s*(\d+(?:\.\d+)?)px/.exec(value);
88381
+ const max2 = /max-width:\s*(\d+(?:\.\d+)?)px/.exec(value);
88382
+ if (!min2 && !max2) continue;
88383
+ const active = (!min2 || width >= Number(min2[1])) && (!max2 || width <= Number(max2[1]));
88384
+ breakpoints.set(modifier.leaf, {
88385
+ active,
88386
+ rank: min2 ? Number(min2[1]) : 0
88387
+ });
88388
+ }
88389
+ this.breakpoints = breakpoints;
88390
+ this.modifierKeys = new Map(options.config.list("modifier").map((modifier) => [modifier.leaf, `_${modifier.leaf}`]));
88115
88391
  }
88116
88392
  convertTop(el) {
88117
88393
  return this.convert(el);
@@ -88125,15 +88401,25 @@ var Converter = class {
88125
88401
  }
88126
88402
  return out;
88127
88403
  }
88128
- /** The components under `layer`, skipping every other layer `path` marks inside it. */
88129
- convertOutsideLayers(layer, path2) {
88404
+ /**
88405
+ * The components under `layer`, skipping every other layer `path` marks inside it. With
88406
+ * `callerMarkup`, the layer is one a slot of elements lands on, so the unmarked markup in it is
88407
+ * the caller's, kept as the plain tags it is, rather than the render's own.
88408
+ */
88409
+ convertOutsideLayers(layer, path2, callerMarkup = false) {
88130
88410
  const out = [];
88411
+ const mixed = callerMarkup && Array.from(layer.childNodes).some((node2) => isElement(node2) && visible(node2));
88131
88412
  for (let i = 0; i < layer.childNodes.length; i += 1) {
88132
88413
  if (this.childCap > 0 && out.length >= this.childCap) break;
88133
88414
  const node2 = layer.childNodes[i];
88134
- if (!isElement(node2)) continue;
88415
+ if (!isElement(node2)) {
88416
+ const text = (node2.textContent ?? "").replace(/\s+/g, " ");
88417
+ if (mixed && text.trim()) out.push(...this.plainTextRun(text, layer));
88418
+ continue;
88419
+ }
88135
88420
  if (node2.getAttribute("data-uds-component") === path2 && node2.getAttribute("data-uds-layer") !== "root") continue;
88136
88421
  if (node2.tagName.toLowerCase() === "svg" || isImage(node2) || node2.hasAttribute("data-uds-component") && node2.getAttribute("data-uds-layer") === "root") out.push(...this.convert(node2));
88422
+ else if (visible(node2) && callerMarkup) out.push(...this.plain(node2));
88137
88423
  else if (visible(node2) && framesItself(node2)) out.push(...this.frame(node2));
88138
88424
  else if (visible(node2)) out.push(...this.pinFolded(node2, this.convertOutsideLayers(node2, path2)));
88139
88425
  }
@@ -88147,61 +88433,429 @@ var Converter = class {
88147
88433
  return key2 ? [key2] : [];
88148
88434
  }
88149
88435
  if (el.tagName.toLowerCase() === "svg") return this.icon(el);
88150
- if (isImage(el)) return this.image(el);
88151
- if (isField(el)) return this.field(el);
88152
- if (framesItself(el)) return this.frame(el);
88153
- return this.pinFolded(el, this.convertChildren(el));
88436
+ if (el.hasAttribute(ORPHAN_LAYER)) return this.frame(el);
88437
+ return this.plain(el);
88154
88438
  }
88155
88439
  /**
88156
- * The content of an unmarked wrapper the capture folded, with the wrapper's measured box written
88157
- * onto it when it is one element: the wrapper's sizing (a flex share, a fixed size) no longer reaches
88158
- * the child, so the child keeps the box it had.
88440
+ * What an element inside a component holds, by the rule for a component's render: a nested
88441
+ * component is itself, and an unmarked element folds into what it holds, or is a frame when it
88442
+ * places itself, since it may be the render's own markup rather than the page's.
88159
88443
  */
88160
- pinFolded(el, keys) {
88161
- const size = el.getAttribute(FOLD)?.match(/^(\d+(?:\.\d+)?)x(\d+(?:\.\d+)?)$/);
88162
- if (!size || keys.length !== 1 || el.hasAttribute("data-uds-component")) return keys;
88163
- const element2 = this.elements[keys[0]];
88164
- const grammar = this.grammar.component(element2.type.replace(/^component:/, ""));
88165
- if (grammar) this.propsFromDeclarations([["width", `${size[1]}px`], ["height", `${size[2]}px`]], grammar, element2.props);
88166
- return keys;
88444
+ convertInside(el) {
88445
+ const out = [];
88446
+ for (let i = 0; i < el.childNodes.length; i += 1) {
88447
+ if (this.childCap > 0 && out.length >= this.childCap) break;
88448
+ const node2 = el.childNodes[i];
88449
+ if (!isElement(node2) || !visible(node2)) continue;
88450
+ if (node2.tagName.toLowerCase() === "svg" || node2.hasAttribute("data-uds-component") && node2.getAttribute("data-uds-layer") === "root") out.push(...this.convert(node2));
88451
+ else if (isImage(node2)) out.push(...this.image(node2));
88452
+ else if (isField(node2)) out.push(...this.field(node2));
88453
+ else if (framesItself(node2)) out.push(...this.frame(node2));
88454
+ else out.push(...this.pinFolded(node2, this.convertInside(node2)));
88455
+ }
88456
+ return out;
88167
88457
  }
88168
88458
  /**
88169
- * An unmarked element with an inline style, which is what the page drew it with, as the canvas's
88170
- * frame component carrying that style. One with nothing inline only groups its children and is
88171
- * folded away, and an empty one that paints nothing of its own (a portal's container) places
88172
- * nothing.
88459
+ * An unmarked element as the plain tag it is: an `img` keeps its source, a link its `href`, a field
88460
+ * its type and placeholder, and its text stays inside it. Its styling is stored as classes, the way
88461
+ * the canvas paints and the design panel edits a plain element: the classes it wears that the system
88462
+ * names, then its own inline style and the styles its stylesheets gave it written as the system's
88463
+ * classes (`16px` of gap is `gap-4`, an off-scale `13px` is `gap-[13px]`). What no style prop can
88464
+ * hold stays as an inline style. A `div` or `span` that carries nothing only groups its children and
88465
+ * folds away, as a wrapper the capture marked foldable does.
88173
88466
  */
88174
- frame(el) {
88175
- const children = this.convertChildren(el);
88176
- if (children.length === 0 && !paintsItself(el)) return [];
88177
- const role = canvasRole(this.options.config, "frame");
88178
- const grammar = role ? this.grammar.component(role.component) : void 0;
88179
- if (!role || !grammar) return children;
88180
- const props = this.orphanLayerProps(el, grammar);
88181
- this.propsFromInlineStyle(el, grammar, props);
88182
- if (Object.keys(props).length === 0) return children;
88183
- const key2 = this.key(role.component);
88467
+ plain(el, convertKids = () => this.plainChildren(el)) {
88468
+ const tag = el.tagName.toLowerCase();
88469
+ if (FORBIDDEN_TAGS.has(tag)) return [];
88470
+ if (el.hasAttribute(FOLD)) return this.pinFolded(el, convertKids());
88471
+ if ([...inlineDeclarations(el), ...declarationsOf(el.getAttribute("data-uds-computed") ?? "")].find(([property]) => property === "display")?.[1].trim() === "contents") return convertKids();
88472
+ const { className: className2, style, paints } = this.plainStyle(el);
88473
+ const attrs = plainAttributes(el);
88474
+ if (tag === "img" && !attrs.src) return [];
88475
+ const children = VOID_TAGS.has(tag) ? [] : convertKids();
88476
+ const text = children.length === 0 ? plainText(el) : "";
88477
+ if (children.length === 0 && !text && !VOID_TAGS.has(tag) && !paints && !el.hasAttribute(EMBED_SPACE_ATTR)) return [];
88478
+ if (!(className2 !== "" || Object.keys(style).length > 0 || Object.keys(attrs).length > 0) && GROUPING_TAGS.has(tag)) {
88479
+ if (text) return this.plainTextRun(text);
88480
+ return children;
88481
+ }
88482
+ const props = { ...attrs };
88483
+ if (className2) props.className = className2;
88484
+ if (Object.keys(style).length > 0) props.style = style;
88485
+ if (text) props.children = text;
88486
+ const key2 = this.key(tag);
88184
88487
  this.elements[key2] = {
88185
- type: `component:${role.component}`,
88488
+ type: tag,
88186
88489
  props,
88187
88490
  ...children.length > 0 ? { children } : {}
88188
88491
  };
88189
88492
  return [key2];
88190
88493
  }
88191
88494
  /**
88192
- * The styles the config gives an orphaned layer, as the frame's props: the rules that always apply
88193
- * and the ones its classes say are on, in authored order. Only values the frame component declares,
88194
- * spelled as an author writes them, are kept.
88495
+ * An inline SVG as itself: the `svg` and every shape in it, each with its attributes under the
88496
+ * names React takes them by. Definitions it references (a clip path, a gradient) are left out with
88497
+ * the references to them, since an id the capture copied may name nothing on the canvas.
88195
88498
  */
88196
- orphanLayerProps(el, frame2) {
88197
- const [path2, layer] = (el.getAttribute(ORPHAN_LAYER) ?? "").split("#");
88198
- if (!path2 || !layer) return {};
88199
- const active = {};
88200
- const own2 = this.grammar.component(path2);
88201
- for (const cls of classesOf(el)) Object.assign(active, own2?.conditions.get(cls));
88202
- const props = {};
88203
- const styles = Component.get(this.options.config, path2)?.styles ?? {};
88204
- for (const rule of Object.values(styles)) {
88499
+ plainSvg(svg) {
88500
+ if (holdsMoreThan(svg, SVG_SHAPE_LIMIT)) {
88501
+ const covered = /* @__PURE__ */ new Set();
88502
+ const size = (attr) => {
88503
+ const value = svg.getAttribute(attr);
88504
+ return value && /^\d+(?:\.\d+)?$/.test(value) ? this.classForDeclaration(attr, `${value}px`, covered) : void 0;
88505
+ };
88506
+ const className2 = [size("width"), size("height")].filter((cls) => !!cls && cls !== "covered").join(" ");
88507
+ const key2 = this.key("div");
88508
+ this.elements[key2] = {
88509
+ type: "div",
88510
+ props: className2 ? { className: className2 } : {}
88511
+ };
88512
+ return key2;
88513
+ }
88514
+ const build2 = (el) => {
88515
+ const tag = el.tagName.toLowerCase();
88516
+ const props = { [VERBATIM_ATTRIBUTES]: true };
88517
+ const styled = [];
88518
+ for (const { name, value } of el.attributes) {
88519
+ if (SVG_SKIPPED_ATTRIBUTES.test(name)) continue;
88520
+ if (name === "class" || name === "style") continue;
88521
+ if (name === "width" || name === "height") continue;
88522
+ const prop = svgAttributeName(name);
88523
+ if (this.options.config.resolve("style-property", prop)) {
88524
+ styled.push([name, value]);
88525
+ continue;
88526
+ }
88527
+ props[prop] = value;
88528
+ }
88529
+ const { className: className2, style } = this.plainStyle(el, styled);
88530
+ if (className2) props.className = className2;
88531
+ if (Object.keys(style).length > 0) props.style = style;
88532
+ const children = [];
88533
+ let text = "";
88534
+ for (const node2 of el.childNodes) {
88535
+ if (!isElement(node2)) {
88536
+ text += node2.textContent ?? "";
88537
+ continue;
88538
+ }
88539
+ if (SVG_SKIPPED_TAGS.has(node2.tagName.toLowerCase())) continue;
88540
+ children.push(build2(node2));
88541
+ }
88542
+ if (children.length === 0 && text.trim()) props.children = text.trim();
88543
+ const key2 = this.key(SVG_TAGS.get(tag) ?? tag);
88544
+ this.elements[key2] = {
88545
+ type: SVG_TAGS.get(tag) ?? tag,
88546
+ props,
88547
+ ...children.length > 0 ? { children } : {}
88548
+ };
88549
+ return key2;
88550
+ };
88551
+ return build2(svg);
88552
+ }
88553
+ /** A plain element's content: its elements, and each run of text between them as a `span`. */
88554
+ plainChildren(el) {
88555
+ if (!Array.from(el.childNodes).some((node2) => isElement(node2) && visible(node2))) return [];
88556
+ const out = [];
88557
+ for (let i = 0; i < el.childNodes.length; i += 1) {
88558
+ if (this.childCap > 0 && out.length >= this.childCap) break;
88559
+ const node2 = el.childNodes[i];
88560
+ if (isElement(node2)) {
88561
+ out.push(...this.convert(node2));
88562
+ continue;
88563
+ }
88564
+ const text = (node2.textContent ?? "").replace(/\s+/g, " ");
88565
+ if (text.trim()) out.push(...this.plainTextRun(text));
88566
+ }
88567
+ return out;
88568
+ }
88569
+ /**
88570
+ * A run of text as a `span`. It keeps how its holder wraps (`white-space: nowrap` on a nav item),
88571
+ * which the holder, a component that takes no such prop, may have no way to say itself.
88572
+ */
88573
+ plainTextRun(text, holder) {
88574
+ const props = { children: text };
88575
+ const wraps = declarationsOf(holder?.getAttribute("data-uds-computed") ?? "").find(([property]) => property === "white-space");
88576
+ if (wraps) {
88577
+ const cls = this.classForDeclaration("white-space", normalizeCssValue(wraps[1]), /* @__PURE__ */ new Set());
88578
+ if (cls && cls !== "covered") props.className = cls;
88579
+ else props.style = { whiteSpace: wraps[1] };
88580
+ }
88581
+ const key2 = this.key("span");
88582
+ this.elements[key2] = {
88583
+ type: "span",
88584
+ props
88585
+ };
88586
+ return [key2];
88587
+ }
88588
+ /**
88589
+ * A plain element's styling as the system's classes, and what none can hold as inline style. The
88590
+ * page's own inline style painted over its classes, so it is read first and a class for a property it
88591
+ * sets is dropped; the computed styles fill only what neither says.
88592
+ */
88593
+ plainStyle(el, attributes = []) {
88594
+ const classes = [];
88595
+ const style = {};
88596
+ const covered = /* @__PURE__ */ new Set();
88597
+ let paints = false;
88598
+ const notePaint = (property) => {
88599
+ if (PAINT_PROPERTY.test(property)) paints = true;
88600
+ };
88601
+ const written = /* @__PURE__ */ new Set();
88602
+ const fromDeclarations = (declarations) => {
88603
+ for (const [property, raw] of declarations.flatMap(gridAreaLines)) {
88604
+ if (written.has(property) || written.has(LOGICAL_SIDES[property] ?? property)) continue;
88605
+ let value = normalizeCssValue(raw);
88606
+ const paintNone = value === "none" && (property === "fill" || property === "stroke");
88607
+ if (!value || SKIP_INLINE_PROPERTY.has(property) || SKIP_INLINE_VALUE.has(value) && !paintNone) continue;
88608
+ if (property === "position" && value === "fixed") value = "absolute";
88609
+ if (VIEWPORT_VALUE.test(value) && !WHOLE_VIEWPORT.test(value)) value = frameUnits(value, this.options.width, this.options.height);
88610
+ const cls = this.classForDeclaration(property, value, covered);
88611
+ if (cls === "covered") continue;
88612
+ notePaint(property);
88613
+ if (cls) {
88614
+ classes.push(cls);
88615
+ continue;
88616
+ }
88617
+ let placed = false;
88618
+ for (const [longhand, part] of gridLonghands({
88619
+ property,
88620
+ value
88621
+ })) {
88622
+ const longClass = this.classForDeclaration(longhand, part, covered);
88623
+ if (longClass && longClass !== "covered") classes.push(longClass);
88624
+ placed = placed || longClass !== void 0;
88625
+ }
88626
+ if (!placed && !(camelCase3(property) in style)) style[camelCase3(property)] = raw.trim();
88627
+ }
88628
+ };
88629
+ fromDeclarations(inlineDeclarations(el));
88630
+ fromDeclarations(attributes);
88631
+ fromDeclarations(["width", "height"].flatMap((attr) => {
88632
+ const value = el.getAttribute(attr);
88633
+ return value && /^\d+(?:\.\d+)?$/.test(value) ? [[attr, `${value}px`]] : [];
88634
+ }));
88635
+ const read = classesOf(el).flatMap((cls) => {
88636
+ const each = this.readModifiedClass(cls);
88637
+ if (!each) return [];
88638
+ if (each.modifiers.length === 0 && covered.has(each.style.path)) return [];
88639
+ const { properties = [] } = this.options.config.resolve("style-property", each.style.path)?.toJSON() ?? {};
88640
+ const atoms = atomsOf(properties);
88641
+ if (atoms.size === 0) atoms.add(`prop:${each.style.path}`);
88642
+ return [{
88643
+ ...each,
88644
+ properties,
88645
+ atoms
88646
+ }];
88647
+ });
88648
+ const winners = /* @__PURE__ */ new Map();
88649
+ for (const each of read) for (const atom of each.atoms) {
88650
+ const slot = `${each.modifiers.join(".")}|${atom}`;
88651
+ const prior = winners.get(slot);
88652
+ if (!prior || each.rank > prior.rank || each.rank === prior.rank && each.atoms.size < prior.atoms.size) winners.set(slot, each);
88653
+ }
88654
+ const painted = new Set(winners.values());
88655
+ for (const each of read) {
88656
+ if (!painted.has(each)) continue;
88657
+ if (each.modifiers.length === 0) covered.add(each.style.path);
88658
+ for (const property of each.properties) {
88659
+ notePaint(property);
88660
+ if (each.modifiers.length === 0) for (const longhand of longhandsOf(property)) written.add(longhand);
88661
+ }
88662
+ const owned = [...each.atoms].filter((atom) => winners.get(`${each.modifiers.join(".")}|${atom}`) === each);
88663
+ classes.push(...owned.length < each.atoms.size ? this.narrowed(each, new Set(owned)) : [each.bare]);
88664
+ }
88665
+ fromDeclarations(declarationsOf(el.getAttribute("data-uds-computed") ?? ""));
88666
+ return {
88667
+ className: [...new Set(classes)].join(" "),
88668
+ style,
88669
+ paints
88670
+ };
88671
+ }
88672
+ /**
88673
+ * The system's class for one declaration: the class of the leaf whose value it is, or the bracket
88674
+ * class of an off-scale value on a prop that takes one. `covered` when a prop for the property is
88675
+ * already set, so the first source to set it wins; nothing when no prop writes the property.
88676
+ */
88677
+ classForDeclaration(property, value, covered) {
88678
+ const logical = LOGICAL_SIDES[property];
88679
+ const options = [...this.grammar.stylePropsFor(property), ...logical ? this.grammar.stylePropsFor(logical) : []];
88680
+ for (const option of options) {
88681
+ if (covered.has(option.path)) return "covered";
88682
+ const css = option.negates ? negated(value) : value;
88683
+ if (css === void 0) continue;
88684
+ const leaf = equivalents({
88685
+ property,
88686
+ value: css
88687
+ }).map((spelling) => option.leafFor(spelling)).find((found) => found !== void 0);
88688
+ let cls;
88689
+ if (WHOLE_VIEWPORT.test(css) && option.fullLeaf !== void 0) cls = stylePropClassName(this.options.config, option.path, option.fullLeaf);
88690
+ else if (leaf !== void 0) cls = stylePropClassName(this.options.config, option.path, leaf);
88691
+ else if (option.arbitrary) cls = arbitraryClassName({
88692
+ config: this.options.config,
88693
+ path: option.path,
88694
+ value: `[${css.replaceAll(" ", "_")}]`
88695
+ });
88696
+ if (cls === void 0) continue;
88697
+ covered.add(option.path);
88698
+ return cls;
88699
+ }
88700
+ }
88701
+ /**
88702
+ * The content of an unmarked wrapper the capture folded, with the wrapper's measured box written
88703
+ * onto it when it is one element: the wrapper's sizing (a flex share, a fixed size) no longer reaches
88704
+ * the child, so the child keeps the box it had.
88705
+ */
88706
+ pinFolded(el, keys) {
88707
+ const size = el.getAttribute(FOLD)?.match(/^(\d+(?:\.\d+)?)x(\d+(?:\.\d+)?)$/);
88708
+ if (!size || keys.length !== 1 || el.hasAttribute("data-uds-component")) return keys;
88709
+ const element2 = this.elements[keys[0]];
88710
+ if (kindOf2(element2.type) !== "component") {
88711
+ const covered = /* @__PURE__ */ new Set();
88712
+ const sized = [this.classForDeclaration("width", `${size[1]}px`, covered), this.classForDeclaration("height", `${size[2]}px`, covered)].filter((cls) => !!cls && cls !== "covered");
88713
+ const own2 = String(element2.props.className ?? "").split(/\s+/).filter((cls) => {
88714
+ const read = cls ? this.readModifiedClass(cls) : void 0;
88715
+ if (!read || read.modifiers.length > 0) return Boolean(cls);
88716
+ const atoms = this.styleAtoms().get(read.style.path);
88717
+ return !(atoms?.has("width") || atoms?.has("height"));
88718
+ });
88719
+ element2.props.className = [...own2, ...sized].join(" ");
88720
+ return keys;
88721
+ }
88722
+ const grammar = this.grammar.component(element2.type.replace(/^component:/, ""));
88723
+ if (grammar) this.propsFromDeclarations([["width", `${size[1]}px`], ["height", `${size[2]}px`]], grammar, element2.props);
88724
+ return keys;
88725
+ }
88726
+ /**
88727
+ * An unmarked element with an inline style, which is what the page drew it with, as the canvas's
88728
+ * frame component carrying that style. One with nothing inline only groups its children and is
88729
+ * folded away, and an empty one that paints nothing of its own (a portal's container) places
88730
+ * nothing.
88731
+ */
88732
+ frame(el) {
88733
+ const children = this.convertInside(el);
88734
+ if (children.length === 0 && !paintsItself(el)) return [];
88735
+ const role = canvasRole(this.options.config, "frame");
88736
+ const grammar = role ? this.grammar.component(role.component) : void 0;
88737
+ if (!role || !grammar) return children;
88738
+ const props = this.orphanLayerProps(el, grammar);
88739
+ this.propsFromInlineStyle(el, grammar, props);
88740
+ if (Object.keys(props).length === 0) return children;
88741
+ const key2 = this.key(role.component);
88742
+ this.elements[key2] = {
88743
+ type: `component:${role.component}`,
88744
+ props,
88745
+ ...children.length > 0 ? { children } : {}
88746
+ };
88747
+ return [key2];
88748
+ }
88749
+ /**
88750
+ * The style props `classes` spell for a component with `grammar`, each class under a modifier
88751
+ * prefix written into that modifier's bag (`md:hover:flex` → `_md._hover.display`). A class whose
88752
+ * prefix names no modifier the config has, or whose prop the component does not take, is not read.
88753
+ * A value already set is kept: the first class for a prop wins, as a stamped value does.
88754
+ */
88755
+ stylePropsFromClasses(classes, grammar, props) {
88756
+ const ranks = /* @__PURE__ */ new Map();
88757
+ for (const cls of classes) {
88758
+ const read = this.readModifiedClass(cls);
88759
+ if (!read) continue;
88760
+ const prop = grammar.propForStyleProperty.get(read.style.path);
88761
+ if (!prop) continue;
88762
+ const slot = `${read.modifiers.join(".")}|${prop}`;
88763
+ const before5 = ranks.get(slot);
88764
+ if (before5 !== void 0 && before5 >= read.rank) continue;
88765
+ ranks.set(slot, read.rank);
88766
+ let bag = props;
88767
+ for (const key2 of read.modifiers) {
88768
+ const inner = bag[key2];
88769
+ if (inner && typeof inner === "object" && !Array.isArray(inner)) bag = inner;
88770
+ else if (inner === void 0) {
88771
+ const next = {};
88772
+ bag[key2] = next;
88773
+ bag = next;
88774
+ } else bag = {};
88775
+ }
88776
+ bag[prop] = this.frameValue(read.style.path, read.style.leaf);
88777
+ }
88778
+ }
88779
+ atomsByStyle;
88780
+ /** Each style property → the physical longhands it writes. */
88781
+ styleAtoms() {
88782
+ if (!this.atomsByStyle) this.atomsByStyle = new Map(this.options.config.list("style-property").map((prop) => {
88783
+ const { properties = [] } = prop.toJSON();
88784
+ return [prop.path, atomsOf(properties)];
88785
+ }));
88786
+ return this.atomsByStyle;
88787
+ }
88788
+ /**
88789
+ * A shorthand class that a narrower one overrode on some sides (`p-5` under `px-16`), as the
88790
+ * classes for the sides it still painted (`py-5`), so the canvas's stylesheet order cannot let it
88791
+ * win the others back. The class as written when the system has no narrower class at its value.
88792
+ */
88793
+ narrowed(shorthand, owned) {
88794
+ const config2 = this.options.config;
88795
+ const options = /* @__PURE__ */ new Map();
88796
+ for (const [path2, atoms] of this.styleAtoms()) {
88797
+ if (path2 === shorthand.style.path || atoms.size === 0) continue;
88798
+ if ([...atoms].every((each) => owned.has(each))) options.set(path2, atoms);
88799
+ }
88800
+ const left = new Set(owned);
88801
+ const out = [];
88802
+ for (const [path2, atoms] of [...options].sort((a, b) => b[1].size - a[1].size)) {
88803
+ if (![...atoms].every((each) => left.has(each))) continue;
88804
+ const cls = stylePropClassName(config2, path2, shorthand.style.leaf);
88805
+ if (this.grammar.styleProp(cls)?.path !== path2) continue;
88806
+ out.push(`${shorthand.prefix}${cls}`);
88807
+ for (const each of atoms) left.delete(each);
88808
+ }
88809
+ return left.size === 0 ? out : [shorthand.bare];
88810
+ }
88811
+ /** A class as the modifier keys over it and the style prop it names, or nothing for one it doesn't. */
88812
+ readModifiedClass(cls) {
88813
+ const bracket = cls.indexOf("[");
88814
+ const head = bracket === -1 ? cls : cls.slice(0, bracket);
88815
+ const at = head.lastIndexOf(":");
88816
+ const prefixes = at === -1 ? [] : head.slice(0, at).split(":");
88817
+ const modifiers = [];
88818
+ const kept = [];
88819
+ let rank = 0;
88820
+ for (const prefix2 of prefixes) {
88821
+ const breakpoint = this.breakpoints.get(prefix2);
88822
+ if (breakpoint) {
88823
+ if (!breakpoint.active) return void 0;
88824
+ rank = Math.max(rank, breakpoint.rank);
88825
+ continue;
88826
+ }
88827
+ const key2 = this.modifierKeys.get(prefix2);
88828
+ if (!key2) return void 0;
88829
+ modifiers.push(key2);
88830
+ kept.push(prefix2);
88831
+ }
88832
+ let leaf = at === -1 ? cls : cls.slice(at + 1);
88833
+ const important = /^!|!$/.test(leaf);
88834
+ if (important) leaf = leaf.replace(/^!|!$/, "");
88835
+ if (important) rank += IMPORTANT_RANK;
88836
+ const style = this.grammar.styleProp(leaf);
88837
+ return style ? {
88838
+ modifiers,
88839
+ style,
88840
+ rank,
88841
+ bare: [...kept, leaf].join(":"),
88842
+ prefix: kept.map((each) => `${each}:`).join("")
88843
+ } : void 0;
88844
+ }
88845
+ /**
88846
+ * The styles the config gives an orphaned layer, as the frame's props: the rules that always apply
88847
+ * and the ones its classes say are on, in authored order. Only values the frame component declares,
88848
+ * spelled as an author writes them, are kept.
88849
+ */
88850
+ orphanLayerProps(el, frame2) {
88851
+ const [path2, layer] = (el.getAttribute(ORPHAN_LAYER) ?? "").split("#");
88852
+ if (!path2 || !layer) return {};
88853
+ const active = {};
88854
+ const own2 = this.grammar.component(path2);
88855
+ for (const cls of classesOf(el)) Object.assign(active, own2?.conditions.get(cls));
88856
+ const props = {};
88857
+ const styles = Component.get(this.options.config, path2)?.styles ?? {};
88858
+ for (const rule of Object.values(styles)) {
88205
88859
  const when = rule?.when ?? {};
88206
88860
  if (!Object.entries(when).every(([key2, value]) => active[key2] === value)) continue;
88207
88861
  for (const [key2, value] of Object.entries(rule.layers?.[layer] ?? {})) {
@@ -88313,7 +88967,8 @@ var Converter = class {
88313
88967
  image(img) {
88314
88968
  const src = img.getAttribute("src");
88315
88969
  const role = canvasRole(this.options.config, "image");
88316
- if (!src || !role) return [];
88970
+ if (!src) return [];
88971
+ if (!role) return this.plain(img);
88317
88972
  const props = { ...role.defaultProps };
88318
88973
  const grammar = this.grammar.component(role.component);
88319
88974
  if (grammar) {
@@ -88368,7 +89023,7 @@ var Converter = class {
88368
89023
  const answer = this.options.icons?.resolve(svgOf(svg));
88369
89024
  if (!answer) {
88370
89025
  this.unresolvedIcons += 1;
88371
- return [];
89026
+ return [this.plainSvg(svg)];
88372
89027
  }
88373
89028
  const key2 = this.key(answer.component);
88374
89029
  this.elements[key2] = {
@@ -88386,8 +89041,16 @@ var Converter = class {
88386
89041
  const props = {};
88387
89042
  const stamped = stampedProps(el);
88388
89043
  if (grammar) this.propsFromClasses(el, grammar, props);
89044
+ if (grammar) for (const [prop, raw] of Object.entries(grammar.declared)) {
89045
+ if (stamped[prop] !== void 0) continue;
89046
+ const declared3 = raw;
89047
+ const attr = declared3?.type === "forward" && declared3.target?.__ref === "layer:root" && typeof declared3.into === "string" ? declared3.into : declared3?.type === "string" && ROOT_ATTRIBUTE_PROPS.includes(prop) ? prop : void 0;
89048
+ const value = attr ? el.getAttribute(attr) : null;
89049
+ if (value) props[prop] = value;
89050
+ }
88389
89051
  Object.assign(props, stamped);
88390
89052
  if (grammar) this.propsFromInlineStyle(el, grammar, props, path2);
89053
+ if (grammar) this.propsFromComputed(el, grammar, props, path2);
88391
89054
  const layerProps2 = stampedLayerProps({
88392
89055
  el,
88393
89056
  layers: this.layerNames(path2)
@@ -88401,9 +89064,14 @@ var Converter = class {
88401
89064
  if (answer) for (const [prop, value] of Object.entries(answer.props)) props[prop] ??= value;
88402
89065
  else if (Object.keys(stamped).length === 0) {
88403
89066
  this.unresolvedIcons += 1;
88404
- return;
89067
+ return svg ? this.plainSvg(svg) : void 0;
88405
89068
  }
88406
89069
  }
89070
+ const glyphProp = this.glyphDrawers.get(path2);
89071
+ if (glyphProp && props[glyphProp] === void 0) {
89072
+ const svg = el.tagName.toLowerCase() === "svg" ? el : el.querySelector("svg");
89073
+ if (svg) return this.plainSvg(svg);
89074
+ }
88407
89075
  const key2 = this.key(path2);
88408
89076
  const element2 = {
88409
89077
  type: `component:${path2}`,
@@ -88411,8 +89079,10 @@ var Converter = class {
88411
89079
  };
88412
89080
  const declared2 = grammar?.declared ?? {};
88413
89081
  const slots = {};
88414
- for (const layer of asArray(el.querySelectorAll("[data-uds-slot]"))) {
88415
- if (nearestRoot(layer) !== el || hiddenBetween(layer, el)) continue;
89082
+ let rootSlotted = false;
89083
+ const marked = [...el.hasAttribute("data-uds-slot") ? [el] : [], ...asArray(el.querySelectorAll("[data-uds-slot]"))];
89084
+ for (const layer of marked) {
89085
+ if (layer !== el && layer.getAttribute("data-uds-layer") === "root" || layer !== el && nearestRoot(layer) !== el || hiddenBetween(layer, el)) continue;
88416
89086
  const names = slotNames(layer).filter((slot) => !grammar || slot in declared2);
88417
89087
  const intoOf = (slot) => grammar?.layerProps.get(slot)?.into ?? "children";
88418
89088
  const ownChildren = names.filter((slot) => intoOf(slot) === "children");
@@ -88421,10 +89091,13 @@ var Converter = class {
88421
89091
  if (into === "children" && slot !== ownChildren.at(-1)) continue;
88422
89092
  const holder = into === "children" ? layer : slotLayerNamed(layer, into);
88423
89093
  if (!holder) continue;
88424
- const fills = holder === layer ? this.convertOutsideLayers(layer, path2) : this.convertChildren(holder);
89094
+ const declaration = declared2[slot];
89095
+ const callerMarkup = declaration?.type === "slot" && declaration.text !== true;
89096
+ const fills = holder === layer ? this.convertOutsideLayers(layer, path2, callerMarkup) : this.convertChildren(holder);
89097
+ if (layer === el && holder === layer) rootSlotted = true;
88425
89098
  if (fills.length > 0) slots[slot] = fills;
88426
- else if (holder !== layer) {
88427
- const text = collapse(ownText(holder));
89099
+ else {
89100
+ const text = collapse(holder === layer ? ownText(layer, /* @__PURE__ */ new Set()) : ownText(holder));
88428
89101
  if (text) props[slot] = text;
88429
89102
  }
88430
89103
  }
@@ -88466,7 +89139,7 @@ var Converter = class {
88466
89139
  }
88467
89140
  const textSlot = declared2.children;
88468
89141
  const holdsText = textSlot?.type === "slot" && textSlot.text === true;
88469
- const loose = this.looseContent({
89142
+ const loose = rootSlotted ? [] : this.looseContent({
88470
89143
  el,
88471
89144
  claimed,
88472
89145
  takesGlyphs: !renders,
@@ -88499,9 +89172,24 @@ var Converter = class {
88499
89172
  if ("checked" in declared2) props.checked = true;
88500
89173
  else if ("selected" in declared2) props.selected = true;
88501
89174
  }
88502
- if (grammar) for (const prop of Object.keys(props)) {
88503
- if (prop in declared2 || prop === "aria-label" || prop === "layerProps") continue;
88504
- delete props[prop];
89175
+ if (grammar) {
89176
+ if (props.style !== void 0 && !("style" in declared2)) {
89177
+ const bags = props["layerProps"] ?? {};
89178
+ const root = bags.root ?? {};
89179
+ bags.root = {
89180
+ ...root,
89181
+ style: {
89182
+ ...Object.fromEntries(Object.entries(props.style).map(([property, value]) => [property, inlineCss(value)])),
89183
+ ...root.style ?? {}
89184
+ }
89185
+ };
89186
+ props[LAYER_PROPS] = bags;
89187
+ delete props.style;
89188
+ }
89189
+ for (const prop of Object.keys(props)) {
89190
+ if (prop in declared2 || prop === "aria-label" || prop === "layerProps") continue;
89191
+ delete props[prop];
89192
+ }
88505
89193
  }
88506
89194
  this.elements[key2] = element2;
88507
89195
  return key2;
@@ -88518,11 +89206,7 @@ var Converter = class {
88518
89206
  props[composite.prop] = composite.value;
88519
89207
  continue;
88520
89208
  }
88521
- const style = this.grammar.styleProp(cls);
88522
- if (style) {
88523
- const prop = grammar.propForStyleProperty.get(style.path);
88524
- if (prop && props[prop] === void 0) props[prop] = this.frameValue(style.path, style.leaf);
88525
- }
89209
+ this.stylePropsFromClasses([cls], grammar, props);
88526
89210
  }
88527
89211
  }
88528
89212
  /**
@@ -88544,6 +89228,46 @@ var Converter = class {
88544
89228
  propsFromInlineStyle(el, grammar, props, path2) {
88545
89229
  this.propsFromDeclarations(inlineDeclarations(el), grammar, props, path2 === void 0 ? void 0 : this.ruledProperties(path2));
88546
89230
  }
89231
+ /**
89232
+ * The styles the page's own classes gave a component's root, from what the browser computed, for
89233
+ * the CSS properties the component does not set itself: a stack's `display` and direction are its
89234
+ * own, while the width and flex share an app's Tailwind gave it are the page's, and no prop said
89235
+ * them. A property a rule, a default or a prop already read sets is left to that.
89236
+ */
89237
+ propsFromComputed(el, grammar, props, path2) {
89238
+ const computed = el.getAttribute(COMPUTED_STYLE_ATTR);
89239
+ if (!computed) return;
89240
+ const own2 = new Set(this.ruledProperties(path2));
89241
+ const { defaultProps = {} } = Component.get(this.options.config, path2) ?? {};
89242
+ const named = new Set(Object.keys(props));
89243
+ for (const [stylePath, prop] of grammar.propForStyleProperty) {
89244
+ if (!named.has(prop)) continue;
89245
+ for (const property of StyleProperty.get(this.options.config, stylePath)?.properties ?? []) for (const each of longhandsOf(property)) own2.add(each);
89246
+ }
89247
+ const fill = {};
89248
+ const unheld = {};
89249
+ for (const declaration of declarationsOf(computed)) {
89250
+ const [property, value] = declaration;
89251
+ if (own2.has(property) || own2.has(LOGICAL_SIDES[property] ?? property)) continue;
89252
+ const before5 = Object.keys(fill).length;
89253
+ this.propsFromDeclarations([declaration], grammar, fill);
89254
+ if (Object.keys(fill).length === before5 && COMPONENT_INLINE_LAYOUT.has(property)) {
89255
+ const arbitrary = this.grammar.stylePropsFor(property).some((option) => option.arbitrary);
89256
+ unheld[camelCase3(property)] = arbitrary ? `[${normalizeCssValue(value).replaceAll(" ", "_")}]` : value;
89257
+ }
89258
+ }
89259
+ for (const [prop, value] of Object.entries(fill)) {
89260
+ if (props[prop] !== void 0 || defaultProps[prop] === value) continue;
89261
+ props[prop] = value;
89262
+ }
89263
+ if (Object.keys(unheld).length > 0) {
89264
+ const own3 = props.style ?? {};
89265
+ props.style = {
89266
+ ...unheld,
89267
+ ...own3
89268
+ };
89269
+ }
89270
+ }
88547
89271
  /** The CSS properties a component's own style rules write on its root layer. */
88548
89272
  ruledProperties(path2) {
88549
89273
  const known = this.ruled.get(path2);
@@ -88646,6 +89370,208 @@ var ARTBOARD = [
88646
89370
  ["isolation", "isolate"]
88647
89371
  ];
88648
89372
  var INPUT_LINE = [["display", "flex"], ["align-items", "center"]];
89373
+ function inlineCss(value) {
89374
+ if (typeof value !== "string" || !/^\[.*\]$/.test(value)) return value;
89375
+ return value.slice(1, -1).replace(/url\([^)]*\)|_/g, (span) => span === "_" ? " " : span);
89376
+ }
89377
+ function holdsMoreThan(el, limit) {
89378
+ let count = 0;
89379
+ const visit2 = (node2) => {
89380
+ for (const child of node2.children) {
89381
+ count += 1;
89382
+ if (count > limit || visit2(child)) return true;
89383
+ }
89384
+ return false;
89385
+ };
89386
+ return visit2(el);
89387
+ }
89388
+ var SVG_SHAPE_LIMIT = 300;
89389
+ var FORBIDDEN_TAGS = /* @__PURE__ */ new Set([
89390
+ "script",
89391
+ "style",
89392
+ "noscript",
89393
+ "template",
89394
+ "iframe",
89395
+ "object",
89396
+ "embed",
89397
+ "base",
89398
+ "link",
89399
+ "meta"
89400
+ ]);
89401
+ var SIDES = [
89402
+ "top",
89403
+ "right",
89404
+ "bottom",
89405
+ "left"
89406
+ ];
89407
+ var CORNERS = [
89408
+ "top-left",
89409
+ "top-right",
89410
+ "bottom-right",
89411
+ "bottom-left"
89412
+ ];
89413
+ var IMPORTANT_RANK = 1e6;
89414
+ function atomsOf(properties) {
89415
+ const physical = new Map(Object.entries(LOGICAL_SIDES).map(([side, logical]) => [logical, side]));
89416
+ const atoms = /* @__PURE__ */ new Set();
89417
+ for (const property of properties) for (const each of longhandsOf(property)) {
89418
+ const side = physical.get(each) ?? each;
89419
+ if (longhandsOf(side).length <= 1) atoms.add(side);
89420
+ }
89421
+ return atoms;
89422
+ }
89423
+ function longhandsOf(property) {
89424
+ const boxed = /^(padding|margin)(-inline|-block)?$/.exec(property);
89425
+ if (boxed) {
89426
+ const [, box, axis] = boxed;
89427
+ return [property, ...(axis === "-inline" ? ["left", "right"] : axis === "-block" ? ["top", "bottom"] : SIDES).flatMap((side) => [`${box}-${side}`, LOGICAL_SIDES[`${box}-${side}`] ?? ""])].filter(Boolean);
89428
+ }
89429
+ switch (property) {
89430
+ case "inset":
89431
+ return [property, ...SIDES];
89432
+ case "gap":
89433
+ return [
89434
+ property,
89435
+ "row-gap",
89436
+ "column-gap"
89437
+ ];
89438
+ case "overflow":
89439
+ return [
89440
+ property,
89441
+ "overflow-x",
89442
+ "overflow-y"
89443
+ ];
89444
+ case "border-radius":
89445
+ return [property, ...CORNERS.map((corner) => `border-${corner}-radius`)];
89446
+ case "border-width":
89447
+ case "border-color":
89448
+ case "border-style": {
89449
+ const part = property.slice(7);
89450
+ return [property, ...SIDES.map((side) => `border-${side}-${part}`)];
89451
+ }
89452
+ default:
89453
+ return [property];
89454
+ }
89455
+ }
89456
+ var LOGICAL_SIDES = {
89457
+ "padding-left": "padding-inline-start",
89458
+ "padding-right": "padding-inline-end",
89459
+ "margin-left": "margin-inline-start",
89460
+ "margin-right": "margin-inline-end",
89461
+ "border-left-width": "border-inline-start-width",
89462
+ "border-right-width": "border-inline-end-width",
89463
+ "border-left-color": "border-inline-start-color",
89464
+ "border-right-color": "border-inline-end-color",
89465
+ left: "inset-inline-start",
89466
+ right: "inset-inline-end",
89467
+ "border-top-left-radius": "border-start-start-radius",
89468
+ "border-top-right-radius": "border-start-end-radius",
89469
+ "border-bottom-left-radius": "border-end-start-radius",
89470
+ "border-bottom-right-radius": "border-end-end-radius"
89471
+ };
89472
+ var VERBATIM_ATTRIBUTES = "__verbatimAttributes";
89473
+ var SVG_SKIPPED_ATTRIBUTES = /^(on|data-|id$|clip-path$|mask$|filter$|xlink:href$|href$)/;
89474
+ var SVG_SKIPPED_TAGS = /* @__PURE__ */ new Set([
89475
+ "defs",
89476
+ "clippath",
89477
+ "mask",
89478
+ "lineargradient",
89479
+ "radialgradient",
89480
+ "filter",
89481
+ "pattern",
89482
+ "symbol",
89483
+ "script",
89484
+ "style",
89485
+ "title",
89486
+ "desc",
89487
+ "use"
89488
+ ]);
89489
+ var SVG_TAGS = /* @__PURE__ */ new Map([["foreignobject", "foreignObject"]]);
89490
+ function svgAttributeName(name) {
89491
+ if (name === "viewbox") return "viewBox";
89492
+ if (name.startsWith("aria-") || name === "role") return name;
89493
+ if (name === "xmlns" || name === "xmlns:xlink") return name === "xmlns" ? "xmlns" : "xmlnsXlink";
89494
+ return name.replace(/[-:]([a-z])/g, (_, letter) => letter.toUpperCase());
89495
+ }
89496
+ var COMPONENT_INLINE_LAYOUT = /* @__PURE__ */ new Set([
89497
+ "grid-template-columns",
89498
+ "grid-template-rows",
89499
+ "grid-column",
89500
+ "grid-row",
89501
+ "white-space",
89502
+ "aspect-ratio",
89503
+ "flex-basis",
89504
+ "flex-grow",
89505
+ "flex-shrink",
89506
+ "max-width",
89507
+ "min-width"
89508
+ ]);
89509
+ var DEFAULT_CAPTURE_WIDTH = 1600;
89510
+ var ROOT_ATTRIBUTE_PROPS = [
89511
+ "src",
89512
+ "alt",
89513
+ "href",
89514
+ "title",
89515
+ "placeholder"
89516
+ ];
89517
+ var PAINT_PROPERTY = /^(background|border-(top-|right-|bottom-|left-)?(width|color)|box-shadow|outline)/;
89518
+ var GROUPING_TAGS = /* @__PURE__ */ new Set(["div", "span"]);
89519
+ var VOID_TAGS = /* @__PURE__ */ new Set([
89520
+ "img",
89521
+ "input",
89522
+ "br",
89523
+ "hr",
89524
+ "wbr",
89525
+ "area",
89526
+ "col",
89527
+ "source",
89528
+ "track"
89529
+ ]);
89530
+ var PLAIN_ATTRIBUTES = {
89531
+ href: "href",
89532
+ src: "src",
89533
+ alt: "alt",
89534
+ title: "title",
89535
+ role: "role",
89536
+ type: "type",
89537
+ placeholder: "placeholder",
89538
+ name: "name",
89539
+ target: "target",
89540
+ rel: "rel",
89541
+ colspan: "colSpan",
89542
+ rowspan: "rowSpan",
89543
+ for: "htmlFor"
89544
+ };
89545
+ function plainAttributes(el) {
89546
+ const out = {};
89547
+ const tag = el.tagName.toLowerCase();
89548
+ for (const [attr, prop] of Object.entries(PLAIN_ATTRIBUTES)) {
89549
+ const value = el.getAttribute(attr);
89550
+ if (value === null || value === void 0) continue;
89551
+ if ((attr === "href" || attr === "src") && /^\s*javascript:/i.test(value)) continue;
89552
+ out[prop] = value;
89553
+ }
89554
+ for (const { name, value } of el.attributes) if (name.startsWith("aria-")) out[name] = value;
89555
+ if (tag === "input" || tag === "textarea") {
89556
+ const value = tag === "textarea" ? el.textContent ?? "" : el.getAttribute("value");
89557
+ if (value) out.defaultValue = value;
89558
+ }
89559
+ return out;
89560
+ }
89561
+ function plainText(el) {
89562
+ if (isField(el)) return "";
89563
+ let text = "";
89564
+ const read = (node2) => {
89565
+ for (const child of node2.childNodes) if (child.nodeType === 3) text += child.textContent ?? "";
89566
+ else if (child.nodeType === 1 && visible(child)) read(child);
89567
+ };
89568
+ read(el);
89569
+ return text.replace(/\s+/g, " ").trim();
89570
+ }
89571
+ function camelCase3(property) {
89572
+ if (property.startsWith("--")) return property;
89573
+ return property.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
89574
+ }
88649
89575
  function isImage(el) {
88650
89576
  return el.tagName.toLowerCase() === "img" && !el.hasAttribute("data-uds-component");
88651
89577
  }
@@ -88711,8 +89637,11 @@ function paintsItself(el) {
88711
89637
  });
88712
89638
  }
88713
89639
  function inlineDeclarations(el) {
89640
+ return declarationsOf(el.getAttribute("style") ?? "");
89641
+ }
89642
+ function declarationsOf(text) {
88714
89643
  const out = [];
88715
- for (const declaration of (el.getAttribute("style") ?? "").split(";")) {
89644
+ for (const declaration of text.split(";")) {
88716
89645
  const at = declaration.indexOf(":");
88717
89646
  if (at < 0) continue;
88718
89647
  const property = declaration.slice(0, at).trim().toLowerCase();
@@ -88731,6 +89660,8 @@ function negated(value) {
88731
89660
  }
88732
89661
  function equivalents({ property, value }) {
88733
89662
  if ((property === "grid-column" || property === "grid-row") && /^span \d+$/.test(value)) return [value, `${value} / ${value}`];
89663
+ const px = /^(-?(?:\d+(?:\.\d+)?|\.\d+))px$/.exec(value);
89664
+ if (px) return [value, `${Number(px[1]) / 16}rem`];
88734
89665
  return [value];
88735
89666
  }
88736
89667
  function stampedLayerProps({ el, layers }) {
@@ -88872,195 +89803,6 @@ function asArray(list) {
88872
89803
  return Array.from(list);
88873
89804
  }
88874
89805
 
88875
- // ../config/dist/entities/system/Icon.js
88876
- var iconVariantAs = external_exports.union([external_exports.strictObject({ prop: external_exports.string().min(1) }), external_exports.strictObject({ export: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)) })]);
88877
- var Icon = defineEntity({
88878
- kind: "icon",
88879
- label: "Icon",
88880
- labelPlural: "Icons",
88881
- fields: iconMemberMetadata,
88882
- groupFields: external_exports.strictObject({
88883
- /** The package the glyphs come from — a REF to the `Package` item, which owns the module
88884
- * specifier (its path) and the pinned version. A generated module imports the glyphs it renders
88885
- * from it, and a render that imports a member of it is placing a glyph of this set. */
88886
- package: Package.optional().describe("The npm package the set comes from."),
88887
- /** Where member metadata comes from and how to read it — `{ from, format }`. The build resolves
88888
- * the source and bakes each member's fields; see `icon-metadata.ts`. */
88889
- metadata: iconMetadataDeclaration.optional().describe("Catalogue metadata read from the package."),
88890
- /** Named sizes the set ships (`sm: 16`).
88891
- * @deprecated How a glyph is sized is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
88892
- sizes: external_exports.record(external_exports.string(), external_exports.number()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
88893
- /** Weights/styles the set ships (`regular`, `fill`).
88894
- * @deprecated Which styles a glyph takes is the icon tool's component's business: the icon tool's component declares its own `size` and `variant` props, and every surface reads those. TODO: remove with a migration once no surface reads the library's copy. */
88895
- variants: external_exports.array(external_exports.string()).optional().describe("Deprecated. The icon tool's component declares its own `size` and `variant` props."),
88896
- /** How a variant reaches the glyph; see {@link iconVariantAs}. Absent, a variant is dropped at
88897
- * render.
88898
- * @deprecated Only the framework's raw-draw path read it; the icon tool's component passes a
88899
- * variant the way its package wants, and a set whose styles are separate exports lists them as
88900
- * members. TODO: remove with `sizes` and `variants`. */
88901
- variantAs: iconVariantAs.optional().describe("Deprecated. The icon tool's component passes a variant the way its package wants.")
88902
- }),
88903
- groupComputed: {
88904
- /** The glyphs the set ships, by leaf name. */
88905
- members: ({ config: config2, path: path2 }) => config2.members("icon", path2).map((member) => member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path),
88906
- /** The module the glyphs import from: the named package's path. `pathOf` drops a source
88907
- * qualifier, so a borrowed set's module is still the bare specifier. */
88908
- module: ({ meta: meta3 }) => isRef2(meta3.package) ? pathOf2(meta3.package) : void 0,
88909
- /** The version the named package pins, resolved through the ref in whichever config holds the
88910
- * package row. */
88911
- version: ({ config: config2, meta: meta3 }) => {
88912
- if (!isRef2(meta3.package)) return void 0;
88913
- const pinned = config2.resolveRef(meta3.package)?.toJSON();
88914
- return typeof pinned?.version === "string" ? pinned.version : void 0;
88915
- }
88916
- },
88917
- groupInputs: {
88918
- /**
88919
- * The package's module namespace. The set's members are its glyph exports, named by the rule
88920
- * the metadata format declares (`glyphExportRule`), so an alias pair is one member and the
88921
- * package's infrastructure exports are none; `items` lays facts over members that exist, and a
88922
- * key naming no member is refused so a typo cannot invent a glyph. Each member's identity is
88923
- * recorded by reference, so an authored glyph (`name={StarIcon}`) is matched to its member by
88924
- * the object rather than by anything the component says about itself, and an alias resolves to
88925
- * the member it is. Read once while the config file is evaluated and never stored.
88926
- */
88927
- glyphs: ({ input: input2, body }) => {
88928
- if (!isRef2(body.package)) throw new Error("Icon.group: `glyphs` needs `package` on the same group, since a glyph is identified as an export of that module.");
88929
- const format = iconMetadataFormat.safeParse(body.metadata?.format);
88930
- const members2 = glyphMembersOf({
88931
- namespace: input2,
88932
- format: format.success ? format.data : void 0
88933
- });
88934
- const overlay = body.items ?? {};
88935
- const unknown2 = Object.keys(overlay).filter((name) => !members2.includes(name));
88936
- if (unknown2.length > 0) throw new Error(`Icon.group: \`items\` names ${spellValues(unknown2)}, which ${unknown2.length === 1 ? "is not a glyph export" : "are not glyph exports"} of \`glyphs\`${members2.length === 0 ? " (the namespace has no glyph components; the package may not be installed)" : ""}. \`items\` lays facts over the members the package exports; it cannot add one.`);
88937
- recordGlyphIdentities({
88938
- namespace: input2,
88939
- names: members2,
88940
- specifier: pathOf2(body.package)
88941
- });
88942
- return { items: Object.fromEntries(members2.map((name) => [name, overlay[name] ?? {}])) };
88943
- }
88944
- },
88945
- /**
88946
- * A value bound to a library may be the glyph component itself, or the `package:` export ref the
88947
- * open-bag pass turned it into. Either is answered as the member name when the export is one of
88948
- * this library's and comes from the module its `package` names.
88949
- */
88950
- authoredValue: ({ config: config2, target: target2, leaves: leaves2 }) => glyphOfLibrary(libraryGlyphFacts({
88951
- config: config2,
88952
- target: target2,
88953
- leaves: leaves2
88954
- })),
88955
- invariants: (config2) => iconDomainInvariants(config2)
88956
- });
88957
-
88958
- // ../config/dist/entities/system/icon-library.js
88959
- var EMPTY_CATEGORIES = Object.freeze([]);
88960
- var EMPTY_SIZES = Object.freeze({});
88961
- var EMPTY_VARIANTS = Object.freeze([]);
88962
- function iconLibrary(config2, path2) {
88963
- if (!config2) return void 0;
88964
- const cache = librariesOf(config2);
88965
- if (cache.has(path2)) return cache.get(path2);
88966
- const library = readIconLibrary(config2, path2);
88967
- cache.set(path2, library);
88968
- return library;
88969
- }
88970
- var librariesOf = createSliceMemo({
88971
- kinds: [
88972
- "icon",
88973
- "component",
88974
- "package"
88975
- ],
88976
- compute: (_config) => /* @__PURE__ */ new Map()
88977
- });
88978
- function readIconLibrary(config2, path2) {
88979
- const group = Icon.groups(config2).find((entry) => entry.path === path2);
88980
- if (!group) return void 0;
88981
- const { items: _items, sizes, variants: variants2, ...meta3 } = group.meta;
88982
- const set2 = setMembers({
88983
- config: config2,
88984
- path: path2,
88985
- declared: variants2
88986
- });
88987
- return {
88988
- ...meta3,
88989
- path: path2,
88990
- members: set2.members,
88991
- sizes: sizes ?? EMPTY_SIZES,
88992
- variants: variants2 ?? EMPTY_VARIANTS,
88993
- ...set2.memberVariants ? { memberVariants: set2.memberVariants } : {},
88994
- ...componentDefaults({
88995
- config: config2,
88996
- library: path2
88997
- })
88998
- };
88999
- }
89000
- function componentDefaults({ config: config2, library }) {
89001
- const bound = glyphComponentOf(config2, library);
89002
- if (!bound) return {};
89003
- const defaults = Component.get(config2, bound.path)?.defaultProps;
89004
- const variant = defaults?.variant;
89005
- const size = defaults?.size;
89006
- return {
89007
- ...typeof variant === "string" ? { defaultVariant: variant } : {},
89008
- ...typeof size === "string" ? { defaultSizeKey: size } : {}
89009
- };
89010
- }
89011
- var membersOf = createSliceMemo({
89012
- kinds: ["icon"],
89013
- compute: (_config) => /* @__PURE__ */ new Map()
89014
- });
89015
- function setMembers({ config: config2, path: path2, declared: declared2 }) {
89016
- const walked = membersOf(config2);
89017
- const hit = walked.get(path2);
89018
- if (hit) return hit;
89019
- const members2 = [];
89020
- const memberVariants = {};
89021
- for (const member of config2.members("icon", path2)) {
89022
- const leaf = member.path.startsWith(`${path2}/`) ? member.path.slice(path2.length + 1) : member.path;
89023
- members2.push(leaf);
89024
- const own2 = ownVariantsOf(member.body);
89025
- if (own2 && own2.length > 0 && !sameVariants({
89026
- own: own2,
89027
- declared: declared2
89028
- })) memberVariants[leaf] = own2;
89029
- }
89030
- const set2 = {
89031
- members: members2,
89032
- ...Object.keys(memberVariants).length > 0 ? { memberVariants } : {}
89033
- };
89034
- walked.set(path2, set2);
89035
- return set2;
89036
- }
89037
- function ownVariantsOf(body) {
89038
- const declared2 = body.variants;
89039
- if (!Array.isArray(declared2)) return void 0;
89040
- return declared2.filter((variant) => typeof variant === "string");
89041
- }
89042
- function sameVariants({ own: own2, declared: declared2 }) {
89043
- if (!declared2 || declared2.length !== own2.length) return false;
89044
- const set2 = new Set(declared2);
89045
- return own2.every((variant) => set2.has(variant));
89046
- }
89047
- var allLibrariesOf = createSliceMemo({
89048
- kinds: [
89049
- "icon",
89050
- "component",
89051
- "package"
89052
- ],
89053
- compute: (config2) => Icon.groups(config2).map(({ path: path2 }) => iconLibrary(config2, path2)).filter((library) => library !== void 0)
89054
- });
89055
- var boundLibrariesOf = createSliceMemo({
89056
- kinds: [
89057
- "component",
89058
- "icon",
89059
- "package"
89060
- ],
89061
- compute: (_config) => /* @__PURE__ */ new Map()
89062
- });
89063
-
89064
89806
  // ../config/dist/entities/canvas/node-patches.js
89065
89807
  function attachedSystem(config2) {
89066
89808
  const [source] = config2.list("system-source");
@@ -89862,7 +90604,7 @@ var Entity = class {
89862
90604
  };
89863
90605
 
89864
90606
  // ../config/dist/framework/schema-version.js
89865
- var CURRENT_SCHEMA_VERSION = 20261103115059;
90607
+ var CURRENT_SCHEMA_VERSION = 20261104151013;
89866
90608
  var SETTINGS_AS_KIND_VERSION = 20260908171448;
89867
90609
  var SchemaVersionTooNew = class extends ConfigFormatError {
89868
90610
  found;
@@ -89882,7 +90624,7 @@ function registerSchemaMigrations(...migrations) {
89882
90624
  for (const migration of migrations) {
89883
90625
  if (migration.version !== 1 && !isMintTimestamp(migration.version)) throw new Error(`Schema migration version ${migration.version} is not a mint timestamp \u2014 mint one with \`date +%Y%m%d%H%M%S\`, like a supabase migration.`);
89884
90626
  if (REGISTERED.has(migration.version)) throw new Error(`A schema migration at version ${migration.version} is already registered.`);
89885
- if (migration.version > 20261103115059) throw new Error(`Schema migration ${migration.version} is newer than CURRENT_SCHEMA_VERSION (${CURRENT_SCHEMA_VERSION}) \u2014 a stale branch merged, or the mint forgot to bump the constant. Re-mint: set CURRENT_SCHEMA_VERSION to the newest migration version.`);
90627
+ if (migration.version > 20261104151013) throw new Error(`Schema migration ${migration.version} is newer than CURRENT_SCHEMA_VERSION (${CURRENT_SCHEMA_VERSION}) \u2014 a stale branch merged, or the mint forgot to bump the constant. Re-mint: set CURRENT_SCHEMA_VERSION to the newest migration version.`);
89886
90628
  REGISTERED.set(migration.version, migration);
89887
90629
  }
89888
90630
  }
@@ -89913,7 +90655,7 @@ function pendingFor(version2, target2, options) {
89913
90655
  return [...(options?.migrations ?? REGISTERED).values()].filter((m) => m.version > version2 && m.version <= target2).sort((a, b) => a.version - b.version);
89914
90656
  }
89915
90657
  function upgradeSerializedConfig(json2, options) {
89916
- const target2 = options?.target ?? 20261103115059;
90658
+ const target2 = options?.target ?? 20261104151013;
89917
90659
  const version2 = detectedWireVersion(json2);
89918
90660
  if (version2 > target2) throw new SchemaVersionTooNew(version2, target2);
89919
90661
  const raw = json2;
@@ -96813,7 +97555,7 @@ var Config = class Config2 {
96813
97555
  * links from the provided sources. A declared `linkedKind` with no provided source throws. */
96814
97556
  hydrateFrom(stored, options) {
96815
97557
  const claimed = schemaVersionOf(stored);
96816
- if (claimed > 20261103115059) throw new SchemaVersionTooNew(claimed);
97558
+ if (claimed > 20261104151013) throw new SchemaVersionTooNew(claimed);
96817
97559
  const wire = upgradeSerializedConfig(stored);
96818
97560
  if (!Array.isArray(wire.ownedKinds) || typeof wire.items !== "object" || wire.items === null) throw new ConfigFormatError(`Config "${stored.name ?? "system-config"}" cannot be hydrated: this is not a serialized config-v2 config (no "ownedKinds"/"items"). A pre-cutover build artifact converts through the registered cutover migration \u2014 import the config type's module (e.g. \`configs/system\`) before hydrating.`);
96819
97561
  const leftover = wire.options;
@@ -100450,6 +101192,15 @@ var sourcesAuthoringMigration = {
100450
101192
  }
100451
101193
  };
100452
101194
 
101195
+ // ../config/dist/migrations/20261104151013_build_debug.js
101196
+ var BUILD_DEBUG_VERSION = 20261104151013;
101197
+ var buildDebugMigration = {
101198
+ version: BUILD_DEBUG_VERSION,
101199
+ up(json2) {
101200
+ return json2;
101201
+ }
101202
+ };
101203
+
100453
101204
  // ../../node_modules/css-tree/lib/generator/sourceMap.js
100454
101205
  var import_source_map_generator = __toESM(require_source_map_generator(), 1);
100455
101206
  var trackNodes = /* @__PURE__ */ new Set(["Atrule", "Selector", "Declaration"]);
@@ -103194,6 +103945,7 @@ if (!registeredSchemaMigrations().has(20261102143821)) registerSchemaMigrations(
103194
103945
  if (!registeredSchemaMigrations().has(20261102185610)) registerSchemaMigrations(linkReplaceMigration);
103195
103946
  if (!registeredSchemaMigrations().has(20261102193912)) registerSchemaMigrations(mapPropsFromMigration);
103196
103947
  if (!registeredSchemaMigrations().has(20261103115059)) registerSchemaMigrations(sourcesAuthoringMigration);
103948
+ if (!registeredSchemaMigrations().has(20261104151013)) registerSchemaMigrations(buildDebugMigration);
103197
103949
 
103198
103950
  // ../config/dist/capture/node-ops.js
103199
103951
  var DEFAULT_WIDTH = 1600;