@zoahhq/cli 0.1.4 → 0.1.5

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +1708 -1109
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -7232,8 +7232,8 @@ function expandBoxShorthand(raw) {
7232
7232
  return { top: all, right: all, bottom: all, left: all };
7233
7233
  }
7234
7234
  if (parts.length === 2) {
7235
- const [v14, h4] = parts;
7236
- return { top: v14, right: h4, bottom: v14, left: h4 };
7235
+ const [v15, h4] = parts;
7236
+ return { top: v15, right: h4, bottom: v15, left: h4 };
7237
7237
  }
7238
7238
  if (parts.length === 3) {
7239
7239
  const [t3, h4, b4] = parts;
@@ -7271,17 +7271,17 @@ function parseBorderShorthand(raw, ctx, property) {
7271
7271
  return result;
7272
7272
  }
7273
7273
  function looksLikeColor(value) {
7274
- const v14 = value.trim().toLowerCase();
7275
- if (v14 === "")
7274
+ const v15 = value.trim().toLowerCase();
7275
+ if (v15 === "")
7276
7276
  return false;
7277
- if (v14.startsWith("#"))
7277
+ if (v15.startsWith("#"))
7278
7278
  return true;
7279
- if (v14.startsWith("rgb(") || v14.startsWith("rgba(") || v14.startsWith("hsl(") || v14.startsWith("hsla(") || v14.startsWith("oklch(") || v14.startsWith("oklab(") || v14.startsWith("color(") || v14.startsWith("hwb(")) {
7279
+ if (v15.startsWith("rgb(") || v15.startsWith("rgba(") || v15.startsWith("hsl(") || v15.startsWith("hsla(") || v15.startsWith("oklch(") || v15.startsWith("oklab(") || v15.startsWith("color(") || v15.startsWith("hwb(")) {
7280
7280
  return true;
7281
7281
  }
7282
- if (COLOR_KEYWORDS.has(v14))
7282
+ if (COLOR_KEYWORDS.has(v15))
7283
7283
  return true;
7284
- if (/^[a-z]+$/.test(v14) && v14.length > 2)
7284
+ if (/^[a-z]+$/.test(v15) && v15.length > 2)
7285
7285
  return true;
7286
7286
  return false;
7287
7287
  }
@@ -7357,30 +7357,30 @@ function mapToNodeLayout(css, ctx) {
7357
7357
  out.visibility = "none";
7358
7358
  break;
7359
7359
  }
7360
- const v14 = isOneOf(value, Object.values(LayoutTypes));
7361
- if (v14) {
7362
- out.display = v14;
7360
+ const v15 = isOneOf(value, Object.values(LayoutTypes));
7361
+ if (v15) {
7362
+ out.display = v15;
7363
7363
  } else {
7364
7364
  pushIssue(ctx, "CSS_DISPLAY_VALUE_UNSUPPORTED", `Unsupported display value: "${value}"`);
7365
7365
  }
7366
7366
  break;
7367
7367
  }
7368
7368
  case "visibility": {
7369
- const v14 = isOneOf(value, Object.values(VisibilityTypes));
7370
- if (v14)
7371
- out.visibility = v14;
7369
+ const v15 = isOneOf(value, Object.values(VisibilityTypes));
7370
+ if (v15)
7371
+ out.visibility = v15;
7372
7372
  break;
7373
7373
  }
7374
7374
  case "flex-direction": {
7375
- const v14 = isOneOf(value, Object.values(FlexDirectionTypes));
7376
- if (v14)
7377
- out.flexDirection = v14;
7375
+ const v15 = isOneOf(value, Object.values(FlexDirectionTypes));
7376
+ if (v15)
7377
+ out.flexDirection = v15;
7378
7378
  break;
7379
7379
  }
7380
7380
  case "flex-wrap": {
7381
- const v14 = isOneOf(value, Object.values(FlexWrapTypes));
7382
- if (v14)
7383
- out.flexWrap = v14;
7381
+ const v15 = isOneOf(value, Object.values(FlexWrapTypes));
7382
+ if (v15)
7383
+ out.flexWrap = v15;
7384
7384
  break;
7385
7385
  }
7386
7386
  case "flex-grow": {
@@ -7416,27 +7416,27 @@ function mapToNodeLayout(css, ctx) {
7416
7416
  break;
7417
7417
  }
7418
7418
  case "justify-content": {
7419
- const v14 = isOneOf(value, Object.values(JustifyContentTypes));
7420
- if (v14)
7421
- out.justifyContent = v14;
7419
+ const v15 = isOneOf(value, Object.values(JustifyContentTypes));
7420
+ if (v15)
7421
+ out.justifyContent = v15;
7422
7422
  break;
7423
7423
  }
7424
7424
  case "justify-items": {
7425
- const v14 = isOneOf(value, Object.values(JustifyItemsTypes));
7426
- if (v14)
7427
- out.justifyItems = v14;
7425
+ const v15 = isOneOf(value, Object.values(JustifyItemsTypes));
7426
+ if (v15)
7427
+ out.justifyItems = v15;
7428
7428
  break;
7429
7429
  }
7430
7430
  case "align-content": {
7431
- const v14 = isOneOf(value, Object.values(JustifyContentTypes));
7432
- if (v14)
7433
- out.alignContent = v14;
7431
+ const v15 = isOneOf(value, Object.values(JustifyContentTypes));
7432
+ if (v15)
7433
+ out.alignContent = v15;
7434
7434
  break;
7435
7435
  }
7436
7436
  case "align-items": {
7437
- const v14 = isOneOf(value, Object.values(JustifyItemsTypes));
7438
- if (v14)
7439
- out.alignItems = v14;
7437
+ const v15 = isOneOf(value, Object.values(JustifyItemsTypes));
7438
+ if (v15)
7439
+ out.alignItems = v15;
7440
7440
  break;
7441
7441
  }
7442
7442
  case "gap": {
@@ -7740,10 +7740,10 @@ function mapToNodeAppearance(css, ctx) {
7740
7740
  const expanded = expandBoxShorthand(value);
7741
7741
  const sides = ["top", "right", "bottom", "left"];
7742
7742
  for (const side of sides) {
7743
- const v14 = expanded[side];
7744
- if (v14 === void 0)
7743
+ const v15 = expanded[side];
7744
+ if (v15 === void 0)
7745
7745
  continue;
7746
- const s5 = isOneOf(v14, Object.values(BorderStyles));
7746
+ const s5 = isOneOf(v15, Object.values(BorderStyles));
7747
7747
  if (s5)
7748
7748
  setBorderStyle(side, s5);
7749
7749
  }
@@ -7836,9 +7836,9 @@ function mapToNodeAppearance(css, ctx) {
7836
7836
  break;
7837
7837
  }
7838
7838
  case "cursor": {
7839
- const v14 = isOneOf(value, Object.values(CursorTypes));
7840
- if (v14)
7841
- out.cursor = v14;
7839
+ const v15 = isOneOf(value, Object.values(CursorTypes));
7840
+ if (v15)
7841
+ out.cursor = v15;
7842
7842
  else
7843
7843
  pushIssue(ctx, "CSS_CURSOR_VALUE_UNSUPPORTED", `Unsupported cursor value: "${value}"`);
7844
7844
  break;
@@ -7867,9 +7867,9 @@ function mapToNodeAppearance(css, ctx) {
7867
7867
  break;
7868
7868
  }
7869
7869
  case "font-style": {
7870
- const v14 = isOneOf(value, Object.values(FontStyleTypes));
7871
- if (v14)
7872
- text.fontStyle = v14;
7870
+ const v15 = isOneOf(value, Object.values(FontStyleTypes));
7871
+ if (v15)
7872
+ text.fontStyle = v15;
7873
7873
  break;
7874
7874
  }
7875
7875
  case "line-height": {
@@ -7890,27 +7890,27 @@ function mapToNodeAppearance(css, ctx) {
7890
7890
  break;
7891
7891
  }
7892
7892
  case "text-align": {
7893
- const v14 = isOneOf(value, Object.values(TextAlignTypes));
7894
- if (v14)
7895
- text.textAlign = v14;
7893
+ const v15 = isOneOf(value, Object.values(TextAlignTypes));
7894
+ if (v15)
7895
+ text.textAlign = v15;
7896
7896
  break;
7897
7897
  }
7898
7898
  case "text-transform": {
7899
- const v14 = isOneOf(value, Object.values(TextTransformTypes));
7900
- if (v14)
7901
- text.textTransform = v14;
7899
+ const v15 = isOneOf(value, Object.values(TextTransformTypes));
7900
+ if (v15)
7901
+ text.textTransform = v15;
7902
7902
  break;
7903
7903
  }
7904
7904
  case "text-overflow": {
7905
- const v14 = isOneOf(value, Object.values(TextOverflowTypes));
7906
- if (v14)
7907
- text.textOverflow = v14;
7905
+ const v15 = isOneOf(value, Object.values(TextOverflowTypes));
7906
+ if (v15)
7907
+ text.textOverflow = v15;
7908
7908
  break;
7909
7909
  }
7910
7910
  case "white-space": {
7911
- const v14 = isOneOf(value, Object.values(WhiteSpaceTypes));
7912
- if (v14)
7913
- text.whiteSpace = v14;
7911
+ const v15 = isOneOf(value, Object.values(WhiteSpaceTypes));
7912
+ if (v15)
7913
+ text.whiteSpace = v15;
7914
7914
  break;
7915
7915
  }
7916
7916
  default:
@@ -7942,9 +7942,9 @@ function mapToNodePosition(css, ctx) {
7942
7942
  continue;
7943
7943
  switch (key) {
7944
7944
  case "position": {
7945
- const v14 = isOneOf(value, Object.values(PositionTypes));
7946
- if (v14)
7947
- out.type = v14;
7945
+ const v15 = isOneOf(value, Object.values(PositionTypes));
7946
+ if (v15)
7947
+ out.type = v15;
7948
7948
  else
7949
7949
  pushIssue(ctx, "CSS_POSITION_VALUE_UNSUPPORTED", `Unsupported position value: "${value}"`);
7950
7950
  break;
@@ -7974,23 +7974,23 @@ function mapToNodePosition(css, ctx) {
7974
7974
  break;
7975
7975
  }
7976
7976
  case "overflow": {
7977
- const v14 = isOneOf(value, Object.values(OverflowTypes));
7978
- if (v14) {
7979
- out.overflowX = v14;
7980
- out.overflowY = v14;
7977
+ const v15 = isOneOf(value, Object.values(OverflowTypes));
7978
+ if (v15) {
7979
+ out.overflowX = v15;
7980
+ out.overflowY = v15;
7981
7981
  }
7982
7982
  break;
7983
7983
  }
7984
7984
  case "overflow-x": {
7985
- const v14 = isOneOf(value, Object.values(OverflowTypes));
7986
- if (v14)
7987
- out.overflowX = v14;
7985
+ const v15 = isOneOf(value, Object.values(OverflowTypes));
7986
+ if (v15)
7987
+ out.overflowX = v15;
7988
7988
  break;
7989
7989
  }
7990
7990
  case "overflow-y": {
7991
- const v14 = isOneOf(value, Object.values(OverflowTypes));
7992
- if (v14)
7993
- out.overflowY = v14;
7991
+ const v15 = isOneOf(value, Object.values(OverflowTypes));
7992
+ if (v15)
7993
+ out.overflowY = v15;
7994
7994
  break;
7995
7995
  }
7996
7996
  case "z-index": {
@@ -24401,7 +24401,7 @@ function detectActiveExportCondition(packageRoot, resolvedAbs) {
24401
24401
  const pkg = readPackageJson(packageRoot);
24402
24402
  const exportsField = pkg?.exports;
24403
24403
  if (!exportsField || typeof exportsField !== "object") return null;
24404
- const isConditionMap = (v14) => typeof v14 === "object" && v14 !== null && !Array.isArray(v14);
24404
+ const isConditionMap = (v15) => typeof v15 === "object" && v15 !== null && !Array.isArray(v15);
24405
24405
  function valueMatches(value) {
24406
24406
  if (typeof value === "string") {
24407
24407
  const abs = resolve3(packageRoot, value);
@@ -25114,7 +25114,7 @@ function readRootVars(cssPaths) {
25114
25114
  const vars = /* @__PURE__ */ new Map();
25115
25115
  for (const path4 of cssPaths) {
25116
25116
  const text = safeRead(path4);
25117
- if (text) for (const [k, v14] of parseRootVars(text)) vars.set(k, v14);
25117
+ if (text) for (const [k, v15] of parseRootVars(text)) vars.set(k, v15);
25118
25118
  }
25119
25119
  return vars;
25120
25120
  }
@@ -25156,8 +25156,8 @@ function parseThemeColorTokens(cssPaths) {
25156
25156
  for (const path4 of cssPaths) {
25157
25157
  const text = safeRead(path4);
25158
25158
  if (!text) continue;
25159
- for (const [k, v14] of parseRootVars(text)) rootVars.set(k, v14);
25160
- for (const [k, v14] of parseThemeColorMap(text)) themeColors.set(k, v14);
25159
+ for (const [k, v15] of parseRootVars(text)) rootVars.set(k, v15);
25160
+ for (const [k, v15] of parseThemeColorMap(text)) themeColors.set(k, v15);
25161
25161
  }
25162
25162
  const names = themeColors.size > 0 ? themeColors : new Map(rootVars);
25163
25163
  const out = [];
@@ -25174,10 +25174,10 @@ function parseThemeColorTokens(cssPaths) {
25174
25174
  return out;
25175
25175
  }
25176
25176
  function isColorValue(value) {
25177
- const v14 = value.trim().toLowerCase();
25178
- if (v14.startsWith("#")) return true;
25179
- if (/^(rgb|rgba|hsl|hsla|oklch|oklab|color|hwb)\(/.test(v14)) return true;
25180
- return CSS_NAMED_COLORS.has(v14);
25177
+ const v15 = value.trim().toLowerCase();
25178
+ if (v15.startsWith("#")) return true;
25179
+ if (/^(rgb|rgba|hsl|hsla|oklch|oklab|color|hwb)\(/.test(v15)) return true;
25180
+ return CSS_NAMED_COLORS.has(v15);
25181
25181
  }
25182
25182
  var CSS_ENTRY_CANDIDATES, CSS_NAMED_COLORS;
25183
25183
  var init_tailwind_tokens = __esm({
@@ -25301,14 +25301,14 @@ function ruleToCss(rule, getVar) {
25301
25301
  return Object.keys(out).length > 0 ? out : null;
25302
25302
  }
25303
25303
  function resolveValue(value, getVar) {
25304
- let v14 = value.trim();
25305
- const mix = /^color-mix\([^,]+,\s*(.+?)\s+\d+(?:\.\d+)?%\s*,/.exec(v14);
25306
- if (mix) v14 = mix[1].trim();
25307
- v14 = substituteVars(v14, getVar);
25308
- if (v14.includes("var(")) return null;
25309
- if (v14.startsWith("calc(")) return evalCalc(v14);
25310
- if (v14.includes("calc(") || v14.includes("color-mix(")) return null;
25311
- return v14;
25304
+ let v15 = value.trim();
25305
+ const mix = /^color-mix\([^,]+,\s*(.+?)\s+\d+(?:\.\d+)?%\s*,/.exec(v15);
25306
+ if (mix) v15 = mix[1].trim();
25307
+ v15 = substituteVars(v15, getVar);
25308
+ if (v15.includes("var(")) return null;
25309
+ if (v15.startsWith("calc(")) return evalCalc(v15);
25310
+ if (v15.includes("calc(") || v15.includes("color-mix(")) return null;
25311
+ return v15;
25312
25312
  }
25313
25313
  function substituteVars(value, getVar) {
25314
25314
  return value.replace(
@@ -25340,11 +25340,11 @@ function evalCalc(value) {
25340
25340
  return null;
25341
25341
  }
25342
25342
  function resolveThemeValue(raw, getVar) {
25343
- const v14 = substituteVars(raw, getVar);
25344
- if (v14.includes("var(")) return null;
25345
- if (v14.startsWith("calc(")) return evalCalc(v14);
25346
- if (v14.includes("calc(")) return null;
25347
- return v14;
25343
+ const v15 = substituteVars(raw, getVar);
25344
+ if (v15.includes("var(")) return null;
25345
+ if (v15.startsWith("calc(")) return evalCalc(v15);
25346
+ if (v15.includes("calc(")) return null;
25347
+ return v15;
25348
25348
  }
25349
25349
  function themeFromDesignSystem(ds, getVar) {
25350
25350
  const theme = {};
@@ -25519,8 +25519,8 @@ function resolveColor(theme, token) {
25519
25519
  const colors = theme.colors;
25520
25520
  if (!colors) return void 0;
25521
25521
  if (token in colors) {
25522
- const v14 = colors[token];
25523
- if (typeof v14 === "string") return v14;
25522
+ const v15 = colors[token];
25523
+ if (typeof v15 === "string") return v15;
25524
25524
  }
25525
25525
  const dashIdx = token.indexOf("-");
25526
25526
  if (dashIdx > 0) {
@@ -25644,12 +25644,12 @@ function looksLikeColorValue(value) {
25644
25644
  function classToCss(className, theme) {
25645
25645
  if (className in STATIC_CLASS_TABLE) return STATIC_CLASS_TABLE[className];
25646
25646
  if (className === "rounded") {
25647
- const v14 = resolveBorderRadius(theme, "DEFAULT");
25648
- return v14 ? { "border-radius": v14 } : null;
25647
+ const v15 = resolveBorderRadius(theme, "DEFAULT");
25648
+ return v15 ? { "border-radius": v15 } : null;
25649
25649
  }
25650
25650
  if (className === "border") {
25651
- const v14 = resolveBorderWidth(theme, "DEFAULT") ?? "1px";
25652
- return { "border-width": v14, "border-style": "solid" };
25651
+ const v15 = resolveBorderWidth(theme, "DEFAULT") ?? "1px";
25652
+ return { "border-width": v15, "border-style": "solid" };
25653
25653
  }
25654
25654
  if (className === "shadow") {
25655
25655
  return { "box-shadow": theme.boxShadow?.DEFAULT ?? SHADOW_TABLE.DEFAULT };
@@ -25687,64 +25687,64 @@ function classToCss(className, theme) {
25687
25687
  }
25688
25688
  switch (prefix) {
25689
25689
  case "p": {
25690
- const v14 = resolveSpacing(theme, arg);
25691
- return v14 ? { padding: v14 } : null;
25690
+ const v15 = resolveSpacing(theme, arg);
25691
+ return v15 ? { padding: v15 } : null;
25692
25692
  }
25693
25693
  case "px": {
25694
- const v14 = resolveSpacing(theme, arg);
25695
- return v14 ? { "padding-left": v14, "padding-right": v14 } : null;
25694
+ const v15 = resolveSpacing(theme, arg);
25695
+ return v15 ? { "padding-left": v15, "padding-right": v15 } : null;
25696
25696
  }
25697
25697
  case "py": {
25698
- const v14 = resolveSpacing(theme, arg);
25699
- return v14 ? { "padding-top": v14, "padding-bottom": v14 } : null;
25698
+ const v15 = resolveSpacing(theme, arg);
25699
+ return v15 ? { "padding-top": v15, "padding-bottom": v15 } : null;
25700
25700
  }
25701
25701
  case "pt": {
25702
- const v14 = resolveSpacing(theme, arg);
25703
- return v14 ? { "padding-top": v14 } : null;
25702
+ const v15 = resolveSpacing(theme, arg);
25703
+ return v15 ? { "padding-top": v15 } : null;
25704
25704
  }
25705
25705
  case "pr": {
25706
- const v14 = resolveSpacing(theme, arg);
25707
- return v14 ? { "padding-right": v14 } : null;
25706
+ const v15 = resolveSpacing(theme, arg);
25707
+ return v15 ? { "padding-right": v15 } : null;
25708
25708
  }
25709
25709
  case "pb": {
25710
- const v14 = resolveSpacing(theme, arg);
25711
- return v14 ? { "padding-bottom": v14 } : null;
25710
+ const v15 = resolveSpacing(theme, arg);
25711
+ return v15 ? { "padding-bottom": v15 } : null;
25712
25712
  }
25713
25713
  case "pl": {
25714
- const v14 = resolveSpacing(theme, arg);
25715
- return v14 ? { "padding-left": v14 } : null;
25714
+ const v15 = resolveSpacing(theme, arg);
25715
+ return v15 ? { "padding-left": v15 } : null;
25716
25716
  }
25717
25717
  case "m": {
25718
- const v14 = resolveSpacing(theme, arg);
25719
- return v14 ? { margin: v14 } : null;
25718
+ const v15 = resolveSpacing(theme, arg);
25719
+ return v15 ? { margin: v15 } : null;
25720
25720
  }
25721
25721
  case "mx": {
25722
- const v14 = resolveSpacing(theme, arg);
25723
- return v14 ? { "margin-left": v14, "margin-right": v14 } : null;
25722
+ const v15 = resolveSpacing(theme, arg);
25723
+ return v15 ? { "margin-left": v15, "margin-right": v15 } : null;
25724
25724
  }
25725
25725
  case "my": {
25726
- const v14 = resolveSpacing(theme, arg);
25727
- return v14 ? { "margin-top": v14, "margin-bottom": v14 } : null;
25726
+ const v15 = resolveSpacing(theme, arg);
25727
+ return v15 ? { "margin-top": v15, "margin-bottom": v15 } : null;
25728
25728
  }
25729
25729
  case "mt": {
25730
- const v14 = resolveSpacing(theme, arg);
25731
- return v14 ? { "margin-top": v14 } : null;
25730
+ const v15 = resolveSpacing(theme, arg);
25731
+ return v15 ? { "margin-top": v15 } : null;
25732
25732
  }
25733
25733
  case "mr": {
25734
- const v14 = resolveSpacing(theme, arg);
25735
- return v14 ? { "margin-right": v14 } : null;
25734
+ const v15 = resolveSpacing(theme, arg);
25735
+ return v15 ? { "margin-right": v15 } : null;
25736
25736
  }
25737
25737
  case "mb": {
25738
- const v14 = resolveSpacing(theme, arg);
25739
- return v14 ? { "margin-bottom": v14 } : null;
25738
+ const v15 = resolveSpacing(theme, arg);
25739
+ return v15 ? { "margin-bottom": v15 } : null;
25740
25740
  }
25741
25741
  case "ml": {
25742
- const v14 = resolveSpacing(theme, arg);
25743
- return v14 ? { "margin-left": v14 } : null;
25742
+ const v15 = resolveSpacing(theme, arg);
25743
+ return v15 ? { "margin-left": v15 } : null;
25744
25744
  }
25745
25745
  case "gap": {
25746
- const v14 = resolveSpacing(theme, arg);
25747
- return v14 ? { gap: v14 } : null;
25746
+ const v15 = resolveSpacing(theme, arg);
25747
+ return v15 ? { gap: v15 } : null;
25748
25748
  }
25749
25749
  case "w": {
25750
25750
  if (arg === "screen") return { width: "100vw" };
@@ -25752,8 +25752,8 @@ function classToCss(className, theme) {
25752
25752
  if (kw) return { width: kw };
25753
25753
  const frac = resolveFraction(arg);
25754
25754
  if (frac) return { width: frac };
25755
- const v14 = resolveSpacing(theme, arg);
25756
- return v14 ? { width: v14 } : null;
25755
+ const v15 = resolveSpacing(theme, arg);
25756
+ return v15 ? { width: v15 } : null;
25757
25757
  }
25758
25758
  case "h": {
25759
25759
  if (arg === "screen") return { height: "100vh" };
@@ -25761,16 +25761,16 @@ function classToCss(className, theme) {
25761
25761
  if (kw) return { height: kw };
25762
25762
  const frac = resolveFraction(arg);
25763
25763
  if (frac) return { height: frac };
25764
- const v14 = resolveSpacing(theme, arg);
25765
- return v14 ? { height: v14 } : null;
25764
+ const v15 = resolveSpacing(theme, arg);
25765
+ return v15 ? { height: v15 } : null;
25766
25766
  }
25767
25767
  case "size": {
25768
25768
  const kw = sizingKeyword(arg);
25769
25769
  if (kw) return { width: kw, height: kw };
25770
25770
  const frac = resolveFraction(arg);
25771
25771
  if (frac) return { width: frac, height: frac };
25772
- const v14 = resolveSpacing(theme, arg);
25773
- return v14 ? { width: v14, height: v14 } : null;
25772
+ const v15 = resolveSpacing(theme, arg);
25773
+ return v15 ? { width: v15, height: v15 } : null;
25774
25774
  }
25775
25775
  case "cursor":
25776
25776
  return { cursor: arg };
@@ -25785,8 +25785,8 @@ function classToCss(className, theme) {
25785
25785
  if (rgba) return { "background-color": rgba };
25786
25786
  }
25787
25787
  }
25788
- const v14 = resolveColor(theme, arg) ?? resolveBaseColor(arg);
25789
- return v14 ? { "background-color": v14 } : null;
25788
+ const v15 = resolveColor(theme, arg) ?? resolveBaseColor(arg);
25789
+ return v15 ? { "background-color": v15 } : null;
25790
25790
  }
25791
25791
  case "text": {
25792
25792
  const size = resolveFontSize(theme, arg);
@@ -25817,8 +25817,8 @@ function classToCss(className, theme) {
25817
25817
  return null;
25818
25818
  }
25819
25819
  case "rounded": {
25820
- const v14 = resolveBorderRadius(theme, arg === "" ? "DEFAULT" : arg);
25821
- return v14 ? { "border-radius": v14 } : null;
25820
+ const v15 = resolveBorderRadius(theme, arg === "" ? "DEFAULT" : arg);
25821
+ return v15 ? { "border-radius": v15 } : null;
25822
25822
  }
25823
25823
  case "border": {
25824
25824
  const sideMap = {
@@ -25860,34 +25860,34 @@ function classToCss(className, theme) {
25860
25860
  return null;
25861
25861
  }
25862
25862
  case "top": {
25863
- const v14 = resolveSpacing(theme, arg);
25864
- return v14 ? { top: v14 } : null;
25863
+ const v15 = resolveSpacing(theme, arg);
25864
+ return v15 ? { top: v15 } : null;
25865
25865
  }
25866
25866
  case "right": {
25867
- const v14 = resolveSpacing(theme, arg);
25868
- return v14 ? { right: v14 } : null;
25867
+ const v15 = resolveSpacing(theme, arg);
25868
+ return v15 ? { right: v15 } : null;
25869
25869
  }
25870
25870
  case "bottom": {
25871
- const v14 = resolveSpacing(theme, arg);
25872
- return v14 ? { bottom: v14 } : null;
25871
+ const v15 = resolveSpacing(theme, arg);
25872
+ return v15 ? { bottom: v15 } : null;
25873
25873
  }
25874
25874
  case "left": {
25875
- const v14 = resolveSpacing(theme, arg);
25876
- return v14 ? { left: v14 } : null;
25875
+ const v15 = resolveSpacing(theme, arg);
25876
+ return v15 ? { left: v15 } : null;
25877
25877
  }
25878
25878
  case "inset": {
25879
25879
  const xMatch = /^x-(.+)$/.exec(arg);
25880
25880
  if (xMatch) {
25881
- const v15 = resolveSpacing(theme, xMatch[1]);
25882
- return v15 ? { left: v15, right: v15 } : null;
25881
+ const v16 = resolveSpacing(theme, xMatch[1]);
25882
+ return v16 ? { left: v16, right: v16 } : null;
25883
25883
  }
25884
25884
  const yMatch = /^y-(.+)$/.exec(arg);
25885
25885
  if (yMatch) {
25886
- const v15 = resolveSpacing(theme, yMatch[1]);
25887
- return v15 ? { top: v15, bottom: v15 } : null;
25886
+ const v16 = resolveSpacing(theme, yMatch[1]);
25887
+ return v16 ? { top: v16, bottom: v16 } : null;
25888
25888
  }
25889
- const v14 = resolveSpacing(theme, arg);
25890
- return v14 ? { top: v14, right: v14, bottom: v14, left: v14 } : null;
25889
+ const v15 = resolveSpacing(theme, arg);
25890
+ return v15 ? { top: v15, right: v15, bottom: v15, left: v15 } : null;
25891
25891
  }
25892
25892
  case "tracking": {
25893
25893
  const value = theme.letterSpacing?.[arg] ?? TRACKING_NAMED_TABLE[arg];
@@ -25911,8 +25911,8 @@ function classToCss(className, theme) {
25911
25911
  }
25912
25912
  if (sizeArg === "full") return { [property]: "100%" };
25913
25913
  if (sizeArg === "auto") return { [property]: "auto" };
25914
- const v14 = resolveSpacing(theme, sizeArg);
25915
- return v14 ? { [property]: v14 } : null;
25914
+ const v15 = resolveSpacing(theme, sizeArg);
25915
+ return v15 ? { [property]: v15 } : null;
25916
25916
  }
25917
25917
  case "max": {
25918
25918
  const m4 = /^([hw])-(.+)$/.exec(arg);
@@ -25925,8 +25925,8 @@ function classToCss(className, theme) {
25925
25925
  }
25926
25926
  if (sizeArg === "full") return { [property]: "100%" };
25927
25927
  if (sizeArg === "auto") return { [property]: "auto" };
25928
- const v14 = resolveSpacing(theme, sizeArg);
25929
- return v14 ? { [property]: v14 } : null;
25928
+ const v15 = resolveSpacing(theme, sizeArg);
25929
+ return v15 ? { [property]: v15 } : null;
25930
25930
  }
25931
25931
  case "flex": {
25932
25932
  if (arg in FLEX_SHORTHAND_TABLE) {
@@ -25977,17 +25977,17 @@ function classToCss(className, theme) {
25977
25977
  case "leading": {
25978
25978
  const named = theme.lineHeight?.[arg] ?? LEADING_NAMED_TABLE[arg];
25979
25979
  if (named) return { "line-height": named };
25980
- const v14 = resolveSpacing(theme, arg);
25981
- return v14 ? { "line-height": v14 } : null;
25980
+ const v15 = resolveSpacing(theme, arg);
25981
+ return v15 ? { "line-height": v15 } : null;
25982
25982
  }
25983
25983
  case "space": {
25984
25984
  const m4 = /^([xy])-(.+)$/.exec(arg);
25985
25985
  if (!m4) return null;
25986
25986
  const axis = m4[1];
25987
25987
  const sizeArg = m4[2];
25988
- const v14 = resolveSpacing(theme, sizeArg);
25989
- if (v14 === void 0) return null;
25990
- return axis === "x" ? { "column-gap": v14 } : { "row-gap": v14 };
25988
+ const v15 = resolveSpacing(theme, sizeArg);
25989
+ if (v15 === void 0) return null;
25990
+ return axis === "x" ? { "column-gap": v15 } : { "row-gap": v15 };
25991
25991
  }
25992
25992
  default:
25993
25993
  return null;
@@ -26507,9 +26507,9 @@ function payloadTypeForTsType(t3, genericNames) {
26507
26507
  let allStringLiterals = true;
26508
26508
  for (const m4 of members) {
26509
26509
  if (m4.isStringLiteral()) {
26510
- const v14 = m4.getLiteralValue();
26511
- if (v14 === "") continue;
26512
- literals.push(v14);
26510
+ const v15 = m4.getLiteralValue();
26511
+ if (v15 === "") continue;
26512
+ literals.push(v15);
26513
26513
  } else if (m4.getFlags() & TypeFlags.Undefined) {
26514
26514
  } else if (m4.getFlags() & TypeFlags.Null) {
26515
26515
  } else {
@@ -27189,8 +27189,8 @@ function declarationsFromRule(rule) {
27189
27189
  return out;
27190
27190
  }
27191
27191
  function mergeInto(target, source) {
27192
- for (const [k, v14] of Object.entries(source)) {
27193
- target[k] = v14;
27192
+ for (const [k, v15] of Object.entries(source)) {
27193
+ target[k] = v15;
27194
27194
  }
27195
27195
  }
27196
27196
  function parseCssClasses(absolutePath) {
@@ -27352,7 +27352,7 @@ function buildSourceFileResolverContext(sourceFile, emit) {
27352
27352
  for (const [cls, decls] of registry.classes) {
27353
27353
  const existing = globalCssClasses.get(cls);
27354
27354
  if (existing) {
27355
- for (const [k, v14] of Object.entries(decls)) existing[k] = v14;
27355
+ for (const [k, v15] of Object.entries(decls)) existing[k] = v15;
27356
27356
  } else {
27357
27357
  globalCssClasses.set(cls, { ...decls });
27358
27358
  }
@@ -27366,7 +27366,7 @@ function buildSourceFileResolverContext(sourceFile, emit) {
27366
27366
  for (const [pseudo, decls] of perPseudo) {
27367
27367
  const existingDecls = existing.get(pseudo);
27368
27368
  if (existingDecls) {
27369
- for (const [k, v14] of Object.entries(decls)) existingDecls[k] = v14;
27369
+ for (const [k, v15] of Object.entries(decls)) existingDecls[k] = v15;
27370
27370
  } else {
27371
27371
  existing.set(pseudo, { ...decls });
27372
27372
  }
@@ -27502,7 +27502,7 @@ function generateSlotPropName(slotName) {
27502
27502
  }
27503
27503
  function inferSlotName(ctx, hint) {
27504
27504
  const candidates = [hint.receiver, hint.leaf, hint.parentTag].filter(
27505
- (v14) => Boolean(v14 && v14.length > 0)
27505
+ (v15) => Boolean(v15 && v15.length > 0)
27506
27506
  );
27507
27507
  let base = candidates[0];
27508
27508
  if (!base) base = `slot${ctx.slots.length + 1}`;
@@ -28094,7 +28094,7 @@ function mergePropPseudoStyles(result, propName, perValuePseudo) {
28094
28094
  if (perValuePseudo.size === 0) return;
28095
28095
  const existing = result.propPseudoStyles.get(propName);
28096
28096
  if (existing) {
28097
- for (const [k, v14] of perValuePseudo) existing.set(k, v14);
28097
+ for (const [k, v15] of perValuePseudo) existing.set(k, v15);
28098
28098
  } else {
28099
28099
  result.propPseudoStyles.set(propName, new Map(perValuePseudo));
28100
28100
  }
@@ -28116,7 +28116,7 @@ function applySpanResolution(result, resolution) {
28116
28116
  if (resolution.kind === "variantOverrides") {
28117
28117
  const existing = result.variantOverrides.get(resolution.propName);
28118
28118
  if (existing) {
28119
- for (const [k, v14] of resolution.perValue) existing.set(k, v14);
28119
+ for (const [k, v15] of resolution.perValue) existing.set(k, v15);
28120
28120
  } else {
28121
28121
  result.variantOverrides.set(
28122
28122
  resolution.propName,
@@ -28143,7 +28143,7 @@ function applySpanResolution(result, resolution) {
28143
28143
  for (const group of resolution.groups) {
28144
28144
  const existing = result.variantOverrides.get(group.propName);
28145
28145
  if (existing) {
28146
- for (const [k, v14] of group.perValue) existing.set(k, v14);
28146
+ for (const [k, v15] of group.perValue) existing.set(k, v15);
28147
28147
  } else {
28148
28148
  result.variantOverrides.set(group.propName, new Map(group.perValue));
28149
28149
  }
@@ -28733,8 +28733,8 @@ function collectOverride(nodeTempId, path4, value, out) {
28733
28733
  return;
28734
28734
  }
28735
28735
  if (Array.isArray(value)) return;
28736
- for (const [k, v14] of Object.entries(value)) {
28737
- collectOverride(nodeTempId, `${path4}.${k}`, v14, out);
28736
+ for (const [k, v15] of Object.entries(value)) {
28737
+ collectOverride(nodeTempId, `${path4}.${k}`, v15, out);
28738
28738
  }
28739
28739
  }
28740
28740
  function flushTransitionFragments(node, fragments) {
@@ -29273,7 +29273,7 @@ function attachVariantPseudoStyles(props, variants, unresolved, propPseudoOverri
29273
29273
  }
29274
29274
  if (entries.length === 0) continue;
29275
29275
  let variant = variants.find(
29276
- (v14) => v14.selector?.propTempId === prop.tempId && v14.selector.value === value
29276
+ (v15) => v15.selector?.propTempId === prop.tempId && v15.selector.value === value
29277
29277
  );
29278
29278
  if (!variant) {
29279
29279
  variant = {
@@ -31797,6 +31797,18 @@ var init_user2 = __esm({
31797
31797
  pixelMode: z41.enum(PixelModeTypes).optional(),
31798
31798
  /** Whether to show pixel grid overlay */
31799
31799
  showPixelGrid: z41.boolean().optional(),
31800
+ /**
31801
+ * When this person finished or skipped the first-project Welcome, as epoch
31802
+ * milliseconds. Unset means the Welcome has not played. Per user, not per
31803
+ * organization: a person who joins a second workspace has seen it.
31804
+ */
31805
+ welcomeSeenAt: z41.number().optional(),
31806
+ /**
31807
+ * The new-project option this person picked last time, by option id
31808
+ * (`blank`, `import`, `studio`, `animate`, `app`). The return-visit menu
31809
+ * focuses it so Enter repeats it.
31810
+ */
31811
+ lastProjectStart: z41.string().optional(),
31800
31812
  /**
31801
31813
  * Whether editor feedback SOUNDS play (snap ticks, placement clicks, tool
31802
31814
  * arming). Unset means on — the absence of a choice is not a choice of
@@ -33354,6 +33366,51 @@ var init_dist = __esm({
33354
33366
  }
33355
33367
  });
33356
33368
 
33369
+ // ../opaque/dist/client/network/hydrationScheduler.js
33370
+ function yieldToMain() {
33371
+ const sched = globalThis.scheduler;
33372
+ if (sched?.yield)
33373
+ return sched.yield();
33374
+ if (typeof MessageChannel !== "undefined") {
33375
+ return new Promise((resolve6) => {
33376
+ const channel = new MessageChannel();
33377
+ channel.port1.onmessage = () => resolve6();
33378
+ channel.port2.postMessage(null);
33379
+ });
33380
+ }
33381
+ return new Promise((resolve6) => setTimeout(resolve6, 0));
33382
+ }
33383
+ function createHydrationSlicer(options = {}) {
33384
+ const now3 = options.now ?? (() => performance.now());
33385
+ let budgetMs = DEFAULT_BUDGET_MS;
33386
+ let sliceStart = now3();
33387
+ return {
33388
+ async tick() {
33389
+ const elapsed = now3() - sliceStart;
33390
+ if (elapsed < budgetMs)
33391
+ return;
33392
+ if (elapsed > FRAME_BUDGET_MS) {
33393
+ budgetMs = Math.max(MIN_BUDGET_MS, budgetMs - 2);
33394
+ } else if (elapsed < budgetMs + 2) {
33395
+ budgetMs = Math.min(MAX_BUDGET_MS, budgetMs + 1);
33396
+ }
33397
+ await yieldToMain();
33398
+ options.onResume?.();
33399
+ sliceStart = now3();
33400
+ }
33401
+ };
33402
+ }
33403
+ var FRAME_BUDGET_MS, DEFAULT_BUDGET_MS, MIN_BUDGET_MS, MAX_BUDGET_MS;
33404
+ var init_hydrationScheduler = __esm({
33405
+ "../opaque/dist/client/network/hydrationScheduler.js"() {
33406
+ "use strict";
33407
+ FRAME_BUDGET_MS = 16;
33408
+ DEFAULT_BUDGET_MS = 8;
33409
+ MIN_BUDGET_MS = 4;
33410
+ MAX_BUDGET_MS = 12;
33411
+ }
33412
+ });
33413
+
33357
33414
  // ../opaque/dist/staffMode.js
33358
33415
  var staffMode;
33359
33416
  var init_staffMode = __esm({
@@ -33761,6 +33818,7 @@ var init_utils2 = __esm({
33761
33818
  "../opaque/dist/client/files/utils.js"() {
33762
33819
  "use strict";
33763
33820
  init_imageHeader();
33821
+ init_files();
33764
33822
  }
33765
33823
  });
33766
33824
 
@@ -34661,11 +34719,18 @@ function determineActionScope(action, context) {
34661
34719
  };
34662
34720
  }
34663
34721
  if (!routingInfo.isBranched) {
34722
+ if (action.targetScope?.scope === routingInfo.scopeName) {
34723
+ return {
34724
+ success: true,
34725
+ scopeInfo: action.targetScope,
34726
+ scopeName: routingInfo.scopeName
34727
+ };
34728
+ }
34664
34729
  if (action.targetScope) {
34665
34730
  return {
34666
34731
  success: false,
34667
34732
  code: "INVALID_TARGET_SCOPE",
34668
- message: `Unbranched ${entityType} action cannot carry a branch target scope`
34733
+ message: `Unbranched ${entityType} action cannot target '${action.targetScope.scope}' scope`
34669
34734
  };
34670
34735
  }
34671
34736
  if (!context.scopeId) {
@@ -37140,7 +37205,7 @@ var init_LocalCache = __esm({
37140
37205
  if (!excluded || excluded.size === 0)
37141
37206
  return false;
37142
37207
  const provenance = this.actionIds.get(key);
37143
- const touched = provenance !== void 0 && Object.values(provenance).some((a5) => excluded.has(a5)) || Object.values(this.fieldVersions.get(key) ?? {}).some((versions) => versions.some((v14) => v14.actionId !== void 0 && excluded.has(v14.actionId)));
37208
+ const touched = provenance !== void 0 && Object.values(provenance).some((a5) => excluded.has(a5)) || Object.values(this.fieldVersions.get(key) ?? {}).some((versions) => versions.some((v15) => v15.actionId !== void 0 && excluded.has(v15.actionId)));
37144
37209
  if (!touched)
37145
37210
  return false;
37146
37211
  const state = this.syncedState.get(key);
@@ -37219,19 +37284,19 @@ var init_LocalCache = __esm({
37219
37284
  const versions = byField[field];
37220
37285
  if (!versions || versions.length === 0)
37221
37286
  continue;
37222
- if (!versions.some((v14) => v14.source === "event"))
37287
+ if (!versions.some((v15) => v15.source === "event"))
37223
37288
  continue;
37224
37289
  const prov = fieldActions?.[field];
37225
- const provKnown = prov !== void 0 && versions.some((v14) => v14.actionId === prov);
37290
+ const provKnown = prov !== void 0 && versions.some((v15) => v15.actionId === prov);
37226
37291
  if (!provKnown) {
37227
- const matchesKnown = versions.some((v14) => stableValueEqual(v14.value ?? null, incoming ?? null));
37292
+ const matchesKnown = versions.some((v15) => stableValueEqual(v15.value ?? null, incoming ?? null));
37228
37293
  if (!matchesKnown) {
37229
37294
  let maxHlc = null;
37230
- for (const v14 of versions) {
37231
- if (v14.actionId !== void 0 && excluded?.has(v14.actionId))
37295
+ for (const v15 of versions) {
37296
+ if (v15.actionId !== void 0 && excluded?.has(v15.actionId))
37232
37297
  continue;
37233
- if (this.compareNullableHlc(v14.hlc, maxHlc) > 0)
37234
- maxHlc = v14.hlc;
37298
+ if (this.compareNullableHlc(v15.hlc, maxHlc) > 0)
37299
+ maxHlc = v15.hlc;
37235
37300
  }
37236
37301
  versions.push({
37237
37302
  value: incoming,
@@ -37244,13 +37309,13 @@ var init_LocalCache = __esm({
37244
37309
  }
37245
37310
  }
37246
37311
  let winner = null;
37247
- for (const v14 of versions) {
37248
- const authoringActionId = v14.source === "event" ? v14.actionId : v14.source === "snapshot" ? v14.actionId ?? prov ?? null : null;
37312
+ for (const v15 of versions) {
37313
+ const authoringActionId = v15.source === "event" ? v15.actionId : v15.source === "snapshot" ? v15.actionId ?? prov ?? null : null;
37249
37314
  if (authoringActionId && excluded?.has(authoringActionId)) {
37250
37315
  continue;
37251
37316
  }
37252
- if (!winner || this.compareNullableHlc(v14.hlc, winner.hlc) >= 0) {
37253
- winner = v14;
37317
+ if (!winner || this.compareNullableHlc(v15.hlc, winner.hlc) >= 0) {
37318
+ winner = v15;
37254
37319
  }
37255
37320
  }
37256
37321
  if (winner) {
@@ -37854,7 +37919,7 @@ var init_LocalCache = __esm({
37854
37919
  materializeOneFieldVersion(targetKey, field, version, merge) {
37855
37920
  const byField = this.fieldVersions.get(targetKey) ?? {};
37856
37921
  const versions = byField[field] ?? [];
37857
- const dup = versions.some((v14) => version.eventId !== void 0 ? v14.eventId === version.eventId : v14.mergeId === merge.id && v14.hlc === version.hlc && v14.value === version.value);
37922
+ const dup = versions.some((v15) => version.eventId !== void 0 ? v15.eventId === version.eventId : v15.mergeId === merge.id && v15.hlc === version.hlc && v15.value === version.value);
37858
37923
  if (dup)
37859
37924
  return false;
37860
37925
  versions.push({ ...version, mergeId: merge.id });
@@ -37867,7 +37932,7 @@ var init_LocalCache = __esm({
37867
37932
  /** Delete-version analogue of {@link materializeOneFieldVersion}. */
37868
37933
  materializeOneDeleteVersion(targetKey, version, merge) {
37869
37934
  const versions = this.deleteVersions.get(targetKey) ?? [];
37870
- const dup = versions.some((v14) => version.eventId !== void 0 ? v14.eventId === version.eventId : v14.mergeId === merge.id && v14.hlc === version.hlc);
37935
+ const dup = versions.some((v15) => version.eventId !== void 0 ? v15.eventId === version.eventId : v15.mergeId === merge.id && v15.hlc === version.hlc);
37871
37936
  if (dup)
37872
37937
  return false;
37873
37938
  versions.push({ ...version, mergeId: merge.id });
@@ -37904,17 +37969,17 @@ var init_LocalCache = __esm({
37904
37969
  const state = { id: entityId };
37905
37970
  for (const [field, versions] of Object.entries(byField)) {
37906
37971
  let winner = null;
37907
- for (const v14 of versions) {
37972
+ for (const v15 of versions) {
37908
37973
  if (!winner) {
37909
- winner = v14;
37974
+ winner = v15;
37910
37975
  continue;
37911
37976
  }
37912
- const cmp = this.compareNullableHlc(v14.hlc, winner.hlc);
37977
+ const cmp = this.compareNullableHlc(v15.hlc, winner.hlc);
37913
37978
  if (cmp > 0) {
37914
- winner = v14;
37979
+ winner = v15;
37915
37980
  } else if (cmp === 0) {
37916
- if (winner.mergeId !== void 0 && v14.mergeId === void 0) {
37917
- winner = v14;
37981
+ if (winner.mergeId !== void 0 && v15.mergeId === void 0) {
37982
+ winner = v15;
37918
37983
  }
37919
37984
  }
37920
37985
  }
@@ -38121,7 +38186,7 @@ var init_LocalCache = __esm({
38121
38186
  if (parsed.branch !== branch)
38122
38187
  continue;
38123
38188
  for (const versions of Object.values(byField)) {
38124
- if (versions.some((v14) => v14.actionId === actionId)) {
38189
+ if (versions.some((v15) => v15.actionId === actionId)) {
38125
38190
  affected.add(parsed.entityId);
38126
38191
  break;
38127
38192
  }
@@ -38139,7 +38204,7 @@ var init_LocalCache = __esm({
38139
38204
  const parsed = this.parseKey(key);
38140
38205
  if (parsed.branch !== branch)
38141
38206
  continue;
38142
- if (versions.some((v14) => v14.actionId === actionId)) {
38207
+ if (versions.some((v15) => v15.actionId === actionId)) {
38143
38208
  affected.add(parsed.entityId);
38144
38209
  }
38145
38210
  }
@@ -38196,13 +38261,13 @@ var init_LocalCache = __esm({
38196
38261
  for (const [field, versions] of Object.entries(byField)) {
38197
38262
  let winner = null;
38198
38263
  let winnerActionId = null;
38199
- for (const v14 of versions) {
38200
- const authoringActionId = v14.source === "event" ? v14.actionId : v14.source === "snapshot" ? v14.actionId ?? fieldActions?.[field] ?? null : null;
38264
+ for (const v15 of versions) {
38265
+ const authoringActionId = v15.source === "event" ? v15.actionId : v15.source === "snapshot" ? v15.actionId ?? fieldActions?.[field] ?? null : null;
38201
38266
  if (authoringActionId && excluded?.has(authoringActionId)) {
38202
38267
  continue;
38203
38268
  }
38204
- if (!winner || this.compareNullableHlc(v14.hlc, winner.hlc) >= 0) {
38205
- winner = v14;
38269
+ if (!winner || this.compareNullableHlc(v15.hlc, winner.hlc) >= 0) {
38270
+ winner = v15;
38206
38271
  winnerActionId = authoringActionId ?? null;
38207
38272
  }
38208
38273
  }
@@ -38256,7 +38321,7 @@ var init_LocalCache = __esm({
38256
38321
  continue;
38257
38322
  let keyTouched = false;
38258
38323
  for (const [field, versions] of Object.entries(byField)) {
38259
- const filtered = versions.filter((v14) => v14.mergeId !== merge.id);
38324
+ const filtered = versions.filter((v15) => v15.mergeId !== merge.id);
38260
38325
  if (filtered.length !== versions.length) {
38261
38326
  keyTouched = true;
38262
38327
  if (filtered.length === 0)
@@ -38275,7 +38340,7 @@ var init_LocalCache = __esm({
38275
38340
  const parsed = this.parseKey(key);
38276
38341
  if (parsed.branch !== merge.targetBranchId)
38277
38342
  continue;
38278
- const filtered = versions.filter((v14) => v14.mergeId !== merge.id);
38343
+ const filtered = versions.filter((v15) => v15.mergeId !== merge.id);
38279
38344
  if (filtered.length !== versions.length) {
38280
38345
  if (filtered.length === 0)
38281
38346
  this.deleteVersions.delete(key);
@@ -39001,6 +39066,7 @@ var init_LocalCache = __esm({
39001
39066
  */
39002
39067
  evictEntityReadCaches(id, branch, field) {
39003
39068
  if (field && field.startsWith("_op.")) {
39069
+ this.childrenCache.clear();
39004
39070
  this.invalidateReadCaches();
39005
39071
  return;
39006
39072
  }
@@ -39146,13 +39212,13 @@ var init_LocalCache = __esm({
39146
39212
  return null;
39147
39213
  const mergeIdsByField = {};
39148
39214
  for (const [field, versions] of Object.entries(byField)) {
39149
- mergeIdsByField[field] = versions.map((v14) => v14.mergeId);
39215
+ mergeIdsByField[field] = versions.map((v15) => v15.mergeId);
39150
39216
  }
39151
39217
  const deletes = this.deleteVersions.get(key) ?? [];
39152
39218
  return {
39153
39219
  fields: Object.keys(byField),
39154
39220
  mergeIdsByField,
39155
- deleteMergeIds: deletes.map((v14) => v14.mergeId)
39221
+ deleteMergeIds: deletes.map((v15) => v15.mergeId)
39156
39222
  };
39157
39223
  }
39158
39224
  /**
@@ -39978,6 +40044,794 @@ var init_cache = __esm({
39978
40044
  }
39979
40045
  });
39980
40046
 
40047
+ // ../opaque/dist/client/storage/constants.js
40048
+ var DB_NAME, DB_VERSION, STORES, SYNC_SNAPSHOT_EVENT_ID_PREFIX;
40049
+ var init_constants2 = __esm({
40050
+ "../opaque/dist/client/storage/constants.js"() {
40051
+ "use strict";
40052
+ DB_NAME = "opaque";
40053
+ DB_VERSION = 12;
40054
+ STORES = {
40055
+ INGESTIONS: "ingestions",
40056
+ LATEST_STATE: "latestState",
40057
+ EVENTS: "events",
40058
+ TOMBSTONE_CURSORS: "tombstoneCursors",
40059
+ PENDING_UPLOADS: "pendingUploads",
40060
+ LOADED_SELECTIONS: "loadedSelections"
40061
+ };
40062
+ SYNC_SNAPSHOT_EVENT_ID_PREFIX = "sync_";
40063
+ }
40064
+ });
40065
+
40066
+ // ../opaque/dist/client/storage/migrations/v1.js
40067
+ var v1;
40068
+ var init_v1 = __esm({
40069
+ "../opaque/dist/client/storage/migrations/v1.js"() {
40070
+ "use strict";
40071
+ init_constants2();
40072
+ v1 = {
40073
+ version: 1,
40074
+ description: "Initial stores: localEvents + entityCache",
40075
+ up(db) {
40076
+ if (!db.objectStoreNames.contains(STORES.LATEST_STATE)) {
40077
+ const entityCache = db.createObjectStore(STORES.LATEST_STATE, {
40078
+ keyPath: "entityId"
40079
+ });
40080
+ entityCache.createIndex("by_scope", ["scope", "scopeId"]);
40081
+ entityCache.createIndex("by_type", "entityType");
40082
+ entityCache.createIndex("by_updated", "updatedAt");
40083
+ }
40084
+ if (!db.objectStoreNames.contains(STORES.EVENTS)) {
40085
+ const localEvents = db.createObjectStore(STORES.EVENTS, {
40086
+ keyPath: "id"
40087
+ });
40088
+ localEvents.createIndex("by_entity", "entityId");
40089
+ localEvents.createIndex("by_hlc", "hlc");
40090
+ localEvents.createIndex("by_action", "actionId");
40091
+ }
40092
+ }
40093
+ };
40094
+ }
40095
+ });
40096
+
40097
+ // ../opaque/dist/client/storage/migrations/v2.js
40098
+ var v2;
40099
+ var init_v2 = __esm({
40100
+ "../opaque/dist/client/storage/migrations/v2.js"() {
40101
+ "use strict";
40102
+ init_constants2();
40103
+ v2 = {
40104
+ version: 2,
40105
+ description: "Add by_synced index on localEvents",
40106
+ up(_db, tx) {
40107
+ if (!tx.objectStoreNames.contains(STORES.EVENTS))
40108
+ return;
40109
+ const localEvents = tx.objectStore(STORES.EVENTS);
40110
+ if (!localEvents.indexNames.contains("by_synced")) {
40111
+ localEvents.createIndex("by_synced", "synced");
40112
+ }
40113
+ }
40114
+ };
40115
+ }
40116
+ });
40117
+
40118
+ // ../opaque/dist/client/storage/migrations/v3.js
40119
+ var DEPRECATED_STORES, v3;
40120
+ var init_v3 = __esm({
40121
+ "../opaque/dist/client/storage/migrations/v3.js"() {
40122
+ "use strict";
40123
+ DEPRECATED_STORES = ["pendingActions", "knownState", "scopeMetadata"];
40124
+ v3 = {
40125
+ version: 3,
40126
+ description: "Drop deprecated pendingActions / knownState / scopeMetadata stores",
40127
+ up(db) {
40128
+ for (const name of DEPRECATED_STORES) {
40129
+ if (db.objectStoreNames.contains(name)) {
40130
+ db.deleteObjectStore(name);
40131
+ }
40132
+ }
40133
+ }
40134
+ };
40135
+ }
40136
+ });
40137
+
40138
+ // ../opaque/dist/client/storage/migrations/v4.js
40139
+ var v4;
40140
+ var init_v4 = __esm({
40141
+ "../opaque/dist/client/storage/migrations/v4.js"() {
40142
+ "use strict";
40143
+ init_constants2();
40144
+ v4 = {
40145
+ version: 4,
40146
+ description: "Add by_user_branch index on localEvents",
40147
+ up(_db, tx) {
40148
+ if (!tx.objectStoreNames.contains(STORES.EVENTS))
40149
+ return;
40150
+ const localEvents = tx.objectStore(STORES.EVENTS);
40151
+ if (!localEvents.indexNames.contains("by_user_branch")) {
40152
+ localEvents.createIndex("by_user_branch", ["userId", "branchId"]);
40153
+ }
40154
+ }
40155
+ };
40156
+ }
40157
+ });
40158
+
40159
+ // ../opaque/dist/client/storage/migrations/v5.js
40160
+ var v5;
40161
+ var init_v5 = __esm({
40162
+ "../opaque/dist/client/storage/migrations/v5.js"() {
40163
+ "use strict";
40164
+ init_constants2();
40165
+ v5 = {
40166
+ version: 5,
40167
+ description: "Branch-aware entityCache (composite key [entityId, branchId]); recreate both stores",
40168
+ up(db) {
40169
+ if (db.objectStoreNames.contains(STORES.LATEST_STATE)) {
40170
+ db.deleteObjectStore(STORES.LATEST_STATE);
40171
+ }
40172
+ if (db.objectStoreNames.contains(STORES.EVENTS)) {
40173
+ db.deleteObjectStore(STORES.EVENTS);
40174
+ }
40175
+ const entityCache = db.createObjectStore(STORES.LATEST_STATE, {
40176
+ keyPath: ["entityId", "branchId"]
40177
+ });
40178
+ entityCache.createIndex("by_entity", "entityId");
40179
+ entityCache.createIndex("by_scope", ["scope", "scopeId"]);
40180
+ entityCache.createIndex("by_type", "entityType");
40181
+ entityCache.createIndex("by_updated", "updatedAt");
40182
+ const localEvents = db.createObjectStore(STORES.EVENTS, {
40183
+ keyPath: "id"
40184
+ });
40185
+ localEvents.createIndex("by_entity", "entityId");
40186
+ localEvents.createIndex("by_hlc", "hlc");
40187
+ localEvents.createIndex("by_action", "actionId");
40188
+ localEvents.createIndex("by_synced", "synced");
40189
+ localEvents.createIndex("by_user_branch", ["userId", "branchId"]);
40190
+ }
40191
+ };
40192
+ }
40193
+ });
40194
+
40195
+ // ../opaque/dist/client/storage/migrations/v6.js
40196
+ var v6;
40197
+ var init_v6 = __esm({
40198
+ "../opaque/dist/client/storage/migrations/v6.js"() {
40199
+ "use strict";
40200
+ init_constants2();
40201
+ v6 = {
40202
+ version: 6,
40203
+ description: "tombstoneCursors store \u2014 per-scope hard-delete catch-up delivery cursor",
40204
+ up(db) {
40205
+ if (!db.objectStoreNames.contains(STORES.TOMBSTONE_CURSORS)) {
40206
+ db.createObjectStore(STORES.TOMBSTONE_CURSORS, { keyPath: "scopeId" });
40207
+ }
40208
+ }
40209
+ };
40210
+ }
40211
+ });
40212
+
40213
+ // ../opaque/dist/client/storage/migrations/v7.js
40214
+ var v7;
40215
+ var init_v7 = __esm({
40216
+ "../opaque/dist/client/storage/migrations/v7.js"() {
40217
+ "use strict";
40218
+ init_constants2();
40219
+ v7 = {
40220
+ version: 7,
40221
+ description: "pendingUploads store \u2014 durable offline queue of file bytes awaiting upload",
40222
+ up(db) {
40223
+ if (!db.objectStoreNames.contains(STORES.PENDING_UPLOADS)) {
40224
+ const store = db.createObjectStore(STORES.PENDING_UPLOADS, {
40225
+ keyPath: "id"
40226
+ });
40227
+ store.createIndex("by_status", "status", { unique: false });
40228
+ }
40229
+ }
40230
+ };
40231
+ }
40232
+ });
40233
+
40234
+ // ../opaque/dist/client/storage/migrations/v8.js
40235
+ var LEGACY_STORE_NAMES, v8;
40236
+ var init_v8 = __esm({
40237
+ "../opaque/dist/client/storage/migrations/v8.js"() {
40238
+ "use strict";
40239
+ init_constants2();
40240
+ LEGACY_STORE_NAMES = ["localEvents", "entityCache"];
40241
+ v8 = {
40242
+ version: 8,
40243
+ description: "Rename core stores to canonical server names: localEvents\u2192events, entityCache\u2192latestState",
40244
+ up(db) {
40245
+ for (const legacy of LEGACY_STORE_NAMES) {
40246
+ if (db.objectStoreNames.contains(legacy)) {
40247
+ db.deleteObjectStore(legacy);
40248
+ }
40249
+ }
40250
+ if (!db.objectStoreNames.contains(STORES.LATEST_STATE)) {
40251
+ const latestState = db.createObjectStore(STORES.LATEST_STATE, {
40252
+ keyPath: ["entityId", "branchId"]
40253
+ });
40254
+ latestState.createIndex("by_entity", "entityId");
40255
+ latestState.createIndex("by_scope", ["scope", "scopeId"]);
40256
+ latestState.createIndex("by_type", "entityType");
40257
+ latestState.createIndex("by_updated", "updatedAt");
40258
+ }
40259
+ if (!db.objectStoreNames.contains(STORES.EVENTS)) {
40260
+ const events = db.createObjectStore(STORES.EVENTS, { keyPath: "id" });
40261
+ events.createIndex("by_entity", "entityId");
40262
+ events.createIndex("by_hlc", "hlc");
40263
+ events.createIndex("by_action", "actionId");
40264
+ events.createIndex("by_synced", "synced");
40265
+ events.createIndex("by_user_branch", ["userId", "branchId"]);
40266
+ }
40267
+ }
40268
+ };
40269
+ }
40270
+ });
40271
+
40272
+ // ../opaque/dist/client/storage/migrations/v9.js
40273
+ var v9;
40274
+ var init_v9 = __esm({
40275
+ "../opaque/dist/client/storage/migrations/v9.js"() {
40276
+ "use strict";
40277
+ init_constants2();
40278
+ v9 = {
40279
+ version: 9,
40280
+ description: "loadedSelections store \u2014 server-confirmed (entity, select, branch) load keys",
40281
+ up(db) {
40282
+ if (!db.objectStoreNames.contains(STORES.LOADED_SELECTIONS)) {
40283
+ db.createObjectStore(STORES.LOADED_SELECTIONS, { keyPath: "key" });
40284
+ }
40285
+ }
40286
+ };
40287
+ }
40288
+ });
40289
+
40290
+ // ../opaque/dist/client/storage/migrations/v10.js
40291
+ var LEGACY_TEXT_ENTITY_TYPES, v10;
40292
+ var init_v10 = __esm({
40293
+ "../opaque/dist/client/storage/migrations/v10.js"() {
40294
+ "use strict";
40295
+ init_constants2();
40296
+ LEGACY_TEXT_ENTITY_TYPES = ["opRichTextRun", "opRichTextCursor"];
40297
+ v10 = {
40298
+ version: 10,
40299
+ description: "Drop cached latestState records under the pre-rename text entity types (opRichTextRun/opRichTextCursor) and the loadedSelections claims that describe them; they re-sync under opTextRun/opTextCursor",
40300
+ up(db, tx) {
40301
+ if (!db.objectStoreNames.contains(STORES.LATEST_STATE))
40302
+ return;
40303
+ const store = tx.objectStore(STORES.LATEST_STATE);
40304
+ if (!store.indexNames.contains("by_type"))
40305
+ return;
40306
+ const swallow = (request3) => {
40307
+ request3.onerror = (event) => {
40308
+ event.preventDefault();
40309
+ event.stopPropagation();
40310
+ };
40311
+ };
40312
+ let purged = false;
40313
+ const clearLoadedSelectionsOnce = () => {
40314
+ if (purged)
40315
+ return;
40316
+ purged = true;
40317
+ if (!db.objectStoreNames.contains(STORES.LOADED_SELECTIONS))
40318
+ return;
40319
+ swallow(tx.objectStore(STORES.LOADED_SELECTIONS).clear());
40320
+ };
40321
+ const byType = store.index("by_type");
40322
+ for (const legacyType of LEGACY_TEXT_ENTITY_TYPES) {
40323
+ const cursorRequest = byType.openCursor(IDBKeyRange.only(legacyType));
40324
+ cursorRequest.onsuccess = () => {
40325
+ const cursor = cursorRequest.result;
40326
+ if (!cursor)
40327
+ return;
40328
+ swallow(cursor.delete());
40329
+ clearLoadedSelectionsOnce();
40330
+ cursor.continue();
40331
+ };
40332
+ swallow(cursorRequest);
40333
+ }
40334
+ }
40335
+ };
40336
+ }
40337
+ });
40338
+
40339
+ // ../opaque/dist/client/storage/migrations/v11.js
40340
+ var v11;
40341
+ var init_v11 = __esm({
40342
+ "../opaque/dist/client/storage/migrations/v11.js"() {
40343
+ "use strict";
40344
+ init_constants2();
40345
+ v11 = {
40346
+ version: 11,
40347
+ description: "events by_branch_type index \u2014 branch-wide exclusion seed",
40348
+ up(_db, tx) {
40349
+ if (!tx.objectStoreNames.contains(STORES.EVENTS))
40350
+ return;
40351
+ const events = tx.objectStore(STORES.EVENTS);
40352
+ if (!events.indexNames.contains("by_branch_type")) {
40353
+ events.createIndex("by_branch_type", ["branchId", "type"]);
40354
+ }
40355
+ }
40356
+ };
40357
+ }
40358
+ });
40359
+
40360
+ // ../opaque/dist/client/storage/migrations/v12.js
40361
+ var v12;
40362
+ var init_v12 = __esm({
40363
+ "../opaque/dist/client/storage/migrations/v12.js"() {
40364
+ "use strict";
40365
+ init_constants2();
40366
+ v12 = {
40367
+ version: 12,
40368
+ description: "Local ingestion receipts",
40369
+ up(db) {
40370
+ db.createObjectStore(STORES.INGESTIONS, { keyPath: "id" });
40371
+ }
40372
+ };
40373
+ }
40374
+ });
40375
+
40376
+ // ../opaque/dist/client/storage/migrations/index.js
40377
+ function runMigrations(db, tx, oldVersion) {
40378
+ for (const migration of MIGRATIONS) {
40379
+ if (migration.version > oldVersion) {
40380
+ migration.up(db, tx, oldVersion);
40381
+ }
40382
+ }
40383
+ }
40384
+ var MIGRATIONS;
40385
+ var init_migrations = __esm({
40386
+ "../opaque/dist/client/storage/migrations/index.js"() {
40387
+ "use strict";
40388
+ init_v1();
40389
+ init_v2();
40390
+ init_v3();
40391
+ init_v4();
40392
+ init_v5();
40393
+ init_v6();
40394
+ init_v7();
40395
+ init_v8();
40396
+ init_v9();
40397
+ init_v10();
40398
+ init_v11();
40399
+ init_v12();
40400
+ MIGRATIONS = [
40401
+ v1,
40402
+ v2,
40403
+ v3,
40404
+ v4,
40405
+ v5,
40406
+ v6,
40407
+ v7,
40408
+ v8,
40409
+ v9,
40410
+ v10,
40411
+ v11,
40412
+ v12
40413
+ ].sort((a5, b4) => a5.version - b4.version);
40414
+ }
40415
+ });
40416
+
40417
+ // ../opaque/dist/client/storage/schema.js
40418
+ function openDatabase(timeoutMs = OPEN_DATABASE_TIMEOUT_MS, databaseName = DB_NAME) {
40419
+ return new Promise((resolve6, reject) => {
40420
+ const request3 = indexedDB.open(databaseName, DB_VERSION);
40421
+ let settled = false;
40422
+ const timer = setTimeout(() => {
40423
+ if (settled)
40424
+ return;
40425
+ settled = true;
40426
+ reject(new IndexedDbOpenBlockedError("timeout"));
40427
+ }, timeoutMs);
40428
+ const settle = (fn2) => {
40429
+ if (settled)
40430
+ return;
40431
+ settled = true;
40432
+ clearTimeout(timer);
40433
+ fn2();
40434
+ };
40435
+ request3.onblocked = () => {
40436
+ settle(() => reject(new IndexedDbOpenBlockedError("blocked")));
40437
+ };
40438
+ request3.onerror = () => settle(() => reject(request3.error));
40439
+ request3.onsuccess = () => {
40440
+ const db = request3.result;
40441
+ if (settled) {
40442
+ db.close();
40443
+ return;
40444
+ }
40445
+ db.onversionchange = () => db.close();
40446
+ settle(() => resolve6(db));
40447
+ };
40448
+ request3.onupgradeneeded = (event) => {
40449
+ const db = request3.result;
40450
+ const tx = request3.transaction;
40451
+ if (!tx)
40452
+ return;
40453
+ runMigrations(db, tx, event.oldVersion);
40454
+ };
40455
+ });
40456
+ }
40457
+ function idbGet(db, storeName, key) {
40458
+ return new Promise((resolve6, reject) => {
40459
+ const tx = db.transaction(storeName, "readonly");
40460
+ const store = tx.objectStore(storeName);
40461
+ const request3 = store.get(key);
40462
+ request3.onsuccess = () => resolve6(request3.result);
40463
+ request3.onerror = () => reject(request3.error);
40464
+ });
40465
+ }
40466
+ function idbPut(db, storeName, value) {
40467
+ return new Promise((resolve6, reject) => {
40468
+ const tx = db.transaction(storeName, "readwrite");
40469
+ const store = tx.objectStore(storeName);
40470
+ const request3 = store.put(value);
40471
+ request3.onsuccess = () => resolve6(request3.result);
40472
+ request3.onerror = () => reject(request3.error);
40473
+ });
40474
+ }
40475
+ function idbDelete(db, storeName, key) {
40476
+ return new Promise((resolve6, reject) => {
40477
+ const tx = db.transaction(storeName, "readwrite");
40478
+ const store = tx.objectStore(storeName);
40479
+ const request3 = store.delete(key);
40480
+ request3.onsuccess = () => resolve6();
40481
+ request3.onerror = () => reject(request3.error);
40482
+ });
40483
+ }
40484
+ function idbGetAll(db, storeName) {
40485
+ return new Promise((resolve6, reject) => {
40486
+ const tx = db.transaction(storeName, "readonly");
40487
+ const store = tx.objectStore(storeName);
40488
+ const request3 = store.getAll();
40489
+ request3.onsuccess = () => resolve6(request3.result);
40490
+ request3.onerror = () => reject(request3.error);
40491
+ });
40492
+ }
40493
+ function idbGetAllByIndex(db, storeName, indexName, key) {
40494
+ return new Promise((resolve6, reject) => {
40495
+ const tx = db.transaction(storeName, "readonly");
40496
+ const store = tx.objectStore(storeName);
40497
+ const index = store.index(indexName);
40498
+ const request3 = index.getAll(key);
40499
+ request3.onsuccess = () => resolve6(request3.result);
40500
+ request3.onerror = () => reject(request3.error);
40501
+ });
40502
+ }
40503
+ function idbGetEntityLastHlc(db, entityId) {
40504
+ return new Promise((resolve6, reject) => {
40505
+ const tx = db.transaction(STORES.LATEST_STATE, "readonly");
40506
+ const index = tx.objectStore(STORES.LATEST_STATE).index("by_entity");
40507
+ const request3 = index.getAll(entityId);
40508
+ request3.onsuccess = () => {
40509
+ const records2 = request3.result;
40510
+ if (records2.length === 0)
40511
+ return resolve6(null);
40512
+ let max = records2[0].lastHlc;
40513
+ for (const r of records2)
40514
+ if (r.lastHlc > max)
40515
+ max = r.lastHlc;
40516
+ resolve6(max);
40517
+ };
40518
+ request3.onerror = () => reject(request3.error);
40519
+ });
40520
+ }
40521
+ function idbPutMany(db, storeName, values) {
40522
+ return new Promise((resolve6, reject) => {
40523
+ const tx = db.transaction(storeName, "readwrite");
40524
+ const store = tx.objectStore(storeName);
40525
+ tx.oncomplete = () => resolve6();
40526
+ tx.onerror = () => reject(tx.error);
40527
+ for (const value of values) {
40528
+ store.put(value);
40529
+ }
40530
+ });
40531
+ }
40532
+ function idbDeleteMany(db, storeName, keys) {
40533
+ return new Promise((resolve6, reject) => {
40534
+ const tx = db.transaction(storeName, "readwrite");
40535
+ const store = tx.objectStore(storeName);
40536
+ tx.oncomplete = () => resolve6();
40537
+ tx.onerror = () => reject(tx.error);
40538
+ for (const key of keys) {
40539
+ store.delete(key);
40540
+ }
40541
+ });
40542
+ }
40543
+ function idbClear(db, storeName) {
40544
+ return new Promise((resolve6, reject) => {
40545
+ const tx = db.transaction(storeName, "readwrite");
40546
+ const store = tx.objectStore(storeName);
40547
+ const request3 = store.clear();
40548
+ request3.onsuccess = () => resolve6();
40549
+ request3.onerror = () => reject(request3.error);
40550
+ });
40551
+ }
40552
+ var OPEN_DATABASE_TIMEOUT_MS, IndexedDbOpenBlockedError;
40553
+ var init_schema4 = __esm({
40554
+ "../opaque/dist/client/storage/schema.js"() {
40555
+ "use strict";
40556
+ init_migrations();
40557
+ init_constants2();
40558
+ init_constants2();
40559
+ OPEN_DATABASE_TIMEOUT_MS = 5e3;
40560
+ IndexedDbOpenBlockedError = class extends Error {
40561
+ constructor(reason) {
40562
+ super(reason === "blocked" ? "IndexedDB open blocked: another tab holds an older version of the database" : `IndexedDB open did not settle within ${OPEN_DATABASE_TIMEOUT_MS}ms`);
40563
+ this.name = "IndexedDbOpenBlockedError";
40564
+ }
40565
+ };
40566
+ }
40567
+ });
40568
+
40569
+ // ../opaque/dist/client/storage/utils.js
40570
+ function getMaxHlc(events) {
40571
+ if (events.length === 0)
40572
+ return "0";
40573
+ return events.reduce((max, e2) => HLC.compare(e2.hlc, max) > 0 ? e2.hlc : max, "0");
40574
+ }
40575
+ function eventBranchId(event) {
40576
+ return event.branchId ?? void 0;
40577
+ }
40578
+ function groupEventsByBranch(events) {
40579
+ const groups = /* @__PURE__ */ new Map();
40580
+ for (const event of events) {
40581
+ const key = eventBranchId(event) ?? "";
40582
+ const bucket = groups.get(key);
40583
+ if (bucket)
40584
+ bucket.push(event);
40585
+ else
40586
+ groups.set(key, [event]);
40587
+ }
40588
+ return groups;
40589
+ }
40590
+ function applyLWWEvents(events, existingState, existingLastHlc, existingFieldHlcs, existingFieldActions) {
40591
+ const state = existingState ? { ...existingState } : {};
40592
+ const fieldHlcs = existingFieldHlcs ? { ...existingFieldHlcs } : {};
40593
+ if (!existingFieldHlcs && existingState && existingLastHlc) {
40594
+ for (const key of Object.keys(existingState)) {
40595
+ fieldHlcs[key] = existingLastHlc;
40596
+ }
40597
+ }
40598
+ const fieldActions = existingFieldActions ? { ...existingFieldActions } : {};
40599
+ const sortedEvents = sortByHlc(events, "asc");
40600
+ for (const event of sortedEvents) {
40601
+ if (isTombstoneEvent(event)) {
40602
+ state.deletedAt = event.hlc;
40603
+ fieldHlcs.deletedAt = event.hlc;
40604
+ fieldActions.deletedAt = event.actionId;
40605
+ continue;
40606
+ }
40607
+ if (event.type === "upsert" && event.field) {
40608
+ const currentHlc = fieldHlcs[event.field];
40609
+ if (!currentHlc || HLC.compare(event.hlc, currentHlc) > 0) {
40610
+ state[event.field] = event.value;
40611
+ fieldHlcs[event.field] = event.hlc;
40612
+ fieldActions[event.field] = event.actionId;
40613
+ }
40614
+ }
40615
+ }
40616
+ if (events.length > 0) {
40617
+ const firstEvent = events[0];
40618
+ state.id = firstEvent.entityId;
40619
+ state.modelName = firstEvent.entityType;
40620
+ }
40621
+ const eventsMaxHlc = getMaxHlc(events);
40622
+ const lastHlc = existingLastHlc && HLC.compare(existingLastHlc, eventsMaxHlc) > 0 ? existingLastHlc : eventsMaxHlc;
40623
+ return { state, fieldHlcs, fieldActions, lastHlc };
40624
+ }
40625
+ var init_utils4 = __esm({
40626
+ "../opaque/dist/client/storage/utils.js"() {
40627
+ "use strict";
40628
+ init_types2();
40629
+ init_hlc();
40630
+ }
40631
+ });
40632
+
40633
+ // ../opaque/dist/client/storage/indexeddb/utils.js
40634
+ function foldLatestStateRecords(records2) {
40635
+ if (records2.length === 0)
40636
+ return null;
40637
+ if (records2.length === 1) {
40638
+ return {
40639
+ state: records2[0].state,
40640
+ ...records2[0].fieldActions !== void 0 && {
40641
+ fieldActions: records2[0].fieldActions
40642
+ },
40643
+ ...records2[0].fieldHlcs !== void 0 && {
40644
+ fieldHlcs: records2[0].fieldHlcs
40645
+ }
40646
+ };
40647
+ }
40648
+ const ordered = [...records2].sort((a5, b4) => HLC.compare(a5.lastHlc, b4.lastHlc));
40649
+ const merged = {};
40650
+ const mergedActions = {};
40651
+ let anyActions = false;
40652
+ const mergedHlcs = {};
40653
+ let anyHlcs = false;
40654
+ for (const record of ordered) {
40655
+ for (const [field, value] of Object.entries(record.state)) {
40656
+ merged[field] = value;
40657
+ const action = record.fieldActions?.[field];
40658
+ if (action !== void 0) {
40659
+ mergedActions[field] = action;
40660
+ anyActions = true;
40661
+ } else {
40662
+ delete mergedActions[field];
40663
+ }
40664
+ const hlc = record.fieldHlcs?.[field];
40665
+ if (hlc !== void 0) {
40666
+ mergedHlcs[field] = hlc;
40667
+ anyHlcs = true;
40668
+ } else {
40669
+ delete mergedHlcs[field];
40670
+ }
40671
+ }
40672
+ }
40673
+ return {
40674
+ state: merged,
40675
+ ...anyActions && { fieldActions: mergedActions },
40676
+ ...anyHlcs && { fieldHlcs: mergedHlcs }
40677
+ };
40678
+ }
40679
+ function groupBy(items, keyFn) {
40680
+ const groups = {};
40681
+ for (const item of items) {
40682
+ const key = keyFn(item);
40683
+ if (!groups[key]) {
40684
+ groups[key] = [];
40685
+ }
40686
+ groups[key].push(item);
40687
+ }
40688
+ return groups;
40689
+ }
40690
+ function eventToRecord(event, synced = 1, actionTargetScope, actionHardDeleteScope) {
40691
+ return {
40692
+ id: event.id,
40693
+ entityId: event.entityId,
40694
+ entityType: event.entityType,
40695
+ field: event.field,
40696
+ value: event.value,
40697
+ previousValue: event.previousValue,
40698
+ hlc: event.hlc,
40699
+ clientId: event.clientId,
40700
+ userId: event.userId,
40701
+ actionId: event.actionId,
40702
+ actionLabel: event.actionLabel,
40703
+ type: event.type,
40704
+ mergeId: event.mergeId,
40705
+ targetId: event.targetId,
40706
+ branchId: event.branchId,
40707
+ parentScopeId: event.parentScopeId,
40708
+ actionTargetScope,
40709
+ actionHardDeleteScope,
40710
+ synced
40711
+ };
40712
+ }
40713
+ function recordToEvent(record) {
40714
+ return {
40715
+ id: record.id,
40716
+ type: record.type,
40717
+ entityId: record.entityId,
40718
+ entityType: record.entityType,
40719
+ field: record.field,
40720
+ value: record.value,
40721
+ previousValue: record.previousValue,
40722
+ hlc: record.hlc,
40723
+ clientId: record.clientId,
40724
+ userId: record.userId,
40725
+ actionId: record.actionId,
40726
+ actionLabel: record.actionLabel,
40727
+ mergeId: record.mergeId,
40728
+ targetId: record.targetId,
40729
+ branchId: record.branchId,
40730
+ parentScopeId: record.parentScopeId
40731
+ };
40732
+ }
40733
+ var init_utils5 = __esm({
40734
+ "../opaque/dist/client/storage/indexeddb/utils.js"() {
40735
+ "use strict";
40736
+ init_hlc();
40737
+ }
40738
+ });
40739
+
40740
+ // ../opaque/dist/client/storage/indexeddb/ingestion.js
40741
+ function prepareBranchIngestion(actions, receipt) {
40742
+ const started = performance.now();
40743
+ if (!actions.length || receipt.actionIds.length !== actions.length || actions.some((action, index) => action.id !== receipt.actionIds[index])) {
40744
+ throw new Error("The receipt must identify every ingestion action in order.");
40745
+ }
40746
+ const groups = /* @__PURE__ */ new Map();
40747
+ const eventRecords = actions.flatMap((action) => {
40748
+ if (!action.events.length)
40749
+ throw new Error("An ingestion action cannot be empty.");
40750
+ if (action.targetScope?.scope !== "branch" || action.targetScope.scopeId !== receipt.scopeId || action.targetScope.branchId !== receipt.branchId) {
40751
+ throw new Error("The ingestion action has a different target scope.");
40752
+ }
40753
+ for (const event of action.events) {
40754
+ if (event.actionId !== action.id)
40755
+ throw new Error("The event has a different action identity.");
40756
+ if (event.type !== "upsert" || event.branchId !== receipt.branchId) {
40757
+ throw new Error("Ingestion requires branch-scoped upserts.");
40758
+ }
40759
+ const group = groups.get(event.entityId) ?? [];
40760
+ group.push(event);
40761
+ groups.set(event.entityId, group);
40762
+ }
40763
+ return action.events.map((event) => eventToRecord(event, 0, action.targetScope));
40764
+ });
40765
+ const states = [];
40766
+ for (const [entityId, events] of groups) {
40767
+ if (!events.some((event) => event.field === "createdAt")) {
40768
+ throw new Error("Ingestion only accepts fresh entities.");
40769
+ }
40770
+ if (events.some((event) => event.entityType !== events[0].entityType))
40771
+ throw new Error("An entity cannot have multiple models.");
40772
+ const fields = new Set(events.map((event) => event.field));
40773
+ if (fields.size !== events.length)
40774
+ throw new Error("Duplicate initial field event.");
40775
+ states.push({
40776
+ entityId,
40777
+ entityType: events[0].entityType,
40778
+ branchId: receipt.branchId,
40779
+ scopeId: receipt.branchId,
40780
+ scope: CollabScope.branch,
40781
+ ...applyLWWEvents(events),
40782
+ updatedAt: Date.now()
40783
+ });
40784
+ }
40785
+ return { eventRecords, states, prepareMs: performance.now() - started };
40786
+ }
40787
+ async function stageBranchIngestion(db, actions, receipt, prepared = prepareBranchIngestion(actions, receipt)) {
40788
+ const { eventRecords, states, prepareMs } = prepared;
40789
+ const transactionStarted = performance.now();
40790
+ await new Promise((resolve6, reject) => {
40791
+ const tx = db.transaction([STORES.EVENTS, STORES.LATEST_STATE, STORES.INGESTIONS], "readwrite");
40792
+ tx.oncomplete = () => resolve6();
40793
+ tx.onabort = () => reject(tx.error ?? new Error("Ingestion transaction aborted."));
40794
+ tx.onerror = () => {
40795
+ };
40796
+ const eventsStore = tx.objectStore(STORES.EVENTS);
40797
+ const stateStore = tx.objectStore(STORES.LATEST_STATE);
40798
+ const receiptStore = tx.objectStore(STORES.INGESTIONS);
40799
+ const stateEnd = eventRecords.length + states.length;
40800
+ const total = stateEnd + 1;
40801
+ let cursor = 0;
40802
+ const enqueueBatch = () => {
40803
+ try {
40804
+ let lastRequest;
40805
+ const end = Math.min(cursor + INGESTION_REQUEST_BATCH_SIZE, total);
40806
+ for (; cursor < end; cursor++) {
40807
+ lastRequest = cursor < eventRecords.length ? eventsStore.add(eventRecords[cursor]) : cursor < stateEnd ? stateStore.add(states[cursor - eventRecords.length]) : receiptStore.add(receipt);
40808
+ }
40809
+ if (cursor < total && lastRequest)
40810
+ lastRequest.onsuccess = enqueueBatch;
40811
+ } catch (error) {
40812
+ tx.abort();
40813
+ reject(error);
40814
+ }
40815
+ };
40816
+ enqueueBatch();
40817
+ });
40818
+ return {
40819
+ prepareMs,
40820
+ transactionMs: performance.now() - transactionStarted
40821
+ };
40822
+ }
40823
+ var INGESTION_REQUEST_BATCH_SIZE;
40824
+ var init_ingestion = __esm({
40825
+ "../opaque/dist/client/storage/indexeddb/ingestion.js"() {
40826
+ "use strict";
40827
+ init_types2();
40828
+ init_schema4();
40829
+ init_utils4();
40830
+ init_utils5();
40831
+ INGESTION_REQUEST_BATCH_SIZE = 128;
40832
+ }
40833
+ });
40834
+
39981
40835
  // ../opaque/dist/client/actor.js
39982
40836
  function actorFields(source) {
39983
40837
  const actorId = source.getActorId?.() ?? null;
@@ -40270,9 +41124,9 @@ var require_bin = __commonJS({
40270
41124
  const gkm = b4[k - 1 - Z4 * Math.floor((k - 1) / Z4)];
40271
41125
  const gkp = b4[k + 1 - Z4 * Math.floor((k + 1) / Z4)];
40272
41126
  const u3 = k === -h4 || k !== h4 && gkm < gkp ? gkp : gkm + 1;
40273
- const v14 = u3 - k;
41127
+ const v15 = u3 - k;
40274
41128
  let x6 = u3;
40275
- let y7 = v14;
41129
+ let y7 = v15;
40276
41130
  while (x6 < N6 && y7 < M4 && eq(i3 + x6, j3 + y7))
40277
41131
  x6++, y7++;
40278
41132
  b4[k - Z4 * Math.floor(k / Z4)] = x6;
@@ -40283,7 +41137,7 @@ var require_bin = __commonJS({
40283
41137
  stack_base[stack_top++] = j3 + y7;
40284
41138
  stack_base[stack_top++] = M4 - y7;
40285
41139
  N6 = u3;
40286
- M4 = v14;
41140
+ M4 = v15;
40287
41141
  Z4 = 2 * (Math.min(N6, M4) + 1);
40288
41142
  continue Z_block;
40289
41143
  } else
@@ -40294,9 +41148,9 @@ var require_bin = __commonJS({
40294
41148
  const pkm = b4[Z4 + k - 1 - Z4 * Math.floor((k - 1) / Z4)];
40295
41149
  const pkp = b4[Z4 + k + 1 - Z4 * Math.floor((k + 1) / Z4)];
40296
41150
  const u3 = k === -h4 || k !== h4 && pkm < pkp ? pkp : pkm + 1;
40297
- const v14 = u3 - k;
41151
+ const v15 = u3 - k;
40298
41152
  let x6 = u3;
40299
- let y7 = v14;
41153
+ let y7 = v15;
40300
41154
  while (x6 < N6 && y7 < M4 && eq(offsetx - x6, offsety - y7))
40301
41155
  x6++, y7++;
40302
41156
  b4[Z4 + k - Z4 * Math.floor(k / Z4)] = x6;
@@ -40304,8 +41158,8 @@ var require_bin = __commonJS({
40304
41158
  if (h4 > 0 || x6 !== u3) {
40305
41159
  stack_base[stack_top++] = i3 + N6 - u3;
40306
41160
  stack_base[stack_top++] = u3;
40307
- stack_base[stack_top++] = j3 + M4 - v14;
40308
- stack_base[stack_top++] = v14;
41161
+ stack_base[stack_top++] = j3 + M4 - v15;
41162
+ stack_base[stack_top++] = v15;
40309
41163
  N6 = N6 - x6;
40310
41164
  M4 = M4 - y7;
40311
41165
  Z4 = 2 * (Math.min(N6, M4) + 1);
@@ -40447,16 +41301,16 @@ var require_bin = __commonJS({
40447
41301
  }
40448
41302
  return rec;
40449
41303
  }
40450
- const v14 = rec.value;
40451
- const sx = v14[0];
40452
- const ex = v14[1];
40453
- const ey = v14[3];
41304
+ const v15 = rec.value;
41305
+ const sx = v15[0];
41306
+ const ex = v15[1];
41307
+ const ey = v15[3];
40454
41308
  const { i: i3, j: j3 } = this;
40455
41309
  if (i3 !== sx) {
40456
- v14.length--;
40457
- v14[0] = i3;
40458
- v14[1] = j3;
40459
- v14[2] = sx - i3;
41310
+ v15.length--;
41311
+ v15[0] = i3;
41312
+ v15[1] = j3;
41313
+ v15[2] = sx - i3;
40460
41314
  }
40461
41315
  this.i = ex;
40462
41316
  this.j = ey;
@@ -40469,9 +41323,9 @@ var require_bin = __commonJS({
40469
41323
  exports.lcs = lcs;
40470
41324
  function* calcPatch2(xs, ys, eq) {
40471
41325
  const slice = ArrayBuffer.isView(xs) ? Uint8Array.prototype.subarray : xs.slice;
40472
- for (const v14 of diff3(xs, ys, eq)) {
40473
- v14[2] = slice.call(ys, v14[2], v14[3]);
40474
- yield v14;
41326
+ for (const v15 of diff3(xs, ys, eq)) {
41327
+ v15[2] = slice.call(ys, v15[2], v15[3]);
41328
+ yield v15;
40475
41329
  }
40476
41330
  }
40477
41331
  exports.calcPatch = calcPatch2;
@@ -43472,509 +44326,6 @@ var init_gap_check = __esm({
43472
44326
  }
43473
44327
  });
43474
44328
 
43475
- // ../opaque/dist/client/storage/constants.js
43476
- var DB_NAME, DB_VERSION, STORES, SYNC_SNAPSHOT_EVENT_ID_PREFIX;
43477
- var init_constants2 = __esm({
43478
- "../opaque/dist/client/storage/constants.js"() {
43479
- "use strict";
43480
- DB_NAME = "opaque";
43481
- DB_VERSION = 11;
43482
- STORES = {
43483
- LATEST_STATE: "latestState",
43484
- EVENTS: "events",
43485
- TOMBSTONE_CURSORS: "tombstoneCursors",
43486
- PENDING_UPLOADS: "pendingUploads",
43487
- LOADED_SELECTIONS: "loadedSelections"
43488
- };
43489
- SYNC_SNAPSHOT_EVENT_ID_PREFIX = "sync_";
43490
- }
43491
- });
43492
-
43493
- // ../opaque/dist/client/storage/migrations/v1.js
43494
- var v1;
43495
- var init_v1 = __esm({
43496
- "../opaque/dist/client/storage/migrations/v1.js"() {
43497
- "use strict";
43498
- init_constants2();
43499
- v1 = {
43500
- version: 1,
43501
- description: "Initial stores: localEvents + entityCache",
43502
- up(db) {
43503
- if (!db.objectStoreNames.contains(STORES.LATEST_STATE)) {
43504
- const entityCache = db.createObjectStore(STORES.LATEST_STATE, {
43505
- keyPath: "entityId"
43506
- });
43507
- entityCache.createIndex("by_scope", ["scope", "scopeId"]);
43508
- entityCache.createIndex("by_type", "entityType");
43509
- entityCache.createIndex("by_updated", "updatedAt");
43510
- }
43511
- if (!db.objectStoreNames.contains(STORES.EVENTS)) {
43512
- const localEvents = db.createObjectStore(STORES.EVENTS, {
43513
- keyPath: "id"
43514
- });
43515
- localEvents.createIndex("by_entity", "entityId");
43516
- localEvents.createIndex("by_hlc", "hlc");
43517
- localEvents.createIndex("by_action", "actionId");
43518
- }
43519
- }
43520
- };
43521
- }
43522
- });
43523
-
43524
- // ../opaque/dist/client/storage/migrations/v2.js
43525
- var v2;
43526
- var init_v2 = __esm({
43527
- "../opaque/dist/client/storage/migrations/v2.js"() {
43528
- "use strict";
43529
- init_constants2();
43530
- v2 = {
43531
- version: 2,
43532
- description: "Add by_synced index on localEvents",
43533
- up(_db, tx) {
43534
- if (!tx.objectStoreNames.contains(STORES.EVENTS))
43535
- return;
43536
- const localEvents = tx.objectStore(STORES.EVENTS);
43537
- if (!localEvents.indexNames.contains("by_synced")) {
43538
- localEvents.createIndex("by_synced", "synced");
43539
- }
43540
- }
43541
- };
43542
- }
43543
- });
43544
-
43545
- // ../opaque/dist/client/storage/migrations/v3.js
43546
- var DEPRECATED_STORES, v3;
43547
- var init_v3 = __esm({
43548
- "../opaque/dist/client/storage/migrations/v3.js"() {
43549
- "use strict";
43550
- DEPRECATED_STORES = ["pendingActions", "knownState", "scopeMetadata"];
43551
- v3 = {
43552
- version: 3,
43553
- description: "Drop deprecated pendingActions / knownState / scopeMetadata stores",
43554
- up(db) {
43555
- for (const name of DEPRECATED_STORES) {
43556
- if (db.objectStoreNames.contains(name)) {
43557
- db.deleteObjectStore(name);
43558
- }
43559
- }
43560
- }
43561
- };
43562
- }
43563
- });
43564
-
43565
- // ../opaque/dist/client/storage/migrations/v4.js
43566
- var v4;
43567
- var init_v4 = __esm({
43568
- "../opaque/dist/client/storage/migrations/v4.js"() {
43569
- "use strict";
43570
- init_constants2();
43571
- v4 = {
43572
- version: 4,
43573
- description: "Add by_user_branch index on localEvents",
43574
- up(_db, tx) {
43575
- if (!tx.objectStoreNames.contains(STORES.EVENTS))
43576
- return;
43577
- const localEvents = tx.objectStore(STORES.EVENTS);
43578
- if (!localEvents.indexNames.contains("by_user_branch")) {
43579
- localEvents.createIndex("by_user_branch", ["userId", "branchId"]);
43580
- }
43581
- }
43582
- };
43583
- }
43584
- });
43585
-
43586
- // ../opaque/dist/client/storage/migrations/v5.js
43587
- var v5;
43588
- var init_v5 = __esm({
43589
- "../opaque/dist/client/storage/migrations/v5.js"() {
43590
- "use strict";
43591
- init_constants2();
43592
- v5 = {
43593
- version: 5,
43594
- description: "Branch-aware entityCache (composite key [entityId, branchId]); recreate both stores",
43595
- up(db) {
43596
- if (db.objectStoreNames.contains(STORES.LATEST_STATE)) {
43597
- db.deleteObjectStore(STORES.LATEST_STATE);
43598
- }
43599
- if (db.objectStoreNames.contains(STORES.EVENTS)) {
43600
- db.deleteObjectStore(STORES.EVENTS);
43601
- }
43602
- const entityCache = db.createObjectStore(STORES.LATEST_STATE, {
43603
- keyPath: ["entityId", "branchId"]
43604
- });
43605
- entityCache.createIndex("by_entity", "entityId");
43606
- entityCache.createIndex("by_scope", ["scope", "scopeId"]);
43607
- entityCache.createIndex("by_type", "entityType");
43608
- entityCache.createIndex("by_updated", "updatedAt");
43609
- const localEvents = db.createObjectStore(STORES.EVENTS, {
43610
- keyPath: "id"
43611
- });
43612
- localEvents.createIndex("by_entity", "entityId");
43613
- localEvents.createIndex("by_hlc", "hlc");
43614
- localEvents.createIndex("by_action", "actionId");
43615
- localEvents.createIndex("by_synced", "synced");
43616
- localEvents.createIndex("by_user_branch", ["userId", "branchId"]);
43617
- }
43618
- };
43619
- }
43620
- });
43621
-
43622
- // ../opaque/dist/client/storage/migrations/v6.js
43623
- var v6;
43624
- var init_v6 = __esm({
43625
- "../opaque/dist/client/storage/migrations/v6.js"() {
43626
- "use strict";
43627
- init_constants2();
43628
- v6 = {
43629
- version: 6,
43630
- description: "tombstoneCursors store \u2014 per-scope hard-delete catch-up delivery cursor",
43631
- up(db) {
43632
- if (!db.objectStoreNames.contains(STORES.TOMBSTONE_CURSORS)) {
43633
- db.createObjectStore(STORES.TOMBSTONE_CURSORS, { keyPath: "scopeId" });
43634
- }
43635
- }
43636
- };
43637
- }
43638
- });
43639
-
43640
- // ../opaque/dist/client/storage/migrations/v7.js
43641
- var v7;
43642
- var init_v7 = __esm({
43643
- "../opaque/dist/client/storage/migrations/v7.js"() {
43644
- "use strict";
43645
- init_constants2();
43646
- v7 = {
43647
- version: 7,
43648
- description: "pendingUploads store \u2014 durable offline queue of file bytes awaiting upload",
43649
- up(db) {
43650
- if (!db.objectStoreNames.contains(STORES.PENDING_UPLOADS)) {
43651
- const store = db.createObjectStore(STORES.PENDING_UPLOADS, {
43652
- keyPath: "id"
43653
- });
43654
- store.createIndex("by_status", "status", { unique: false });
43655
- }
43656
- }
43657
- };
43658
- }
43659
- });
43660
-
43661
- // ../opaque/dist/client/storage/migrations/v8.js
43662
- var LEGACY_STORE_NAMES, v8;
43663
- var init_v8 = __esm({
43664
- "../opaque/dist/client/storage/migrations/v8.js"() {
43665
- "use strict";
43666
- init_constants2();
43667
- LEGACY_STORE_NAMES = ["localEvents", "entityCache"];
43668
- v8 = {
43669
- version: 8,
43670
- description: "Rename core stores to canonical server names: localEvents\u2192events, entityCache\u2192latestState",
43671
- up(db) {
43672
- for (const legacy of LEGACY_STORE_NAMES) {
43673
- if (db.objectStoreNames.contains(legacy)) {
43674
- db.deleteObjectStore(legacy);
43675
- }
43676
- }
43677
- if (!db.objectStoreNames.contains(STORES.LATEST_STATE)) {
43678
- const latestState = db.createObjectStore(STORES.LATEST_STATE, {
43679
- keyPath: ["entityId", "branchId"]
43680
- });
43681
- latestState.createIndex("by_entity", "entityId");
43682
- latestState.createIndex("by_scope", ["scope", "scopeId"]);
43683
- latestState.createIndex("by_type", "entityType");
43684
- latestState.createIndex("by_updated", "updatedAt");
43685
- }
43686
- if (!db.objectStoreNames.contains(STORES.EVENTS)) {
43687
- const events = db.createObjectStore(STORES.EVENTS, { keyPath: "id" });
43688
- events.createIndex("by_entity", "entityId");
43689
- events.createIndex("by_hlc", "hlc");
43690
- events.createIndex("by_action", "actionId");
43691
- events.createIndex("by_synced", "synced");
43692
- events.createIndex("by_user_branch", ["userId", "branchId"]);
43693
- }
43694
- }
43695
- };
43696
- }
43697
- });
43698
-
43699
- // ../opaque/dist/client/storage/migrations/v9.js
43700
- var v9;
43701
- var init_v9 = __esm({
43702
- "../opaque/dist/client/storage/migrations/v9.js"() {
43703
- "use strict";
43704
- init_constants2();
43705
- v9 = {
43706
- version: 9,
43707
- description: "loadedSelections store \u2014 server-confirmed (entity, select, branch) load keys",
43708
- up(db) {
43709
- if (!db.objectStoreNames.contains(STORES.LOADED_SELECTIONS)) {
43710
- db.createObjectStore(STORES.LOADED_SELECTIONS, { keyPath: "key" });
43711
- }
43712
- }
43713
- };
43714
- }
43715
- });
43716
-
43717
- // ../opaque/dist/client/storage/migrations/v10.js
43718
- var LEGACY_TEXT_ENTITY_TYPES, v10;
43719
- var init_v10 = __esm({
43720
- "../opaque/dist/client/storage/migrations/v10.js"() {
43721
- "use strict";
43722
- init_constants2();
43723
- LEGACY_TEXT_ENTITY_TYPES = ["opRichTextRun", "opRichTextCursor"];
43724
- v10 = {
43725
- version: 10,
43726
- description: "Drop cached latestState records under the pre-rename text entity types (opRichTextRun/opRichTextCursor) and the loadedSelections claims that describe them; they re-sync under opTextRun/opTextCursor",
43727
- up(db, tx) {
43728
- if (!db.objectStoreNames.contains(STORES.LATEST_STATE))
43729
- return;
43730
- const store = tx.objectStore(STORES.LATEST_STATE);
43731
- if (!store.indexNames.contains("by_type"))
43732
- return;
43733
- const swallow = (request3) => {
43734
- request3.onerror = (event) => {
43735
- event.preventDefault();
43736
- event.stopPropagation();
43737
- };
43738
- };
43739
- let purged = false;
43740
- const clearLoadedSelectionsOnce = () => {
43741
- if (purged)
43742
- return;
43743
- purged = true;
43744
- if (!db.objectStoreNames.contains(STORES.LOADED_SELECTIONS))
43745
- return;
43746
- swallow(tx.objectStore(STORES.LOADED_SELECTIONS).clear());
43747
- };
43748
- const byType = store.index("by_type");
43749
- for (const legacyType of LEGACY_TEXT_ENTITY_TYPES) {
43750
- const cursorRequest = byType.openCursor(IDBKeyRange.only(legacyType));
43751
- cursorRequest.onsuccess = () => {
43752
- const cursor = cursorRequest.result;
43753
- if (!cursor)
43754
- return;
43755
- swallow(cursor.delete());
43756
- clearLoadedSelectionsOnce();
43757
- cursor.continue();
43758
- };
43759
- swallow(cursorRequest);
43760
- }
43761
- }
43762
- };
43763
- }
43764
- });
43765
-
43766
- // ../opaque/dist/client/storage/migrations/v11.js
43767
- var v11;
43768
- var init_v11 = __esm({
43769
- "../opaque/dist/client/storage/migrations/v11.js"() {
43770
- "use strict";
43771
- init_constants2();
43772
- v11 = {
43773
- version: 11,
43774
- description: "events by_branch_type index \u2014 branch-wide exclusion seed",
43775
- up(_db, tx) {
43776
- if (!tx.objectStoreNames.contains(STORES.EVENTS))
43777
- return;
43778
- const events = tx.objectStore(STORES.EVENTS);
43779
- if (!events.indexNames.contains("by_branch_type")) {
43780
- events.createIndex("by_branch_type", ["branchId", "type"]);
43781
- }
43782
- }
43783
- };
43784
- }
43785
- });
43786
-
43787
- // ../opaque/dist/client/storage/migrations/index.js
43788
- function runMigrations(db, tx, oldVersion) {
43789
- for (const migration of MIGRATIONS) {
43790
- if (migration.version > oldVersion) {
43791
- migration.up(db, tx, oldVersion);
43792
- }
43793
- }
43794
- }
43795
- var MIGRATIONS;
43796
- var init_migrations = __esm({
43797
- "../opaque/dist/client/storage/migrations/index.js"() {
43798
- "use strict";
43799
- init_v1();
43800
- init_v2();
43801
- init_v3();
43802
- init_v4();
43803
- init_v5();
43804
- init_v6();
43805
- init_v7();
43806
- init_v8();
43807
- init_v9();
43808
- init_v10();
43809
- init_v11();
43810
- MIGRATIONS = [
43811
- v1,
43812
- v2,
43813
- v3,
43814
- v4,
43815
- v5,
43816
- v6,
43817
- v7,
43818
- v8,
43819
- v9,
43820
- v10,
43821
- v11
43822
- ].sort((a5, b4) => a5.version - b4.version);
43823
- }
43824
- });
43825
-
43826
- // ../opaque/dist/client/storage/schema.js
43827
- function openDatabase(timeoutMs = OPEN_DATABASE_TIMEOUT_MS, databaseName = DB_NAME) {
43828
- return new Promise((resolve6, reject) => {
43829
- const request3 = indexedDB.open(databaseName, DB_VERSION);
43830
- let settled = false;
43831
- const timer = setTimeout(() => {
43832
- if (settled)
43833
- return;
43834
- settled = true;
43835
- reject(new IndexedDbOpenBlockedError("timeout"));
43836
- }, timeoutMs);
43837
- const settle = (fn2) => {
43838
- if (settled)
43839
- return;
43840
- settled = true;
43841
- clearTimeout(timer);
43842
- fn2();
43843
- };
43844
- request3.onblocked = () => {
43845
- settle(() => reject(new IndexedDbOpenBlockedError("blocked")));
43846
- };
43847
- request3.onerror = () => settle(() => reject(request3.error));
43848
- request3.onsuccess = () => {
43849
- const db = request3.result;
43850
- if (settled) {
43851
- db.close();
43852
- return;
43853
- }
43854
- db.onversionchange = () => db.close();
43855
- settle(() => resolve6(db));
43856
- };
43857
- request3.onupgradeneeded = (event) => {
43858
- const db = request3.result;
43859
- const tx = request3.transaction;
43860
- if (!tx)
43861
- return;
43862
- runMigrations(db, tx, event.oldVersion);
43863
- };
43864
- });
43865
- }
43866
- function idbGet(db, storeName, key) {
43867
- return new Promise((resolve6, reject) => {
43868
- const tx = db.transaction(storeName, "readonly");
43869
- const store = tx.objectStore(storeName);
43870
- const request3 = store.get(key);
43871
- request3.onsuccess = () => resolve6(request3.result);
43872
- request3.onerror = () => reject(request3.error);
43873
- });
43874
- }
43875
- function idbPut(db, storeName, value) {
43876
- return new Promise((resolve6, reject) => {
43877
- const tx = db.transaction(storeName, "readwrite");
43878
- const store = tx.objectStore(storeName);
43879
- const request3 = store.put(value);
43880
- request3.onsuccess = () => resolve6(request3.result);
43881
- request3.onerror = () => reject(request3.error);
43882
- });
43883
- }
43884
- function idbDelete(db, storeName, key) {
43885
- return new Promise((resolve6, reject) => {
43886
- const tx = db.transaction(storeName, "readwrite");
43887
- const store = tx.objectStore(storeName);
43888
- const request3 = store.delete(key);
43889
- request3.onsuccess = () => resolve6();
43890
- request3.onerror = () => reject(request3.error);
43891
- });
43892
- }
43893
- function idbGetAll(db, storeName) {
43894
- return new Promise((resolve6, reject) => {
43895
- const tx = db.transaction(storeName, "readonly");
43896
- const store = tx.objectStore(storeName);
43897
- const request3 = store.getAll();
43898
- request3.onsuccess = () => resolve6(request3.result);
43899
- request3.onerror = () => reject(request3.error);
43900
- });
43901
- }
43902
- function idbGetAllByIndex(db, storeName, indexName, key) {
43903
- return new Promise((resolve6, reject) => {
43904
- const tx = db.transaction(storeName, "readonly");
43905
- const store = tx.objectStore(storeName);
43906
- const index = store.index(indexName);
43907
- const request3 = index.getAll(key);
43908
- request3.onsuccess = () => resolve6(request3.result);
43909
- request3.onerror = () => reject(request3.error);
43910
- });
43911
- }
43912
- function idbGetEntityLastHlc(db, entityId) {
43913
- return new Promise((resolve6, reject) => {
43914
- const tx = db.transaction(STORES.LATEST_STATE, "readonly");
43915
- const index = tx.objectStore(STORES.LATEST_STATE).index("by_entity");
43916
- const request3 = index.getAll(entityId);
43917
- request3.onsuccess = () => {
43918
- const records2 = request3.result;
43919
- if (records2.length === 0)
43920
- return resolve6(null);
43921
- let max = records2[0].lastHlc;
43922
- for (const r of records2)
43923
- if (r.lastHlc > max)
43924
- max = r.lastHlc;
43925
- resolve6(max);
43926
- };
43927
- request3.onerror = () => reject(request3.error);
43928
- });
43929
- }
43930
- function idbPutMany(db, storeName, values) {
43931
- return new Promise((resolve6, reject) => {
43932
- const tx = db.transaction(storeName, "readwrite");
43933
- const store = tx.objectStore(storeName);
43934
- tx.oncomplete = () => resolve6();
43935
- tx.onerror = () => reject(tx.error);
43936
- for (const value of values) {
43937
- store.put(value);
43938
- }
43939
- });
43940
- }
43941
- function idbDeleteMany(db, storeName, keys) {
43942
- return new Promise((resolve6, reject) => {
43943
- const tx = db.transaction(storeName, "readwrite");
43944
- const store = tx.objectStore(storeName);
43945
- tx.oncomplete = () => resolve6();
43946
- tx.onerror = () => reject(tx.error);
43947
- for (const key of keys) {
43948
- store.delete(key);
43949
- }
43950
- });
43951
- }
43952
- function idbClear(db, storeName) {
43953
- return new Promise((resolve6, reject) => {
43954
- const tx = db.transaction(storeName, "readwrite");
43955
- const store = tx.objectStore(storeName);
43956
- const request3 = store.clear();
43957
- request3.onsuccess = () => resolve6();
43958
- request3.onerror = () => reject(request3.error);
43959
- });
43960
- }
43961
- var OPEN_DATABASE_TIMEOUT_MS, IndexedDbOpenBlockedError;
43962
- var init_schema4 = __esm({
43963
- "../opaque/dist/client/storage/schema.js"() {
43964
- "use strict";
43965
- init_migrations();
43966
- init_constants2();
43967
- init_constants2();
43968
- OPEN_DATABASE_TIMEOUT_MS = 5e3;
43969
- IndexedDbOpenBlockedError = class extends Error {
43970
- constructor(reason) {
43971
- super(reason === "blocked" ? "IndexedDB open blocked: another tab holds an older version of the database" : `IndexedDB open did not settle within ${OPEN_DATABASE_TIMEOUT_MS}ms`);
43972
- this.name = "IndexedDbOpenBlockedError";
43973
- }
43974
- };
43975
- }
43976
- });
43977
-
43978
44329
  // ../opaque/dist/client/storage/writeQueue.js
43979
44330
  var WriteQueue;
43980
44331
  var init_writeQueue = __esm({
@@ -44189,177 +44540,6 @@ var init_knownState = __esm({
44189
44540
  }
44190
44541
  });
44191
44542
 
44192
- // ../opaque/dist/client/storage/utils.js
44193
- function getMaxHlc(events) {
44194
- if (events.length === 0)
44195
- return "0";
44196
- return events.reduce((max, e2) => HLC.compare(e2.hlc, max) > 0 ? e2.hlc : max, "0");
44197
- }
44198
- function eventBranchId(event) {
44199
- return event.branchId ?? void 0;
44200
- }
44201
- function groupEventsByBranch(events) {
44202
- const groups = /* @__PURE__ */ new Map();
44203
- for (const event of events) {
44204
- const key = eventBranchId(event) ?? "";
44205
- const bucket = groups.get(key);
44206
- if (bucket)
44207
- bucket.push(event);
44208
- else
44209
- groups.set(key, [event]);
44210
- }
44211
- return groups;
44212
- }
44213
- function applyLWWEvents(events, existingState, existingLastHlc, existingFieldHlcs, existingFieldActions) {
44214
- const state = existingState ? { ...existingState } : {};
44215
- const fieldHlcs = existingFieldHlcs ? { ...existingFieldHlcs } : {};
44216
- if (!existingFieldHlcs && existingState && existingLastHlc) {
44217
- for (const key of Object.keys(existingState)) {
44218
- fieldHlcs[key] = existingLastHlc;
44219
- }
44220
- }
44221
- const fieldActions = existingFieldActions ? { ...existingFieldActions } : {};
44222
- const sortedEvents = sortByHlc(events, "asc");
44223
- for (const event of sortedEvents) {
44224
- if (isTombstoneEvent(event)) {
44225
- state.deletedAt = event.hlc;
44226
- fieldHlcs.deletedAt = event.hlc;
44227
- fieldActions.deletedAt = event.actionId;
44228
- continue;
44229
- }
44230
- if (event.type === "upsert" && event.field) {
44231
- const currentHlc = fieldHlcs[event.field];
44232
- if (!currentHlc || HLC.compare(event.hlc, currentHlc) > 0) {
44233
- state[event.field] = event.value;
44234
- fieldHlcs[event.field] = event.hlc;
44235
- fieldActions[event.field] = event.actionId;
44236
- }
44237
- }
44238
- }
44239
- if (events.length > 0) {
44240
- const firstEvent = events[0];
44241
- state.id = firstEvent.entityId;
44242
- state.modelName = firstEvent.entityType;
44243
- }
44244
- const eventsMaxHlc = getMaxHlc(events);
44245
- const lastHlc = existingLastHlc && HLC.compare(existingLastHlc, eventsMaxHlc) > 0 ? existingLastHlc : eventsMaxHlc;
44246
- return { state, fieldHlcs, fieldActions, lastHlc };
44247
- }
44248
- var init_utils4 = __esm({
44249
- "../opaque/dist/client/storage/utils.js"() {
44250
- "use strict";
44251
- init_types2();
44252
- init_hlc();
44253
- }
44254
- });
44255
-
44256
- // ../opaque/dist/client/storage/indexeddb/utils.js
44257
- function foldLatestStateRecords(records2) {
44258
- if (records2.length === 0)
44259
- return null;
44260
- if (records2.length === 1) {
44261
- return {
44262
- state: records2[0].state,
44263
- ...records2[0].fieldActions !== void 0 && {
44264
- fieldActions: records2[0].fieldActions
44265
- },
44266
- ...records2[0].fieldHlcs !== void 0 && {
44267
- fieldHlcs: records2[0].fieldHlcs
44268
- }
44269
- };
44270
- }
44271
- const ordered = [...records2].sort((a5, b4) => HLC.compare(a5.lastHlc, b4.lastHlc));
44272
- const merged = {};
44273
- const mergedActions = {};
44274
- let anyActions = false;
44275
- const mergedHlcs = {};
44276
- let anyHlcs = false;
44277
- for (const record of ordered) {
44278
- for (const [field, value] of Object.entries(record.state)) {
44279
- merged[field] = value;
44280
- const action = record.fieldActions?.[field];
44281
- if (action !== void 0) {
44282
- mergedActions[field] = action;
44283
- anyActions = true;
44284
- } else {
44285
- delete mergedActions[field];
44286
- }
44287
- const hlc = record.fieldHlcs?.[field];
44288
- if (hlc !== void 0) {
44289
- mergedHlcs[field] = hlc;
44290
- anyHlcs = true;
44291
- } else {
44292
- delete mergedHlcs[field];
44293
- }
44294
- }
44295
- }
44296
- return {
44297
- state: merged,
44298
- ...anyActions && { fieldActions: mergedActions },
44299
- ...anyHlcs && { fieldHlcs: mergedHlcs }
44300
- };
44301
- }
44302
- function groupBy(items, keyFn) {
44303
- const groups = {};
44304
- for (const item of items) {
44305
- const key = keyFn(item);
44306
- if (!groups[key]) {
44307
- groups[key] = [];
44308
- }
44309
- groups[key].push(item);
44310
- }
44311
- return groups;
44312
- }
44313
- function eventToRecord(event, synced = 1, actionTargetScope, actionHardDeleteScope) {
44314
- return {
44315
- id: event.id,
44316
- entityId: event.entityId,
44317
- entityType: event.entityType,
44318
- field: event.field,
44319
- value: event.value,
44320
- previousValue: event.previousValue,
44321
- hlc: event.hlc,
44322
- clientId: event.clientId,
44323
- userId: event.userId,
44324
- actionId: event.actionId,
44325
- actionLabel: event.actionLabel,
44326
- type: event.type,
44327
- mergeId: event.mergeId,
44328
- targetId: event.targetId,
44329
- branchId: event.branchId,
44330
- parentScopeId: event.parentScopeId,
44331
- actionTargetScope,
44332
- actionHardDeleteScope,
44333
- synced
44334
- };
44335
- }
44336
- function recordToEvent(record) {
44337
- return {
44338
- id: record.id,
44339
- type: record.type,
44340
- entityId: record.entityId,
44341
- entityType: record.entityType,
44342
- field: record.field,
44343
- value: record.value,
44344
- previousValue: record.previousValue,
44345
- hlc: record.hlc,
44346
- clientId: record.clientId,
44347
- userId: record.userId,
44348
- actionId: record.actionId,
44349
- actionLabel: record.actionLabel,
44350
- mergeId: record.mergeId,
44351
- targetId: record.targetId,
44352
- branchId: record.branchId,
44353
- parentScopeId: record.parentScopeId
44354
- };
44355
- }
44356
- var init_utils5 = __esm({
44357
- "../opaque/dist/client/storage/indexeddb/utils.js"() {
44358
- "use strict";
44359
- init_hlc();
44360
- }
44361
- });
44362
-
44363
44543
  // ../opaque/dist/client/storage/entityLoader.js
44364
44544
  var SINGLE_NAMESPACE_METADATA_TYPES, REDACTED_STATE_KEYS, EntityLoader;
44365
44545
  var init_entityLoader = __esm({
@@ -44872,6 +45052,12 @@ function inferScopeFromEntityType(entityType) {
44872
45052
  }
44873
45053
  return CollabScope.branch;
44874
45054
  }
45055
+ function transactionRequest(request3) {
45056
+ return new Promise((resolve6, reject) => {
45057
+ request3.onsuccess = () => resolve6(request3.result);
45058
+ request3.onerror = () => reject(request3.error);
45059
+ });
45060
+ }
44875
45061
  var LatestStateManager;
44876
45062
  var init_latestState = __esm({
44877
45063
  "../opaque/dist/client/storage/indexeddb/latestState.js"() {
@@ -44899,7 +45085,7 @@ var init_latestState = __esm({
44899
45085
  * being lost on reload. `scopeId` is the branch the caller wrote under; it's
44900
45086
  * the namespace for events that don't carry their own `branchId`.
44901
45087
  */
44902
- async updateEntityCache(entityId, events, scopeId) {
45088
+ async updateEntityCache(entityId, events, scopeId, transaction) {
44903
45089
  const byBranch = /* @__PURE__ */ new Map();
44904
45090
  for (const event of events) {
44905
45091
  const branchId = eventBranchId(event) ?? (isTextContentType(event.entityType) || isUnbranchedCustomScopeType(event.entityType) ? GLOBAL_NAMESPACE_BRANCH_KEY : scopeId);
@@ -44910,12 +45096,15 @@ var init_latestState = __esm({
44910
45096
  byBranch.set(branchId, [event]);
44911
45097
  }
44912
45098
  for (const [branchId, branchEvents] of byBranch) {
44913
- await this.writeBranchRecord(entityId, branchId, branchEvents, scopeId);
45099
+ await this.writeBranchRecord(entityId, branchId, branchEvents, scopeId, transaction);
44914
45100
  }
44915
45101
  }
44916
45102
  /** Fold one branch's events onto its existing record and persist it. */
44917
- async writeBranchRecord(entityId, branchId, events, fallbackScopeId) {
44918
- const existing = await idbGet(this.db, STORES.LATEST_STATE, [entityId, branchId]);
45103
+ async writeBranchRecord(entityId, branchId, events, fallbackScopeId, transaction) {
45104
+ const existing = transaction ? await transactionRequest(transaction.objectStore(STORES.LATEST_STATE).get([entityId, branchId])) : await idbGet(this.db, STORES.LATEST_STATE, [
45105
+ entityId,
45106
+ branchId
45107
+ ]);
44919
45108
  const entityType = events[0]?.entityType ?? existing?.entityType ?? "unknown";
44920
45109
  const contentCohabitsBranch = isTextContentType(entityType) && (isBranchId(branchId) || branchId === GLOBAL_NAMESPACE_BRANCH_KEY);
44921
45110
  const scope = existing?.scope ?? (contentCohabitsBranch ? CollabScope.branch : inferScopeFromEntityType(entityType));
@@ -44959,7 +45148,10 @@ var init_latestState = __esm({
44959
45148
  fieldActions,
44960
45149
  updatedAt: Date.now()
44961
45150
  };
44962
- await idbPut(this.db, STORES.LATEST_STATE, cacheRecord);
45151
+ if (transaction)
45152
+ await transactionRequest(transaction.objectStore(STORES.LATEST_STATE).put(cacheRecord));
45153
+ else
45154
+ await idbPut(this.db, STORES.LATEST_STATE, cacheRecord);
44963
45155
  }
44964
45156
  /**
44965
45157
  * Remove a dropped action's contribution from the entities' LATEST_STATE
@@ -45351,8 +45543,10 @@ var PendingActionsManager;
45351
45543
  var init_pendingActions = __esm({
45352
45544
  "../opaque/dist/client/storage/indexeddb/pendingActions.js"() {
45353
45545
  "use strict";
45546
+ init_dist();
45354
45547
  init_schema4();
45355
45548
  init_utils4();
45549
+ init_hlc();
45356
45550
  init_utils5();
45357
45551
  PendingActionsManager = class {
45358
45552
  db;
@@ -45365,18 +45559,52 @@ var init_pendingActions = __esm({
45365
45559
  }
45366
45560
  /**
45367
45561
  * Store a locally-created action (not yet sent to server).
45368
- * Writes to EVENTS (source of truth) and LATEST_STATE (computed state).
45562
+ * Commit EVENTS and LATEST_STATE together so refresh cannot restore a partial action.
45369
45563
  *
45370
45564
  * @param action - The action to store
45371
45565
  * @param scopeId - The scope ID (branch ID) for entity cache updates
45372
45566
  */
45373
45567
  async storePendingAction(action, scopeId) {
45374
- const eventRecords = action.events.map((e2) => eventToRecord(e2, 0, action.targetScope, action.hardDeleteScope));
45375
- await idbPutMany(this.db, STORES.EVENTS, eventRecords);
45376
- const byEntity = groupBy(action.events, (e2) => e2.entityId);
45377
- for (const [entityId, entityEvents] of Object.entries(byEntity)) {
45378
- await this.latestStateManager.updateEntityCache(entityId, entityEvents, scopeId);
45568
+ const started = performance.now();
45569
+ const tx = this.db.transaction([STORES.EVENTS, STORES.LATEST_STATE], "readwrite");
45570
+ const completion = new Promise((resolve6, reject) => {
45571
+ tx.oncomplete = () => resolve6();
45572
+ tx.onabort = () => reject(tx.error ?? new Error("Action transaction aborted."));
45573
+ tx.onerror = () => {
45574
+ };
45575
+ });
45576
+ void completion.catch(() => {
45577
+ });
45578
+ let eventsStored = started;
45579
+ try {
45580
+ for (const event of action.events) {
45581
+ tx.objectStore(STORES.EVENTS).put({
45582
+ ...eventToRecord(event, 0, action.targetScope, action.hardDeleteScope),
45583
+ actionLabel: event.actionLabel ?? action.label
45584
+ });
45585
+ }
45586
+ eventsStored = performance.now();
45587
+ const byEntity = groupBy(action.events, (event) => event.entityId);
45588
+ for (const [entityId, entityEvents] of Object.entries(byEntity)) {
45589
+ await this.latestStateManager.updateEntityCache(entityId, entityEvents, scopeId, tx);
45590
+ }
45591
+ await completion;
45592
+ } catch (error) {
45593
+ try {
45594
+ tx.abort();
45595
+ } catch {
45596
+ }
45597
+ await completion.catch(() => {
45598
+ });
45599
+ throw error;
45379
45600
  }
45601
+ traceMark("client.action.persist", {
45602
+ actionId: action.id,
45603
+ branchId: scopeId,
45604
+ events: action.events.length,
45605
+ eventStoreMs: eventsStored - started,
45606
+ latestStateMs: performance.now() - eventsStored
45607
+ });
45380
45608
  }
45381
45609
  /**
45382
45610
  * Get all pending actions (unsynced events grouped by actionId).
@@ -45387,7 +45615,11 @@ var init_pendingActions = __esm({
45387
45615
  if (unsyncedEvents.length === 0) {
45388
45616
  return [];
45389
45617
  }
45390
- const byAction = groupBy(unsyncedEvents.map(recordToEvent), (e2) => e2.actionId);
45618
+ const byAction = groupBy(
45619
+ // IndexedDB indexes return primary-key order. Routing uses the first authored event.
45620
+ sortByHlc(unsyncedEvents).map(recordToEvent),
45621
+ (e2) => e2.actionId
45622
+ );
45391
45623
  const recordsByAction = groupBy(unsyncedEvents, (record) => record.actionId);
45392
45624
  const actions = Object.entries(byAction).map(([actionId, events]) => {
45393
45625
  const records2 = recordsByAction[actionId] ?? [];
@@ -46024,6 +46256,7 @@ var init_indexeddb = __esm({
46024
46256
  init_scopeMetadata();
46025
46257
  init_cleanup();
46026
46258
  init_utils5();
46259
+ init_ingestion();
46027
46260
  init_utils5();
46028
46261
  init_latestState();
46029
46262
  init_pendingActions();
@@ -46033,6 +46266,13 @@ var init_indexeddb = __esm({
46033
46266
  init_scopeMetadata();
46034
46267
  init_cleanup();
46035
46268
  BrowserDBStorage = class _BrowserDBStorage {
46269
+ /** Persist fresh events, current state, and the receipt atomically. */
46270
+ async stageBranchIngestion(actions, receipt, prepared) {
46271
+ return stageBranchIngestion(this.db, actions, receipt, prepared);
46272
+ }
46273
+ async getIngestionReceipt(id) {
46274
+ return await idbGet(this.db, STORES.INGESTIONS, id) ?? void 0;
46275
+ }
46036
46276
  db;
46037
46277
  writeQueue;
46038
46278
  knownStateManager;
@@ -47035,6 +47275,11 @@ function handleContext(state, message, cache4, eventHandlers, storage2 = null) {
47035
47275
  state.pendingContextResolve = null;
47036
47276
  state.pendingContextReject = null;
47037
47277
  }
47278
+ if (state.pendingActionReplay && contextMessageMatchesDesired(state, message)) {
47279
+ const replay = state.pendingActionReplay;
47280
+ state.pendingActionReplay = null;
47281
+ replay();
47282
+ }
47038
47283
  const orgChanged = prevOrgId !== nextOrgId;
47039
47284
  const scopeChanged = !scopesEqual(prevScope, nextScope);
47040
47285
  if (orgChanged || scopeChanged) {
@@ -47233,14 +47478,13 @@ function handleAuthenticated(accountId, authState, currentBranch, eventHandlers,
47233
47478
  });
47234
47479
  emitAuthenticated(eventHandlers, accountId);
47235
47480
  const hasDesired = contextState.desiredOrgId !== null || contextState.desiredScope !== null || contextState.desiredRealmId !== null;
47481
+ contextState.pendingActionReplay = hasDesired ? syncPendingActions2 : null;
47236
47482
  if (hasDesired) {
47237
47483
  setOpaqueContext(contextState, {
47238
47484
  orgId: contextState.desiredOrgId,
47239
47485
  scope: contextState.desiredScope,
47240
47486
  realmId: contextState.desiredRealmId
47241
- }, send2, contextTimeout, mode).then(() => {
47242
- syncPendingActions2();
47243
- }).catch((err) => {
47487
+ }, send2, contextTimeout, mode).catch((err) => {
47244
47488
  staffMode.log("[OpaqueClient] Context restore on auth failed; deferring pending actions:", err);
47245
47489
  });
47246
47490
  } else {
@@ -47740,7 +47984,7 @@ function handleInvalidate(message, cache4, storage2, eventHandlers, isActionAwai
47740
47984
  });
47741
47985
  }
47742
47986
  }
47743
- function sendAction(action, storage2, eventHandlers, send2, scopeId, serverProtocolVersion = 1) {
47987
+ function sendAction(action, storage2, eventHandlers, send2, scopeId, serverProtocolVersion = 1, alreadyPersisted = false) {
47744
47988
  if (!action.meta?.requestId) {
47745
47989
  const ambientReqId = currentRequestId();
47746
47990
  const pinnedReqId = ambientReqId && ambientReqId.length > 0 && !ambientReqId.startsWith("sess_") ? ambientReqId : void 0;
@@ -47748,7 +47992,8 @@ function sendAction(action, storage2, eventHandlers, send2, scopeId, serverProto
47748
47992
  action = { ...action, meta: { ...action.meta, requestId: reqId } };
47749
47993
  }
47750
47994
  const storageScopeId = action.targetScope?.scope === "branch" ? action.targetScope.branchId : scopeId;
47751
- fireAndForget(storage2?.storePendingAction(action, storageScopeId), "[OpaqueClient] Failed to store pending action:");
47995
+ if (!alreadyPersisted)
47996
+ fireAndForget(storage2?.storePendingAction(action, storageScopeId), "[OpaqueClient] Failed to store pending action:");
47752
47997
  emitAction(eventHandlers, action);
47753
47998
  const frame = {
47754
47999
  type: "action",
@@ -47849,51 +48094,6 @@ var init_org_membership = __esm({
47849
48094
  }
47850
48095
  });
47851
48096
 
47852
- // ../opaque/dist/client/network/hydrationScheduler.js
47853
- function yieldToMain() {
47854
- const sched = globalThis.scheduler;
47855
- if (sched?.yield)
47856
- return sched.yield();
47857
- if (typeof MessageChannel !== "undefined") {
47858
- return new Promise((resolve6) => {
47859
- const channel = new MessageChannel();
47860
- channel.port1.onmessage = () => resolve6();
47861
- channel.port2.postMessage(null);
47862
- });
47863
- }
47864
- return new Promise((resolve6) => setTimeout(resolve6, 0));
47865
- }
47866
- function createHydrationSlicer(options = {}) {
47867
- const now3 = options.now ?? (() => performance.now());
47868
- let budgetMs = DEFAULT_BUDGET_MS;
47869
- let sliceStart = now3();
47870
- return {
47871
- async tick() {
47872
- const elapsed = now3() - sliceStart;
47873
- if (elapsed < budgetMs)
47874
- return;
47875
- if (elapsed > FRAME_BUDGET_MS) {
47876
- budgetMs = Math.max(MIN_BUDGET_MS, budgetMs - 2);
47877
- } else if (elapsed < budgetMs + 2) {
47878
- budgetMs = Math.min(MAX_BUDGET_MS, budgetMs + 1);
47879
- }
47880
- await yieldToMain();
47881
- options.onResume?.();
47882
- sliceStart = now3();
47883
- }
47884
- };
47885
- }
47886
- var FRAME_BUDGET_MS, DEFAULT_BUDGET_MS, MIN_BUDGET_MS, MAX_BUDGET_MS;
47887
- var init_hydrationScheduler = __esm({
47888
- "../opaque/dist/client/network/hydrationScheduler.js"() {
47889
- "use strict";
47890
- FRAME_BUDGET_MS = 16;
47891
- DEFAULT_BUDGET_MS = 8;
47892
- MIN_BUDGET_MS = 4;
47893
- MAX_BUDGET_MS = 12;
47894
- }
47895
- });
47896
-
47897
48097
  // ../opaque/dist/client/network/offline.js
47898
48098
  function isBranchScopedAction(action) {
47899
48099
  const entityType = action.events[0]?.entityType;
@@ -48373,10 +48573,10 @@ function stripAutoFields(value) {
48373
48573
  return value.map(stripAutoFields);
48374
48574
  if (value && typeof value === "object") {
48375
48575
  const out = {};
48376
- for (const [k, v14] of Object.entries(value)) {
48576
+ for (const [k, v15] of Object.entries(value)) {
48377
48577
  if (k === "id" || k === "createdAt" || k === "updatedAt")
48378
48578
  continue;
48379
- out[k] = stripAutoFields(v14);
48579
+ out[k] = stripAutoFields(v15);
48380
48580
  }
48381
48581
  return out;
48382
48582
  }
@@ -51584,6 +51784,7 @@ var init_client2 = __esm({
51584
51784
  "../opaque/dist/client/client.js"() {
51585
51785
  "use strict";
51586
51786
  init_dist();
51787
+ init_hydrationScheduler();
51587
51788
  init_messaging();
51588
51789
  init_events2();
51589
51790
  init_utils();
@@ -51597,6 +51798,7 @@ var init_client2 = __esm({
51597
51798
  init_files();
51598
51799
  init_cache();
51599
51800
  init_global();
51801
+ init_ingestion();
51600
51802
  init_adopt();
51601
51803
  init_scope_sync();
51602
51804
  init_gap_check();
@@ -52827,6 +53029,152 @@ var init_client2 = __esm({
52827
53029
  // server-side yet). Chaining onto a single Promise preserves the
52828
53030
  // order in which sendAction was called.
52829
53031
  actionQueue = Promise.resolve();
53032
+ stagedActions = /* @__PURE__ */ new Map();
53033
+ pendingIngestions = [];
53034
+ ingestionListeners = /* @__PURE__ */ new Set();
53035
+ ingestionRetries = /* @__PURE__ */ new Map();
53036
+ reservedIngestionEntities = /* @__PURE__ */ new Set();
53037
+ getPendingIngestions = () => this.pendingIngestions;
53038
+ subscribeIngestions = (listener) => {
53039
+ this.ingestionListeners.add(listener);
53040
+ return () => {
53041
+ this.ingestionListeners.delete(listener);
53042
+ };
53043
+ };
53044
+ retryIngestion(id) {
53045
+ this.ingestionRetries.get(id)?.();
53046
+ }
53047
+ setIngestionStatus(receipt, status) {
53048
+ this.pendingIngestions = this.pendingIngestions.filter((entry) => entry.id !== receipt.id);
53049
+ if (status)
53050
+ this.pendingIngestions = [
53051
+ ...this.pendingIngestions,
53052
+ { id: receipt.id, branchId: receipt.branchId, status }
53053
+ ];
53054
+ for (const listener of this.ingestionListeners)
53055
+ listener();
53056
+ }
53057
+ /** Publish fresh entities while one retryable transaction persists them. */
53058
+ async startBranchIngestion(actions, receipt) {
53059
+ const started = performance.now();
53060
+ if (this.ingestionRetries.has(receipt.id))
53061
+ throw new Error("Ingestion is already pending.");
53062
+ const storage2 = this.validateBranchIngestion(actions, receipt);
53063
+ const preflightMs = performance.now() - started;
53064
+ const prepared = prepareBranchIngestion(actions, receipt);
53065
+ let completePersistence;
53066
+ const persistence = new Promise((resolve6) => {
53067
+ completePersistence = resolve6;
53068
+ });
53069
+ let completePublication;
53070
+ const publication = new Promise((resolve6) => {
53071
+ completePublication = resolve6;
53072
+ });
53073
+ let saving = false;
53074
+ const attempt = () => {
53075
+ if (saving)
53076
+ return;
53077
+ saving = true;
53078
+ this.setIngestionStatus(receipt, "saving");
53079
+ void storage2.stageBranchIngestion(actions, receipt, prepared).then((timings) => {
53080
+ this.ingestionRetries.delete(receipt.id);
53081
+ this.setIngestionStatus(receipt);
53082
+ completePersistence(timings);
53083
+ }, (error) => {
53084
+ saving = false;
53085
+ this.setIngestionStatus(receipt, "failed");
53086
+ console.error("[OpaqueClient] Ingestion persistence failed; retry is available:", error);
53087
+ });
53088
+ };
53089
+ this.ingestionRetries.set(receipt.id, attempt);
53090
+ this.actionQueue = this.actionQueue.then(() => Promise.all([persistence, publication])).then(() => {
53091
+ });
53092
+ for (const action of actions) {
53093
+ for (const event of action.events)
53094
+ this.reservedIngestionEntities.add(`${receipt.branchId}:${event.entityId}`);
53095
+ this.stagedActions.set(action.id, action.events.length);
53096
+ this.sendAction(action);
53097
+ }
53098
+ attempt();
53099
+ const cache4 = await this.publishBranchIngestion(actions, receipt, true);
53100
+ completePublication();
53101
+ for (const action of actions) {
53102
+ for (const event of action.events)
53103
+ this.reservedIngestionEntities.delete(`${receipt.branchId}:${event.entityId}`);
53104
+ }
53105
+ return { preflightMs, ...cache4, persistence };
53106
+ }
53107
+ validateBranchIngestion(actions, receipt) {
53108
+ const storage2 = this.getStorage();
53109
+ if (!storage2)
53110
+ throw new Error("Browser storage is not ready.");
53111
+ if (this.cache.getEntity(receipt.branchId, receipt.branchId)?.onlyAcceptsMerges)
53112
+ throw new Error("The target branch only accepts merges.");
53113
+ const checkedEntities = /* @__PURE__ */ new Set();
53114
+ for (const action of actions) {
53115
+ if (action.events.length > MAX_INBOUND_ACTION_EVENTS)
53116
+ throw new Error("Ingestion action exceeds the event limit.");
53117
+ if (messageByteLength({ type: "action", action }) > MAX_OUTBOUND_MESSAGE_BYTES)
53118
+ throw new Error("Ingestion action exceeds the frame limit.");
53119
+ for (const event of action.events) {
53120
+ if (checkedEntities.has(event.entityId))
53121
+ continue;
53122
+ checkedEntities.add(event.entityId);
53123
+ if (this.reservedIngestionEntities.has(`${receipt.branchId}:${event.entityId}`) || this.cache.getEntity(event.entityId, receipt.branchId))
53124
+ throw new Error("Ingestion cannot overwrite an existing entity.");
53125
+ }
53126
+ }
53127
+ return storage2;
53128
+ }
53129
+ /** Commit fresh branch events before publishing them to local readers. */
53130
+ async ingestBranchActions(actions, receipt) {
53131
+ const started = performance.now();
53132
+ const storage2 = this.validateBranchIngestion(actions, receipt);
53133
+ const commitStart = performance.now();
53134
+ const storageTimings = await storage2.stageBranchIngestion(actions, receipt);
53135
+ const commitMs = performance.now() - commitStart;
53136
+ const cache4 = await this.publishBranchIngestion(actions, receipt);
53137
+ return {
53138
+ commitMs,
53139
+ ...cache4,
53140
+ preflightMs: commitStart - started,
53141
+ storagePrepareMs: storageTimings.prepareMs,
53142
+ storageTransactionMs: storageTimings.transactionMs
53143
+ };
53144
+ }
53145
+ async publishBranchIngestion(actions, receipt, alreadyQueued = false) {
53146
+ const cacheStart = performance.now();
53147
+ const slicer = createHydrationSlicer();
53148
+ let lastEntity = "";
53149
+ let cacheApplied = cacheStart;
53150
+ this.cache.beginInvalidationBatch();
53151
+ try {
53152
+ for (const action of actions) {
53153
+ for (const event of action.events) {
53154
+ if (event.entityId !== lastEntity) {
53155
+ await slicer.tick();
53156
+ lastEntity = event.entityId;
53157
+ }
53158
+ this.cache.applyPendingEvent(event, receipt.branchId);
53159
+ }
53160
+ if (!alreadyQueued)
53161
+ this.stagedActions.set(action.id, action.events.length);
53162
+ }
53163
+ cacheApplied = performance.now();
53164
+ if (!alreadyQueued)
53165
+ for (const action of actions)
53166
+ this.sendAction(action);
53167
+ } finally {
53168
+ this.cache.endInvalidationBatch();
53169
+ }
53170
+ this.emitLocalChange();
53171
+ const finished = performance.now();
53172
+ return {
53173
+ cacheMs: finished - cacheStart,
53174
+ cacheApplyMs: cacheApplied - cacheStart,
53175
+ cachePublishMs: finished - cacheApplied
53176
+ };
53177
+ }
52830
53178
  // Action methods
52831
53179
  sendAction(action) {
52832
53180
  const scopedAction = this.withActionTargetScope(action);
@@ -52888,6 +53236,7 @@ var init_client2 = __esm({
52888
53236
  const overByteCap = byteLength > MAX_OUTBOUND_MESSAGE_BYTES;
52889
53237
  const overEventCap = action.events.length > MAX_INBOUND_ACTION_EVENTS;
52890
53238
  if (overByteCap || overEventCap) {
53239
+ this.stagedActions.delete(action.id);
52891
53240
  this.cache.removeByActionId(action.id);
52892
53241
  fireAndForget(this.connectionState.storage?.deletePendingAction(action.id), "[OpaqueClient] Failed to drop oversized action:");
52893
53242
  staffMode.log("[OpaqueClient] Action refused: exceeds a delivery limit (dropped):", {
@@ -52908,7 +53257,12 @@ var init_client2 = __esm({
52908
53257
  });
52909
53258
  return;
52910
53259
  }
52911
- sendAction(action, this.connectionState.storage, this.eventHandlers, (msg, preEncoded) => this.send(msg, preEncoded), this.currentBranch, this.authState.serverProtocolVersion);
53260
+ const stagedCount = this.stagedActions.get(action.id);
53261
+ if (stagedCount !== void 0 && stagedCount !== action.events.length) {
53262
+ await this.connectionState.storage?.storePendingAction(action, action.targetScope?.scope === "branch" ? action.targetScope.branchId : this.currentBranch);
53263
+ }
53264
+ this.stagedActions.delete(action.id);
53265
+ sendAction(action, this.connectionState.storage, this.eventHandlers, (msg, preEncoded) => this.send(msg, preEncoded), this.currentBranch, this.authState.serverProtocolVersion, stagedCount !== void 0);
52912
53266
  }
52913
53267
  async flushActions() {
52914
53268
  await this.actionQueue;
@@ -54092,6 +54446,12 @@ var init_opaque_config = __esm({
54092
54446
  // publishes again. A project that has never published has no registry row,
54093
54447
  // and the handler treats that as done rather than as an error.
54094
54448
  "project.setPackagePrivacy",
54449
+ // Brand actions. `brand.traceLogo` traces one picked logo candidate (a
54450
+ // PNG crop) into one master SVG and returns it in the request result. It
54451
+ // rides the Brand, reads the crop from the request's own project scope,
54452
+ // and spends CPU, not money, so it has no ADMIN_ONLY_ACTIONS entry. The
54453
+ // handler is packages/service-worker/src/handlers/logo.ts.
54454
+ "brand.traceLogo",
54095
54455
  // Marketing actions. Registers a newly created account in Resend: segment
54096
54456
  // membership plus topic subscriptions. Runs on the User entity, off the
54097
54457
  // sign-up request path, so a Resend outage or rate limit retries through the
@@ -54185,12 +54545,12 @@ function def(type, description, input, options) {
54185
54545
  function getOpaqueActionDef(type) {
54186
54546
  return OPAQUE_ACTIONS.find((a5) => a5.type === type);
54187
54547
  }
54188
- var shaderLayersSchema, variableValue, STYLE_KEYS, STYLE_TRAPS, nodeUpdatesSchema, ORGANIZATION_ACTION_TYPES, componentId, pageId, variantId, OPAQUE_ACTIONS;
54548
+ var shaderLayersSchema, variableValue, STYLE_KEYS, STYLE_TRAPS, SVG_ARTWORK_DESCRIPTION, nodeUpdatesSchema, ORGANIZATION_ACTION_TYPES, componentId, pageId, variantId, OPAQUE_ACTIONS;
54189
54549
  var init_opaqueActions = __esm({
54190
54550
  "../shared/dist/ai/opaque/opaqueActions.js"() {
54191
54551
  "use strict";
54192
54552
  init_ai_action_style_keys();
54193
- shaderLayersSchema = z52.array(z52.record(z52.string(), z52.unknown())).describe("Shader layer specs, one per layer. Each matches the ShaderLayer shape: name (string), sortOrder (number), visible (boolean), effectType (e.g. 'meshGradient', 'perlinNoise'), blendMode, opacity/animated/animationSpeed/scale/offsetX/offsetY/rotation and effect-specific numeric params as plain numbers, color1/color2/color3/colorBack as hex or rgb(a) strings, colors as an array of such strings.");
54553
+ shaderLayersSchema = z52.array(z52.record(z52.string(), z52.unknown())).describe("Shader layer specs, one per layer. Each matches the ShaderLayer shape: name (string), sortOrder (number), visible (boolean), effectType (e.g. 'meshGradient', 'perlinNoise'), blendMode, opacity/animated/animationSpeed/scale/offsetX/offsetY/rotation and effect-specific numeric params as plain numbers, color1/color2/color3/colorBack as hex or rgb(a) strings, colors as an array of such strings. Only catalog effects are supported; this field does not accept custom GLSL or WGSL source.");
54194
54554
  variableValue = z52.union([
54195
54555
  z52.string(),
54196
54556
  z52.number(),
@@ -54209,10 +54569,11 @@ var init_opaqueActions = __esm({
54209
54569
  "`display` / `flex` \u2192 use flexDirection, justifyContent, alignItems",
54210
54570
  "`textColor` \u2192 use color"
54211
54571
  ].join("; ");
54572
+ SVG_ARTWORK_DESCRIPTION = "Accepts a complete SVG document or bare path data. Imports supported geometry into an editable vector network. The renderer uses SVG baked from that network, not the original document. Supply a viewBox to define the artwork dimensions. Check warnings for unsupported elements. This is not a runtime for scripts or SVG/CSS animation.";
54212
54573
  nodeUpdatesSchema = z52.object({
54213
54574
  name: z52.string().optional().describe("Layer name"),
54214
54575
  innerText: z52.string().optional().describe("Text content (text nodes only)"),
54215
- svgPath: z52.string().optional().describe("Import SVG markup or path data as editable vector artwork. This promotes the node to 'vector' and replaces its entire network. Replacement does not preserve existing layer IDs, constraints, or variable bindings."),
54576
+ svgPath: z52.string().optional().describe(SVG_ARTWORK_DESCRIPTION + " This promotes the node to 'vector' and replaces its entire network. Replacement does not preserve existing layer IDs, constraints, or variable bindings."),
54216
54577
  shaderLayers: shaderLayersSchema.optional().describe("Replaces the node's shader layers - GPU effects drawn over the node's own content. Boxes only."),
54217
54578
  // Real node fields that were previously unreachable through BOTH edit
54218
54579
  // surfaces: they are not styles, so they fell into `styles.base` and were
@@ -54225,7 +54586,7 @@ var init_opaqueActions = __esm({
54225
54586
  className: z52.string().optional().describe("CSS class name(s) applied to the rendered element."),
54226
54587
  url: z52.string().optional().describe("Link destination for a link node."),
54227
54588
  target: z52.string().optional().describe("Link target: 'self' or 'blank'."),
54228
- frameUrl: z52.string().optional().describe("URL an iframe node loads."),
54589
+ frameUrl: z52.string().optional().describe("URL an iframe node loads. Canvas and deployment use an empty sandbox, which blocks scripts. Use svgPath to import editable vector geometry. It does not preserve an animation document."),
54229
54590
  styles: z52.object({
54230
54591
  base: z52.record(z52.string(), z52.unknown()).optional().describe(`Visual properties. VALID KEYS \u2014 no others are accepted, and one invalid key rejects the WHOLE edit: ${STYLE_KEYS.join(", ")}. Common mistakes: ${STYLE_TRAPS}.`)
54231
54592
  }).optional()
@@ -54277,7 +54638,7 @@ var init_opaqueActions = __esm({
54277
54638
  "textarea",
54278
54639
  "text"
54279
54640
  ]).optional().describe("For nodeType 'input': which form control this node renders (default 'text')."),
54280
- svgPath: z52.string().optional().describe("Required when nodeType is 'vector': the SVG markup/path."),
54641
+ svgPath: z52.string().optional().describe("Required when nodeType is 'vector'. " + SVG_ARTWORK_DESCRIPTION),
54281
54642
  shaderLayers: shaderLayersSchema.optional().describe("Shader effects for a 'box' node."),
54282
54643
  updates: nodeUpdatesSchema.optional()
54283
54644
  })),
@@ -54300,9 +54661,15 @@ var init_opaqueActions = __esm({
54300
54661
  name: z52.string().optional().describe("Name for the new component (auto-generated if omitted)")
54301
54662
  })),
54302
54663
  def("deleteComponent", "Delete a component. The component and its node graph are tombstoned, not hard-deleted - they remain recoverable through branch history.", z52.object({ componentId })),
54303
- def("createPage", "Create a new draft page with no nodes. Auto-names 'Page N' (deduped) when name is omitted.", z52.object({
54664
+ def("createPage", "Create a new draft page with no nodes. Auto-names 'Page N' (deduped) when name is omitted. Use createRoute for a page that publishes to a URL.", z52.object({
54304
54665
  name: z52.string().optional().describe("Name for the new page (auto-generated if omitted)")
54305
54666
  })),
54667
+ def("createRoute", "Create a publishable route with one Body node. Returns pageId, bodyNodeId, slug, path, and isIndex. Add content inside bodyNodeId with createNode or applyCanvasEdits. The first root route becomes the homepage automatically. An explicit isIndex claim transfers the homepage from the current route. Use parentPageId to nest routes; slug is one URL segment. Deployment remains a separate action.", z52.object({
54668
+ name: z52.string().trim().min(1).optional().describe("Display name. Defaults to a unique Route N."),
54669
+ slug: z52.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).optional().describe("URL segment, such as signal-noise. Omit to generate a unique slug from the name. Explicit collisions are rejected."),
54670
+ parentPageId: pageId.optional().describe("Existing route in this branch to use as the parent. Omit for a root route."),
54671
+ isIndex: z52.boolean().optional().describe("Set true to make this root route the homepage. The first root route is always the homepage.")
54672
+ })),
54306
54673
  def("moveNode", "Reparent a node within its page or variant. Pass no newParentNodeId to move it to the top level. Cannot move a node between pages or variants, or into its own subtree.", z52.object({
54307
54674
  componentId: componentId.optional(),
54308
54675
  pageId: pageId.optional(),
@@ -55120,7 +55487,7 @@ function getDefaultVariant(component) {
55120
55487
  if (variants.length === 0) {
55121
55488
  return null;
55122
55489
  }
55123
- const groupless = variants.find((v14) => v14 && !v14.variantGroups);
55490
+ const groupless = variants.find((v15) => v15 && !v15.variantGroups);
55124
55491
  return (_a2 = groupless !== null && groupless !== void 0 ? groupless : variants[0]) !== null && _a2 !== void 0 ? _a2 : null;
55125
55492
  }
55126
55493
  function getNodes(parent, variantId2) {
@@ -55135,7 +55502,7 @@ function getNodes(parent, variantId2) {
55135
55502
  return void 0;
55136
55503
  }
55137
55504
  if (variantId2) {
55138
- const variant = variants.find((v14) => v14 && v14.id === variantId2);
55505
+ const variant = variants.find((v15) => v15 && v15.id === variantId2);
55139
55506
  return variant ? nodesOf(variant) : void 0;
55140
55507
  } else {
55141
55508
  const defaultVariant = getDefaultVariant(parent);
@@ -55154,7 +55521,7 @@ function resolveTargetList(parent, variantId2) {
55154
55521
  if (variants.length === 0) {
55155
55522
  return null;
55156
55523
  }
55157
- const variant = variantId2 ? variants.find((v14) => v14 && v14.id === variantId2) : getDefaultVariant(parent);
55524
+ const variant = variantId2 ? variants.find((v15) => v15 && v15.id === variantId2) : getDefaultVariant(parent);
55158
55525
  if (!variant)
55159
55526
  return null;
55160
55527
  return getOpList(variant, "nodes");
@@ -56179,7 +56546,7 @@ function getOverrideBoundVariable(override, variables) {
56179
56546
  var _a2;
56180
56547
  if (!override.variableId || !variables)
56181
56548
  return void 0;
56182
- return (_a2 = variables.find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === override.variableId)) !== null && _a2 !== void 0 ? _a2 : void 0;
56549
+ return (_a2 = variables.find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === override.variableId)) !== null && _a2 !== void 0 ? _a2 : void 0;
56183
56550
  }
56184
56551
  function resolveNumberOrVariable(prop, variables, propOverrides) {
56185
56552
  if (prop === void 0 || prop === null)
@@ -56203,7 +56570,7 @@ function resolveNumberOrVariable(prop, variables, propOverrides) {
56203
56570
  }
56204
56571
  }
56205
56572
  if (variables) {
56206
- const variable = variables.find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === prop.variableId);
56573
+ const variable = variables.find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === prop.variableId);
56207
56574
  if (variable && variable.type === "number") {
56208
56575
  const numberValue = getNumberFromVariable(variable);
56209
56576
  if (numberValue !== void 0) {
@@ -56241,7 +56608,7 @@ function resolveEnumOrVariable(prop, variables, propOverrides) {
56241
56608
  }
56242
56609
  }
56243
56610
  if (variables) {
56244
- const variable = variables.find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === prop.variableId);
56611
+ const variable = variables.find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === prop.variableId);
56245
56612
  if (variable && variable.type === "enum" && variable.enumValue) {
56246
56613
  return variable.enumValue;
56247
56614
  }
@@ -56278,7 +56645,7 @@ function resolveColor2(color2, variables, propOverrides) {
56278
56645
  if (override === null || override === void 0 ? void 0 : override.colorValue) {
56279
56646
  let overrideColor = override.colorValue;
56280
56647
  if (overrideColor.variableId && variables) {
56281
- const innerVar = variables.find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === overrideColor.variableId);
56648
+ const innerVar = variables.find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === overrideColor.variableId);
56282
56649
  if (innerVar && innerVar.type === "color") {
56283
56650
  const innerColor = getColorFromVariable(innerVar);
56284
56651
  if (innerColor)
@@ -56298,7 +56665,7 @@ function resolveColor2(color2, variables, propOverrides) {
56298
56665
  }
56299
56666
  }
56300
56667
  if (variables) {
56301
- const variable = variables.find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === color2.variableId);
56668
+ const variable = variables.find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === color2.variableId);
56302
56669
  if (variable && variable.type === "color") {
56303
56670
  const colorValue = getColorFromVariable(variable);
56304
56671
  if (colorValue) {
@@ -56638,7 +57005,7 @@ var init_chunk_F4W4HJCD = __esm({
56638
57005
  return { l: 116 * f4 - 16, a: 500 * (C2(u3 / Ko) - f4) || 0, b: 200 * (f4 - C2(x6 / Vo)) || 0, alpha: s(s5, 3), colorSpace: "lab" };
56639
57006
  };
56640
57007
  Dn = (n5, o3) => {
56641
- let { l: t3, a: s5, b: r } = n5, { l, a: a5, b: u3 } = o3, e2 = Math.PI / 180, x6 = 180 / Math.PI, f4 = Math.sqrt(s5 ** 2 + r ** 2), wo = Math.sqrt(a5 ** 2 + u3 ** 2), v14 = ((f4 + wo) / 2) ** 7, V3 = 0.5 * (1 - Math.sqrt(v14 / (v14 + 25 ** 7))), Y3 = s5 * (1 + V3), Z4 = a5 * (1 + V3), k = Math.sqrt(Y3 ** 2 + r ** 2), $5 = Math.sqrt(Z4 ** 2 + u3 ** 2), N6 = (k + $5) / 2, W4 = Y3 === 0 && r === 0 ? 0 : Math.atan2(r, Y3) * x6, E = Z4 === 0 && u3 === 0 ? 0 : Math.atan2(u3, Z4) * x6, i3 = W4 < 0 ? W4 + 360 : W4, X4 = E < 0 ? E + 360 : E, q2 = X4 - i3, j3 = Math.abs(X4 - i3);
57008
+ let { l: t3, a: s5, b: r } = n5, { l, a: a5, b: u3 } = o3, e2 = Math.PI / 180, x6 = 180 / Math.PI, f4 = Math.sqrt(s5 ** 2 + r ** 2), wo = Math.sqrt(a5 ** 2 + u3 ** 2), v15 = ((f4 + wo) / 2) ** 7, V3 = 0.5 * (1 - Math.sqrt(v15 / (v15 + 25 ** 7))), Y3 = s5 * (1 + V3), Z4 = a5 * (1 + V3), k = Math.sqrt(Y3 ** 2 + r ** 2), $5 = Math.sqrt(Z4 ** 2 + u3 ** 2), N6 = (k + $5) / 2, W4 = Y3 === 0 && r === 0 ? 0 : Math.atan2(r, Y3) * x6, E = Z4 === 0 && u3 === 0 ? 0 : Math.atan2(u3, Z4) * x6, i3 = W4 < 0 ? W4 + 360 : W4, X4 = E < 0 ? E + 360 : E, q2 = X4 - i3, j3 = Math.abs(X4 - i3);
56642
57009
  j3 > 180 && X4 <= i3 ? q2 += 360 : j3 > 180 && X4 > i3 && (q2 -= 360);
56643
57010
  let J4 = (t3 + l) / 2, D2 = i3 + X4;
56644
57011
  j3 <= 180 ? D2 /= 2 : D2 = (i3 + X4 < 360 ? D2 + 360 : D2 - 360) / 2;
@@ -57353,7 +57720,7 @@ var init_a11y = __esm({
57353
57720
  });
57354
57721
 
57355
57722
  // ../../node_modules/.pnpm/@colordx+core@5.4.3/node_modules/@colordx/core/dist/plugins/p3.mjs
57356
- var $4, I3, v13, K2;
57723
+ var $4, I3, v14, K2;
57357
57724
  var init_p3 = __esm({
57358
57725
  "../../node_modules/.pnpm/@colordx+core@5.4.3/node_modules/@colordx/core/dist/plugins/p3.mjs"() {
57359
57726
  "use strict";
@@ -57362,7 +57729,7 @@ var init_p3 = __esm({
57362
57729
  init_chunk_IOXRZECH();
57363
57730
  $4 = (r, o3, e2) => cn(...z55(r, o3, e2));
57364
57731
  I3 = Math.PI / 180;
57365
- v13 = (r$1, o3, e$1) => {
57732
+ v14 = (r$1, o3, e$1) => {
57366
57733
  r$1.toGamutP3 = (n5) => {
57367
57734
  let t3 = jn(n5, xn2, $4);
57368
57735
  if (t3 === null) return new r$1(n5);
@@ -57376,7 +57743,7 @@ var init_p3 = __esm({
57376
57743
  return u3 < 1 ? `color(display-p3 ${t3} ${m4} ${a5} / ${u3})` : `color(display-p3 ${t3} ${m4} ${a5})`;
57377
57744
  }, o3.push(Sn, yn), e$1.push([Sn, "p3"], [yn, "p3"]);
57378
57745
  };
57379
- K2 = v13;
57746
+ K2 = v14;
57380
57747
  }
57381
57748
  });
57382
57749
 
@@ -57787,14 +58154,82 @@ var init_deployed_naming = __esm({
57787
58154
  });
57788
58155
 
57789
58156
  // ../shared/dist/utils/route-helpers.js
58157
+ function isReservedSlug(slug) {
58158
+ return RESERVED_SLUGS.includes(slug.toLowerCase());
58159
+ }
58160
+ function generateSlug(name) {
58161
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "page";
58162
+ }
58163
+ function getRouteFullPath(page, allPages) {
58164
+ if (page.isIndex && !page.parentPageId) {
58165
+ return "/";
58166
+ }
58167
+ const slugs = [];
58168
+ let currentPage = page;
58169
+ while (currentPage) {
58170
+ const isRootIndex = currentPage.isIndex && !currentPage.parentPageId;
58171
+ if (!isRootIndex) {
58172
+ const slug = currentPage.slug || generateSlug(currentPage.name || "page");
58173
+ slugs.unshift(slug);
58174
+ }
58175
+ if (currentPage.parentPageId) {
58176
+ currentPage = allPages.find((p4) => p4 && p4.id === currentPage.parentPageId);
58177
+ } else {
58178
+ currentPage = void 0;
58179
+ }
58180
+ }
58181
+ if (slugs.length === 0) {
58182
+ return "/";
58183
+ }
58184
+ if (slugs.length === 1 && slugs[0] === "index") {
58185
+ return "/";
58186
+ }
58187
+ return "/" + slugs.join("/");
58188
+ }
58189
+ function isSlugUnique(slug, parentId, pageId2, allPages) {
58190
+ const siblings = allPages.filter((p4) => p4 && p4.type === "route" && p4.parentPageId === parentId && p4.id !== pageId2);
58191
+ return !siblings.some((p4) => (p4.slug || generateSlug(p4.name || "")) === slug);
58192
+ }
58193
+ function generateUniqueSlug(name, parentId, pageId2, allPages) {
58194
+ let slug = generateSlug(name);
58195
+ let counter = 1;
58196
+ while (!isSlugUnique(slug, parentId, pageId2, allPages)) {
58197
+ slug = `${generateSlug(name)}-${counter}`;
58198
+ counter++;
58199
+ }
58200
+ return slug;
58201
+ }
58202
+ function getNextSortOrder(parentId, allPages) {
58203
+ const siblings = allPages.filter((p4) => p4 && p4.type === "route" && p4.parentPageId === parentId);
58204
+ if (siblings.length === 0) {
58205
+ return 0;
58206
+ }
58207
+ const maxOrder = Math.max(...siblings.map((p4) => p4.sortOrder || 0));
58208
+ return maxOrder + 1;
58209
+ }
58210
+ function shouldNewRouteBeIndex(allPages, route = {}) {
58211
+ if (route.parentPageId)
58212
+ return false;
58213
+ if (route.requestedIndex)
58214
+ return true;
58215
+ return !allPages.some((page) => page.type === "route" && page.isIndex && !page.parentPageId);
58216
+ }
57790
58217
  function indexRouteDeleteError(page) {
57791
58218
  return page.type === "route" && page.isIndex && !page.parentPageId ? INDEX_ROUTE_DELETE_MESSAGE : void 0;
57792
58219
  }
57793
- var INDEX_ROUTE_DELETE_MESSAGE, ROUTE_GUARD_REJECTION_CODE, ROUTE_GUARD_REJECTION_CODES;
58220
+ function clearOtherIndexPages(pageIdToKeep, allPages) {
58221
+ for (const page of allPages) {
58222
+ if (page && page.isIndex && page.id !== pageIdToKeep) {
58223
+ Page.update(page.id, { isIndex: false });
58224
+ }
58225
+ }
58226
+ }
58227
+ var RESERVED_SLUGS, INDEX_ROUTE_DELETE_MESSAGE, ROUTE_GUARD_REJECTION_CODE, ROUTE_GUARD_REJECTION_CODES;
57794
58228
  var init_route_helpers = __esm({
57795
58229
  "../shared/dist/utils/route-helpers.js"() {
57796
58230
  "use strict";
57797
58231
  init_page();
58232
+ RESERVED_SLUGS = ["_assets", "_worker"];
57798
58233
  INDEX_ROUTE_DELETE_MESSAGE = "You can't delete the index route. Set another route as the index first.";
57799
58234
  ROUTE_GUARD_REJECTION_CODE = {
57800
58235
  duplicateIndexRoute: "DUPLICATE_INDEX_ROUTE",
@@ -65753,7 +66188,8 @@ function uniqueProjectSlug(base, existingSlugs) {
65753
66188
  return `${base}-${counter}`;
65754
66189
  }
65755
66190
  function generateUniqueProjectSlug(name, existingSlugs) {
65756
- return uniqueProjectSlug(generateProjectSlug(name), existingSlugs);
66191
+ const suffix = crypto.randomUUID().replaceAll("-", "").slice(0, 12);
66192
+ return uniqueProjectSlug(`${generateProjectSlug(name)}-${suffix}`, existingSlugs);
65757
66193
  }
65758
66194
  var init_project_slug = __esm({
65759
66195
  "../shared/dist/utils/project-slug.js"() {
@@ -65805,7 +66241,7 @@ function createProjectRealms(projectId, organizationAdminsGroupId) {
65805
66241
  });
65806
66242
  return { realmsGroupId, realmIds };
65807
66243
  }
65808
- function createProjectInOrganization(organization, projectName, creator, { sharingMode = SharingModeTypes.Organization, orgAccessLevel = AccessLevelTypes.Collaborator, existingProjectSlugs = [], seedIndexRoute = false, seedBrandAndManifesto = false, onActionDispatched } = {}) {
66244
+ function createProjectInOrganization(organization, projectName, creator, { sharingMode = SharingModeTypes.Organization, orgAccessLevel = AccessLevelTypes.Collaborator, existingProjectSlugs = [], seedIndexRoute = false, seedInitialContent = true, seedBrandAndManifesto = false, initialBrief, onActionDispatched } = {}) {
65809
66245
  var _a2;
65810
66246
  let orgForGroups = organization;
65811
66247
  const needsMembers = sharingMode === SharingModeTypes.Organization;
@@ -65849,6 +66285,7 @@ function createProjectInOrganization(organization, projectName, creator, { shari
65849
66285
  mainBranchId: mainBranch.id,
65850
66286
  currentBranch: ref(mainBranch)
65851
66287
  });
66288
+ project = Object.assign(Object.assign({}, project), { mainBranchId: mainBranch.id, currentBranch: ref(mainBranch) });
65852
66289
  });
65853
66290
  if (createEvents[0])
65854
66291
  onActionDispatched === null || onActionDispatched === void 0 ? void 0 : onActionDispatched(createEvents[0].actionId);
@@ -65861,6 +66298,8 @@ function createProjectInOrganization(organization, projectName, creator, { shari
65861
66298
  branchId: mainBranch.id
65862
66299
  }
65863
66300
  };
66301
+ if (!seedInitialContent)
66302
+ return project;
65864
66303
  const seedEvents = batch(Object.assign(Object.assign({}, seedBatchOptions), {
65865
66304
  // The label names what the action actually carries, so this class of
65866
66305
  // regression stays visible in the event log.
@@ -65885,7 +66324,18 @@ function createProjectInOrganization(organization, projectName, creator, { shari
65885
66324
  if (seedBrandAndManifesto) {
65886
66325
  const seededBrand = Brand.create({});
65887
66326
  Branch2.update(mainBranch.id, { brand: ref(seededBrand) });
65888
- const seededManifesto = Manifesto.create({});
66327
+ const seededManifesto = Manifesto.create(initialBrief ? {
66328
+ purpose: ManifestoPurpose.create({
66329
+ oneLiner: initialBrief,
66330
+ provenance: ManifestoProvenance.create({
66331
+ basis: ManifestoBasisTypes.User,
66332
+ confidence: ManifestoConfidenceTypes.High,
66333
+ source: "user",
66334
+ stampedAt: /* @__PURE__ */ new Date()
66335
+ })
66336
+ }),
66337
+ status: ManifestoStatusTypes.Draft
66338
+ } : {});
65889
66339
  Branch2.update(mainBranch.id, { manifesto: ref(seededManifesto) });
65890
66340
  }
65891
66341
  });
@@ -66000,6 +66450,13 @@ var init_founding_card = __esm({
66000
66450
  }
66001
66451
  });
66002
66452
 
66453
+ // ../shared/dist/utils/brand-logo-trace.js
66454
+ var init_brand_logo_trace = __esm({
66455
+ "../shared/dist/utils/brand-logo-trace.js"() {
66456
+ "use strict";
66457
+ }
66458
+ });
66459
+
66003
66460
  // ../shared/dist/utils/code-file-text.js
66004
66461
  function normalizeCodeFileText(text) {
66005
66462
  const lf = normalizeEol(text);
@@ -67341,7 +67798,7 @@ var init_pr2 = __esm({
67341
67798
  // ../shared/dist/utils/variant-helpers.js
67342
67799
  function getValueName(group, valueId) {
67343
67800
  var _a2, _b;
67344
- return (_b = (_a2 = group.validValues) === null || _a2 === void 0 ? void 0 : _a2.find((v14) => v14.id === valueId)) === null || _b === void 0 ? void 0 : _b.name;
67801
+ return (_b = (_a2 = group.validValues) === null || _a2 === void 0 ? void 0 : _a2.find((v15) => v15.id === valueId)) === null || _b === void 0 ? void 0 : _b.name;
67345
67802
  }
67346
67803
  var init_variant_helpers = __esm({
67347
67804
  "../shared/dist/utils/variant-helpers.js"() {
@@ -87174,6 +87631,7 @@ var init_dist4 = __esm({
87174
87631
  init_id_generation();
87175
87632
  init_vectorNetwork2();
87176
87633
  init_founding_card();
87634
+ init_brand_logo_trace();
87177
87635
  init_code_file_text();
87178
87636
  init_code_file_batches();
87179
87637
  init_app_schema();
@@ -89257,7 +89715,7 @@ var CLI_VERSION;
89257
89715
  var init_version = __esm({
89258
89716
  "src/config/version.ts"() {
89259
89717
  "use strict";
89260
- CLI_VERSION = true ? "0.1.4" : "0.0.0-dev";
89718
+ CLI_VERSION = true ? "0.1.5" : "0.0.0-dev";
89261
89719
  }
89262
89720
  });
89263
89721
 
@@ -89391,8 +89849,8 @@ function distanceQuintic(p4, p0, p1, p22, p32) {
89391
89849
  function bernsteinRoots(w5, lo2, hi, out, depth) {
89392
89850
  let sign = 0;
89393
89851
  let crossings = 0;
89394
- for (const v14 of w5) {
89395
- const s5 = v14 > 1e-14 ? 1 : v14 < -1e-14 ? -1 : 0;
89852
+ for (const v15 of w5) {
89853
+ const s5 = v15 > 1e-14 ? 1 : v15 < -1e-14 ? -1 : 0;
89396
89854
  if (s5 !== 0) {
89397
89855
  if (sign !== 0 && s5 !== sign)
89398
89856
  crossings++;
@@ -89420,8 +89878,8 @@ function bernsteinRoots(w5, lo2, hi, out, depth) {
89420
89878
  const right = tri.map((row) => row[row.length - 1]).reverse();
89421
89879
  const mid = (lo2 + hi) / 2;
89422
89880
  let scale = 0;
89423
- for (const v14 of w5)
89424
- scale = Math.max(scale, Math.abs(v14));
89881
+ for (const v15 of w5)
89882
+ scale = Math.max(scale, Math.abs(v15));
89425
89883
  if (Math.abs(tri[n5 - 1][0]) <= 1e-12 * (1 + scale))
89426
89884
  out.push(mid);
89427
89885
  bernsteinRoots(left, lo2, mid, out, depth + 1);
@@ -89766,8 +90224,8 @@ var clamp, clamp01;
89766
90224
  var init_num = __esm({
89767
90225
  "../vector-engine/dist/vector/math/num.js"() {
89768
90226
  "use strict";
89769
- clamp = (v14, min, max) => v14 < min ? min : v14 > max ? max : v14;
89770
- clamp01 = (v14) => v14 < 0 ? 0 : v14 > 1 ? 1 : v14;
90227
+ clamp = (v15, min, max) => v15 < min ? min : v15 > max ? max : v15;
90228
+ clamp01 = (v15) => v15 < 0 ? 0 : v15 > 1 ? 1 : v15;
89771
90229
  }
89772
90230
  });
89773
90231
 
@@ -89914,8 +90372,8 @@ var init_linalg = __esm({
89914
90372
  // ../vector-engine/dist/vector/solver/math/cg.js
89915
90373
  function schurCG(rows, winv, n5, rhs) {
89916
90374
  const m4 = rows.length;
89917
- const apply = (v14, out) => {
89918
- const t3 = applyT(v14);
90375
+ const apply = (v15, out) => {
90376
+ const t3 = applyT(v15);
89919
90377
  for (let i3 = 0; i3 < m4; i3++) {
89920
90378
  const r3 = rows[i3];
89921
90379
  let s5 = 0;
@@ -89925,11 +90383,11 @@ function schurCG(rows, winv, n5, rhs) {
89925
90383
  }
89926
90384
  };
89927
90385
  const scratch = new Array(n5);
89928
- const applyT = (v14) => {
90386
+ const applyT = (v15) => {
89929
90387
  scratch.fill(0);
89930
90388
  for (let i3 = 0; i3 < m4; i3++) {
89931
90389
  const r3 = rows[i3];
89932
- const vi = v14[i3];
90390
+ const vi = v15[i3];
89933
90391
  if (vi === 0)
89934
90392
  continue;
89935
90393
  for (let k = 0; k < r3.cols.length; k++)
@@ -90224,22 +90682,22 @@ function galloc() {
90224
90682
  function resetPool() {
90225
90683
  poolIdx = 0;
90226
90684
  }
90227
- function dvar(v14, col) {
90685
+ function dvar(v15, col) {
90228
90686
  if (valuesOnly)
90229
- return { v: v14, g: EMPTY_GRAD };
90687
+ return { v: v15, g: EMPTY_GRAD };
90230
90688
  const g2 = galloc();
90231
90689
  g2.cols[0] = col;
90232
90690
  g2.vals[0] = 1;
90233
90691
  g2.n = 1;
90234
- return { v: v14, g: g2 };
90692
+ return { v: v15, g: g2 };
90235
90693
  }
90236
- function chain(v14, ka, a5, kb, b4) {
90694
+ function chain(v15, ka, a5, kb, b4) {
90237
90695
  if (valuesOnly)
90238
- return { v: v14, g: EMPTY_GRAD };
90696
+ return { v: v15, g: EMPTY_GRAD };
90239
90697
  const ag = a5.g;
90240
90698
  const bg = b4.g;
90241
90699
  if (bg.n === 0 && ag.n === 0)
90242
- return { v: v14, g: EMPTY_GRAD };
90700
+ return { v: v15, g: EMPTY_GRAD };
90243
90701
  const g2 = galloc();
90244
90702
  let i3 = 0;
90245
90703
  let j3 = 0;
@@ -90260,7 +90718,7 @@ function chain(v14, ka, a5, kb, b4) {
90260
90718
  n5++;
90261
90719
  }
90262
90720
  g2.n = n5;
90263
- return { v: v14, g: g2 };
90721
+ return { v: v15, g: g2 };
90264
90722
  }
90265
90723
  function div(a5, b4) {
90266
90724
  const bv = b4.v || 1;
@@ -90851,10 +91309,10 @@ function curvatureRows(sa, sb, atIn, ctx) {
90851
91309
  if (cubicSide && (sa.kind === "line" || sb.kind === "line")) {
90852
91310
  const fromA = at === cubicSide.a;
90853
91311
  const u3 = vsub(P4(fromA ? cubicSide.h1 : cubicSide.h2), P4(at));
90854
- const v14 = vsub(P4(fromA ? cubicSide.h2 : cubicSide.h1), P4(fromA ? cubicSide.h1 : cubicSide.h2));
91312
+ const v15 = vsub(P4(fromA ? cubicSide.h2 : cubicSide.h1), P4(fromA ? cubicSide.h1 : cubicSide.h2));
90855
91313
  return [
90856
91314
  ...tangentRows(sa, sb, atIn, ctx),
90857
- asRow(scl(1 / L3, div(cross(u3, v14), vlen(u3))))
91315
+ asRow(scl(1 / L3, div(cross(u3, v15), vlen(u3))))
90858
91316
  ];
90859
91317
  }
90860
91318
  return [
@@ -90876,7 +91334,7 @@ var init_residuals = __esm({
90876
91334
  pool = [];
90877
91335
  poolIdx = 0;
90878
91336
  valuesOnly = false;
90879
- dc = (v14) => ({ v: v14, g: EMPTY_GRAD });
91337
+ dc = (v15) => ({ v: v15, g: EMPTY_GRAD });
90880
91338
  lin = (ka, a5, kb, b4) => chain(ka * a5.v + kb * b4.v, ka, a5, kb, b4);
90881
91339
  add = (a5, b4) => lin(1, a5, 1, b4);
90882
91340
  sub = (a5, b4) => lin(1, a5, -1, b4);
@@ -91124,28 +91582,28 @@ function rankFilter(J4, c3, rel) {
91124
91582
  for (let r = 0; r < J4.length; r++) {
91125
91583
  const row = J4[r];
91126
91584
  let rowNorm = 0;
91127
- for (const v15 of row)
91128
- rowNorm += v15 * v15;
91585
+ for (const v16 of row)
91586
+ rowNorm += v16 * v16;
91129
91587
  rowNorm = Math.sqrt(rowNorm);
91130
91588
  if (rowNorm === 0)
91131
91589
  continue;
91132
- const v14 = row.slice();
91590
+ const v15 = row.slice();
91133
91591
  for (const b4 of basis) {
91134
91592
  let d4 = 0;
91135
- for (let i3 = 0; i3 < v14.length; i3++)
91136
- d4 += v14[i3] * b4[i3];
91137
- for (let i3 = 0; i3 < v14.length; i3++)
91138
- v14[i3] -= d4 * b4[i3];
91593
+ for (let i3 = 0; i3 < v15.length; i3++)
91594
+ d4 += v15[i3] * b4[i3];
91595
+ for (let i3 = 0; i3 < v15.length; i3++)
91596
+ v15[i3] -= d4 * b4[i3];
91139
91597
  }
91140
91598
  let pn2 = 0;
91141
- for (const e2 of v14)
91599
+ for (const e2 of v15)
91142
91600
  pn2 += e2 * e2;
91143
91601
  pn2 = Math.sqrt(pn2);
91144
91602
  if (pn2 <= rel * rowNorm)
91145
91603
  continue;
91146
- for (let i3 = 0; i3 < v14.length; i3++)
91147
- v14[i3] /= pn2;
91148
- basis.push(v14);
91604
+ for (let i3 = 0; i3 < v15.length; i3++)
91605
+ v15[i3] /= pn2;
91606
+ basis.push(v15);
91149
91607
  keptJ.push(row);
91150
91608
  keptC.push(c3[r]);
91151
91609
  kept.push(r);
@@ -91174,7 +91632,7 @@ function gram(J4, winv) {
91174
91632
  }
91175
91633
  function kktStep(rows, g2, n5, winv, rungFloor = 0, cg) {
91176
91634
  const free = rows.filter((r) => r.cols.length > 0);
91177
- const delta = g2.map((v14) => -v14);
91635
+ const delta = g2.map((v15) => -v15);
91178
91636
  if (free.length === 0)
91179
91637
  return delta;
91180
91638
  if (free.length >= CG_MIN_ROWS && rungFloor === 0 && !cg?.futile) {
@@ -91450,11 +91908,11 @@ function gramSpectrum(rows, withVectors) {
91450
91908
  if (rows.length === 0)
91451
91909
  return { rank: 0, values: [], vectors: [] };
91452
91910
  const { values, vectors } = jacobiEigen(gramMatrix(rows), withVectors);
91453
- const lmax = values.reduce((mx, v14) => Math.max(mx, v14), 0);
91911
+ const lmax = values.reduce((mx, v15) => Math.max(mx, v15), 0);
91454
91912
  const tol = GRAM_EIG_TOL * (lmax || 1);
91455
91913
  let rank = 0;
91456
- for (const v14 of values)
91457
- if (v14 > tol)
91914
+ for (const v15 of values)
91915
+ if (v15 > tol)
91458
91916
  rank++;
91459
91917
  return { rank, values, vectors };
91460
91918
  }
@@ -91546,10 +92004,10 @@ function solve(graph, constraints, trace) {
91546
92004
  const sub3 = subsystem(graph, cons, touched);
91547
92005
  const vm = buildVarMap(sub3.graph, [], new Set(Object.keys(sub3.graph.points)));
91548
92006
  for (const row of evalResidualValues(sub3.graph, sub3.constraints, [], vm)) {
91549
- const v14 = Math.abs(row.value);
91550
- if (v14 > cmax)
91551
- cmax = v14;
91552
- if (v14 >= EPS)
92007
+ const v15 = Math.abs(row.value);
92008
+ if (v15 > cmax)
92009
+ cmax = v15;
92010
+ if (v15 >= EPS)
91553
92011
  converged = false;
91554
92012
  }
91555
92013
  }
@@ -92166,7 +92624,7 @@ function bernProd3(f4, g2) {
92166
92624
  function cubicCircleTs(p4, c3, r) {
92167
92625
  const dx = p4.map((pt) => pt.x - c3.x);
92168
92626
  const dy = p4.map((pt) => pt.y - c3.y);
92169
- const w5 = bernProd3(dx, dx).map((v14, k) => v14 + bernProd3(dy, dy)[k] - r * r);
92627
+ const w5 = bernProd3(dx, dx).map((v15, k) => v15 + bernProd3(dy, dy)[k] - r * r);
92170
92628
  const raw = [];
92171
92629
  bernsteinRoots(w5, 0, 1, raw, 0);
92172
92630
  const xs = p4.map((q2) => q2.x);
@@ -92186,7 +92644,7 @@ function cubicCubicTs(pa, pb) {
92186
92644
  x1: Math.max(p4[0].x, p4[1].x, p4[2].x, p4[3].x),
92187
92645
  y1: Math.max(p4[0].y, p4[1].y, p4[2].y, p4[3].y)
92188
92646
  });
92189
- const overlaps = (u3, v14) => u3.x0 <= v14.x1 + HULL_PAD && v14.x0 <= u3.x1 + HULL_PAD && u3.y0 <= v14.y1 + HULL_PAD && v14.y0 <= u3.y1 + HULL_PAD;
92647
+ const overlaps = (u3, v15) => u3.x0 <= v15.x1 + HULL_PAD && v15.x0 <= u3.x1 + HULL_PAD && u3.y0 <= v15.y1 + HULL_PAD && v15.y0 <= u3.y1 + HULL_PAD;
92190
92648
  const stack = [{ a0: 0, a1: 1, ca: pa, b0: 0, b1: 1, cb: pb }];
92191
92649
  const seeds = [];
92192
92650
  let budget = 2e4;
@@ -92781,7 +93239,7 @@ function buildPlanar(graph, chains) {
92781
93239
  const ids = [...geoms.keys()];
92782
93240
  const nodes = [];
92783
93241
  const cells = /* @__PURE__ */ new Map();
92784
- const cellOf = (v14) => Math.floor(v14 / WELD_EPS);
93242
+ const cellOf = (v15) => Math.floor(v15 / WELD_EPS);
92785
93243
  const weld = (p4) => {
92786
93244
  const cx = cellOf(p4.x);
92787
93245
  const cy = cellOf(p4.y);
@@ -93520,10 +93978,10 @@ function faceCentroidOf(face, geoms) {
93520
93978
  const t3 = (t0 + t1) / 2 + (t1 - t0) / 2 * G8_N[i3];
93521
93979
  const w5 = G8_W[i3] * (t1 - t0) / 2;
93522
93980
  const p4 = geomPointAt(geom, t3);
93523
- const v14 = geomVelocityAt(geom, t3);
93524
- a5 += w5 * (p4.x * v14.y - p4.y * v14.x) / 2;
93525
- cx += w5 * p4.x * p4.x * v14.y / 2;
93526
- cy -= w5 * p4.y * p4.y * v14.x / 2;
93981
+ const v15 = geomVelocityAt(geom, t3);
93982
+ a5 += w5 * (p4.x * v15.y - p4.y * v15.x) / 2;
93983
+ cx += w5 * p4.x * p4.x * v15.y / 2;
93984
+ cy -= w5 * p4.y * p4.y * v15.x / 2;
93527
93985
  }
93528
93986
  }
93529
93987
  }
@@ -94027,8 +94485,8 @@ function isIdentity(m4) {
94027
94485
  function applyAffine(m4, p4) {
94028
94486
  return { x: m4.a * p4.x + m4.c * p4.y + m4.e, y: m4.b * p4.x + m4.d * p4.y + m4.f };
94029
94487
  }
94030
- function applyLinear(m4, v14) {
94031
- return { x: m4.a * v14.x + m4.c * v14.y, y: m4.b * v14.x + m4.d * v14.y };
94488
+ function applyLinear(m4, v15) {
94489
+ return { x: m4.a * v15.x + m4.c * v15.y, y: m4.b * v15.x + m4.d * v15.y };
94032
94490
  }
94033
94491
  function rotation(rad) {
94034
94492
  const cos = Math.cos(rad);
@@ -94419,7 +94877,7 @@ function resolveScope(path4, node) {
94419
94877
  if (!src || src.kind !== "path")
94420
94878
  continue;
94421
94879
  const srcFrame = pathFrame(src);
94422
- const map = (v14) => reframe(v14, srcFrame, dest);
94880
+ const map = (v15) => reframe(v15, srcFrame, dest);
94423
94881
  const addPoint = (pid) => {
94424
94882
  const p4 = src.graph.points[pid];
94425
94883
  if (!p4)
@@ -94665,7 +95123,7 @@ function readViewBox(attrSource) {
94665
95123
  if (!box)
94666
95124
  return null;
94667
95125
  const n5 = (box[1] ?? box[2] ?? "").trim().split(/[\s,]+/).map(Number);
94668
- if (n5.length !== 4 || !n5.every((v14) => Number.isFinite(v14)) || n5[2] <= 0 || n5[3] <= 0)
95126
+ if (n5.length !== 4 || !n5.every((v15) => Number.isFinite(v15)) || n5[2] <= 0 || n5[3] <= 0)
94669
95127
  return null;
94670
95128
  return { x: n5[0], y: n5[1], width: n5[2], height: n5[3] };
94671
95129
  }
@@ -94679,8 +95137,8 @@ function svgFrame(text) {
94679
95137
  return box;
94680
95138
  const dim2 = (name) => {
94681
95139
  const m4 = new RegExp(`\\b${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`, "i").exec(attrs);
94682
- const v14 = m4 ? parseFloat((m4[1] ?? m4[2] ?? "").trim()) : NaN;
94683
- return Number.isFinite(v14) && v14 > 0 ? v14 : null;
95140
+ const v15 = m4 ? parseFloat((m4[1] ?? m4[2] ?? "").trim()) : NaN;
95141
+ return Number.isFinite(v15) && v15 > 0 ? v15 : null;
94684
95142
  };
94685
95143
  const w5 = dim2("width");
94686
95144
  const h4 = dim2("height");
@@ -94730,7 +95188,7 @@ function parseTransform(source) {
94730
95188
  read = re.lastIndex;
94731
95189
  const body = t3[2].trim();
94732
95190
  const n5 = body === "" ? [] : body.split(/[\s,]+/).map(Number);
94733
- if (n5.some((v14) => !Number.isFinite(v14)))
95191
+ if (n5.some((v15) => !Number.isFinite(v15)))
94734
95192
  return null;
94735
95193
  const step = transformStep(t3[1], n5);
94736
95194
  if (!step)
@@ -94751,7 +95209,7 @@ function len2(raw, fallback = 0) {
94751
95209
  function points(raw) {
94752
95210
  if (!raw)
94753
95211
  return [];
94754
- const n5 = raw.trim().split(/[\s,]+/).map(Number).filter((v14) => Number.isFinite(v14));
95212
+ const n5 = raw.trim().split(/[\s,]+/).map(Number).filter((v15) => Number.isFinite(v15));
94755
95213
  return n5.length % 2 === 0 ? n5 : n5.slice(0, -1);
94756
95214
  }
94757
95215
  function shapeElementPathData(name, attrs) {
@@ -94847,12 +95305,12 @@ function inheritPaint(parent, own) {
94847
95305
  }
94848
95306
  }
94849
95307
  for (const key of INHERITED_PAINT) {
94850
- const v14 = own[key];
94851
- if (v14 === void 0)
95308
+ const v15 = own[key];
95309
+ if (v15 === void 0)
94852
95310
  continue;
94853
- if (v14.trim().toLowerCase() === "inherit")
95311
+ if (v15.trim().toLowerCase() === "inherit")
94854
95312
  continue;
94855
- out[key] = v14;
95313
+ out[key] = v15;
94856
95314
  }
94857
95315
  return out;
94858
95316
  }
@@ -96145,7 +96603,7 @@ function polygonVertices(raw) {
96145
96603
  if (!raw)
96146
96604
  return null;
96147
96605
  const n5 = raw.trim().split(/[\s,]+/).map(Number);
96148
- if (n5.some((v14) => !Number.isFinite(v14)))
96606
+ if (n5.some((v15) => !Number.isFinite(v15)))
96149
96607
  return null;
96150
96608
  if (n5.length < 6 || n5.length % 2 !== 0)
96151
96609
  return null;
@@ -96311,9 +96769,9 @@ function parseSvgGradient(markup, resolve6) {
96311
96769
  let dy = at("y2", 0) - at("y1", 0);
96312
96770
  const t3 = parseTransform(attr("gradientTransform") ?? "");
96313
96771
  if (t3) {
96314
- const v14 = applyLinear(t3, { x: dx, y: dy });
96315
- dx = v14.x;
96316
- dy = v14.y;
96772
+ const v15 = applyLinear(t3, { x: dx, y: dy });
96773
+ dx = v15.x;
96774
+ dy = v15.y;
96317
96775
  }
96318
96776
  const angle = dx === 0 && dy === 0 ? void 0 : angleOf(dx, dy);
96319
96777
  return { type: "linear", stops, repeating, angle };
@@ -96374,11 +96832,11 @@ function fitCircle(pts) {
96374
96832
  if (Math.abs(d4) < 1e-12)
96375
96833
  return null;
96376
96834
  const rhs = [sxz, syz, sz];
96377
- const col = (i3) => m4.map((row, k) => row.map((v15, j3) => j3 === i3 ? rhs[k] : v15));
96835
+ const col = (i3) => m4.map((row, k) => row.map((v16, j3) => j3 === i3 ? rhs[k] : v16));
96378
96836
  const u3 = det(col(0)) / d4;
96379
- const v14 = det(col(1)) / d4;
96837
+ const v15 = det(col(1)) / d4;
96380
96838
  const w5 = det(col(2)) / d4;
96381
- const center = { x: u3 / 2, y: v14 / 2 };
96839
+ const center = { x: u3 / 2, y: v15 / 2 };
96382
96840
  const rsq = w5 + center.x * center.x + center.y * center.y;
96383
96841
  if (!(rsq > 0) || !Number.isFinite(rsq))
96384
96842
  return null;
@@ -96503,7 +96961,7 @@ function inferConstraints(graph, opts = {}) {
96503
96961
  own.add(pair(mine[i3], mine[j3]));
96504
96962
  }
96505
96963
  const places = Object.keys(graph.points).filter((id) => !skip.has(id));
96506
- const cell = (v14) => Math.round(v14 / quantum);
96964
+ const cell = (v15) => Math.round(v15 / quantum);
96507
96965
  const grid = /* @__PURE__ */ new Map();
96508
96966
  for (const id of places) {
96509
96967
  const p4 = graph.points[id];
@@ -96992,7 +97450,7 @@ function collapseRuns(points2, segments, chains, retired, welded, tol) {
96992
97450
  return s5 && (s5.kind === "line" || s5.kind === "arc") ? s5 : null;
96993
97451
  };
96994
97452
  const graph = { points: points2, segments };
96995
- const away = (s5, v14) => edgeTangentAt(graph, s5, v14);
97453
+ const away = (s5, v15) => edgeTangentAt(graph, s5, v15);
96996
97454
  const atVertex = /* @__PURE__ */ new Map();
96997
97455
  for (const s5 of Object.values(segments)) {
96998
97456
  if (s5.kind === "cubic")
@@ -97053,9 +97511,9 @@ function collapseRuns(points2, segments, chains, retired, welded, tol) {
97053
97511
  const ends = [];
97054
97512
  for (const side of ["a", "b"]) {
97055
97513
  let cur = start;
97056
- let v14 = cur[side];
97514
+ let v15 = cur[side];
97057
97515
  for (; ; ) {
97058
- const nxt = partner.get(cur.id)?.get(v14);
97516
+ const nxt = partner.get(cur.id)?.get(v15);
97059
97517
  const ns = nxt ? joinable(nxt) : null;
97060
97518
  if (!ns || done.has(ns.id))
97061
97519
  break;
@@ -97064,10 +97522,10 @@ function collapseRuns(points2, segments, chains, retired, welded, tol) {
97064
97522
  seq.unshift(ns.id);
97065
97523
  else
97066
97524
  seq.push(ns.id);
97067
- v14 = ns.a === v14 ? ns.b : ns.a;
97525
+ v15 = ns.a === v15 ? ns.b : ns.a;
97068
97526
  cur = ns;
97069
97527
  }
97070
- ends.push(v14);
97528
+ ends.push(v15);
97071
97529
  }
97072
97530
  if (seq.length < 2)
97073
97531
  continue;
@@ -98464,14 +98922,14 @@ var init_dist5 = __esm({
98464
98922
  function checkJsonSafe(value, rootPath = "value") {
98465
98923
  const violations2 = [];
98466
98924
  const seen = /* @__PURE__ */ new WeakSet();
98467
- const walk = (v14, path4) => {
98925
+ const walk = (v15, path4) => {
98468
98926
  var _a2;
98469
- if (v14 === null || v14 === void 0)
98927
+ if (v15 === null || v15 === void 0)
98470
98928
  return;
98471
- const t3 = typeof v14;
98929
+ const t3 = typeof v15;
98472
98930
  if (t3 === "number") {
98473
- if (!Number.isFinite(v14)) {
98474
- violations2.push({ path: path4, reason: `is ${String(v14)}` });
98931
+ if (!Number.isFinite(v15)) {
98932
+ violations2.push({ path: path4, reason: `is ${String(v15)}` });
98475
98933
  }
98476
98934
  return;
98477
98935
  }
@@ -98481,7 +98939,7 @@ function checkJsonSafe(value, rootPath = "value") {
98481
98939
  }
98482
98940
  if (t3 !== "object")
98483
98941
  return;
98484
- const o3 = v14;
98942
+ const o3 = v15;
98485
98943
  if (seen.has(o3)) {
98486
98944
  violations2.push({ path: path4, reason: "is a cycle" });
98487
98945
  return;
@@ -98517,7 +98975,7 @@ var init_jsonSafety = __esm({
98517
98975
  "use strict";
98518
98976
  JsonSafetyError = class extends Error {
98519
98977
  constructor(violations2) {
98520
- const shown = violations2.slice(0, 5).map((v14) => `${v14.path} ${v14.reason}`).join(", ");
98978
+ const shown = violations2.slice(0, 5).map((v15) => `${v15.path} ${v15.reason}`).join(", ");
98521
98979
  const more = violations2.length > 5 ? ` (+${violations2.length - 5} more)` : "";
98522
98980
  super(`Refusing to write a vector value that a document cannot carry: ${shown}${more}. Nothing downstream catches this \u2014 Opaque persists NaN as null and OpJson skips validation on write, so the row would become permanently unreadable.`);
98523
98981
  this.name = "JsonSafetyError";
@@ -98871,7 +99329,7 @@ function gradientReference(gradient, id, defs) {
98871
99329
  return `url(#${id})`;
98872
99330
  }
98873
99331
  function serializeGradientDef(def3) {
98874
- const attrs = Object.entries(def3.attrs).map(([k, v14]) => `${attrName(k)}="${escapeAttr(String(v14))}"`).join(" ");
99332
+ const attrs = Object.entries(def3.attrs).map(([k, v15]) => `${attrName(k)}="${escapeAttr(String(v15))}"`).join(" ");
98875
99333
  const stops = def3.stops.map((s5) => `<stop offset="${escapeAttr(s5.offset)}" stop-color="${escapeAttr(s5.color)}"/>`).join("");
98876
99334
  return `<${def3.tag} ${attrs}>${stops}</${def3.tag}>`;
98877
99335
  }
@@ -100781,8 +101239,8 @@ function createBackgroundsList(specs) {
100781
101239
  function isOpaqueObject(value) {
100782
101240
  if (!value || typeof value !== "object")
100783
101241
  return false;
100784
- const v14 = value;
100785
- return "id" in v14 && "modelName" in v14;
101242
+ const v15 = value;
101243
+ return "id" in v15 && "modelName" in v15;
100786
101244
  }
100787
101245
  var init_creators = __esm({
100788
101246
  "../shared/dist/ai/executor/property-updater/creators.js"() {
@@ -100801,20 +101259,20 @@ function isMeasurementValue(value) {
100801
101259
  function isBlurSpec(value) {
100802
101260
  if (typeof value !== "object" || value === null)
100803
101261
  return false;
100804
- const v14 = value;
100805
- return "value" in v14;
101262
+ const v15 = value;
101263
+ return "value" in v15;
100806
101264
  }
100807
101265
  function isDimensionsSpec(value) {
100808
101266
  if (typeof value !== "object" || value === null)
100809
101267
  return false;
100810
- const v14 = value;
100811
- return "top" in v14 || "right" in v14 || "bottom" in v14 || "left" in v14;
101268
+ const v15 = value;
101269
+ return "top" in v15 || "right" in v15 || "bottom" in v15 || "left" in v15;
100812
101270
  }
100813
101271
  function isCornersSpec(value) {
100814
101272
  if (typeof value !== "object" || value === null)
100815
101273
  return false;
100816
- const v14 = value;
100817
- return "topLeft" in v14 || "topRight" in v14 || "bottomLeft" in v14 || "bottomRight" in v14;
101274
+ const v15 = value;
101275
+ return "topLeft" in v15 || "topRight" in v15 || "bottomLeft" in v15 || "bottomRight" in v15;
100818
101276
  }
100819
101277
  var init_types6 = __esm({
100820
101278
  "../shared/dist/ai/executor/property-updater/types.js"() {
@@ -101194,6 +101652,9 @@ function createComponentInBranch(branch, name) {
101194
101652
  getOpList(branch, "components").prepend(component);
101195
101653
  return component;
101196
101654
  }
101655
+ function createPageBodyNode(overrides) {
101656
+ return createNodeWithDefaults("page", Object.assign(Object.assign({}, overrides), { node: Object.assign({ name: PAGE_BODY_NAME, sortOrder: 1 }, overrides === null || overrides === void 0 ? void 0 : overrides.node) }));
101657
+ }
101197
101658
  function createPageInBranch(branch, name) {
101198
101659
  const page = Page.create({
101199
101660
  name,
@@ -101203,7 +101664,20 @@ function createPageInBranch(branch, name) {
101203
101664
  getOpList(branch, "pages").prepend(page);
101204
101665
  return page;
101205
101666
  }
101206
- var newCanvas;
101667
+ function createRouteInBranch(branch, name, route) {
101668
+ const siblings = getOpList(branch, "pages").asArray().filter((p4) => p4 != null);
101669
+ const isIndex = shouldNewRouteBeIndex(siblings, {
101670
+ requestedIndex: route.isIndex,
101671
+ parentPageId: route.parentPageId
101672
+ });
101673
+ if (isIndex) {
101674
+ clearOtherIndexPages("", siblings);
101675
+ }
101676
+ const page = Page.create(Object.assign(Object.assign({ type: PageTypes.Route, name, slug: route.slug, sortOrder: route.sortOrder, parentPageId: route.parentPageId }, isIndex ? { isIndex: true } : {}), { nodes: ListOfNodes.create([createPageBodyNode()]), canvas: ref(newCanvas()) }));
101677
+ getOpList(branch, "pages").append(page);
101678
+ return page;
101679
+ }
101680
+ var newCanvas, PAGE_BODY_NAME;
101207
101681
  var init_canvas_authoring = __esm({
101208
101682
  "../shared/dist/ai/executor/canvas-authoring.js"() {
101209
101683
  "use strict";
@@ -101212,6 +101686,89 @@ var init_canvas_authoring = __esm({
101212
101686
  init_schema();
101213
101687
  init_sanitizeIdentifier();
101214
101688
  newCanvas = (overrides) => Canvas.create(Object.assign({ zoom: 1, position: { x: 0, y: 0 }, backgroundColor: canvasBackgroundColor() }, overrides));
101689
+ PAGE_BODY_NAME = "Body";
101690
+ }
101691
+ });
101692
+
101693
+ // ../shared/dist/ai/executor/routeCreation.js
101694
+ function planRouteCreation(action, pages) {
101695
+ var _a2, _b;
101696
+ const parentPageId = action.parentPageId;
101697
+ if (parentPageId !== void 0) {
101698
+ const parent = pages.find((page) => page.id === parentPageId);
101699
+ if (!parent || parent.type !== PageTypes.Route) {
101700
+ return {
101701
+ error: "parentPageId must name an existing route in this branch."
101702
+ };
101703
+ }
101704
+ if (action.isIndex) {
101705
+ return { error: "Only a root route can be the homepage." };
101706
+ }
101707
+ }
101708
+ const name = (_a2 = action.name) !== null && _a2 !== void 0 ? _a2 : nextSequentialName(pages.filter((page) => page.type === PageTypes.Route && page.parentPageId === parentPageId).map((page) => page.name), (n5) => `Route ${n5}`);
101709
+ const isIndex = shouldNewRouteBeIndex(pages, {
101710
+ requestedIndex: action.isIndex,
101711
+ parentPageId
101712
+ });
101713
+ let slug = (_b = action.slug) !== null && _b !== void 0 ? _b : generateUniqueSlug(name, parentPageId, "", pages);
101714
+ if (isReservedSlug(slug)) {
101715
+ return { error: `The slug "${slug}" is reserved.` };
101716
+ }
101717
+ if (!isSlugUnique(slug, parentPageId, "", pages)) {
101718
+ return {
101719
+ error: `Another route at this level already uses the slug "${slug}".`
101720
+ };
101721
+ }
101722
+ const existing = pages.filter((page) => page.type === PageTypes.Route).map((page) => ({
101723
+ id: page.id,
101724
+ name: page.name,
101725
+ slug: page.slug,
101726
+ parentPageId: page.parentPageId,
101727
+ isIndex: isIndex ? false : page.isIndex
101728
+ }));
101729
+ const paths = /* @__PURE__ */ new Set();
101730
+ for (const page of existing) {
101731
+ const path5 = getRouteFullPath(page, existing);
101732
+ if (paths.has(path5)) {
101733
+ return {
101734
+ error: `Route creation would leave multiple routes at "${path5}". Resolve the conflicting routes first.`
101735
+ };
101736
+ }
101737
+ paths.add(path5);
101738
+ }
101739
+ const candidate = { id: "", name, slug, parentPageId, isIndex };
101740
+ let path4 = getRouteFullPath(candidate, existing);
101741
+ const baseSlug = slug;
101742
+ let suffix = 1;
101743
+ while (paths.has(path4)) {
101744
+ if (action.slug !== void 0 || isIndex) {
101745
+ return {
101746
+ error: `Another route already publishes at "${path4}". Choose a different slug.`
101747
+ };
101748
+ }
101749
+ slug = `${baseSlug}-${suffix++}`;
101750
+ if (!isSlugUnique(slug, parentPageId, "", pages))
101751
+ continue;
101752
+ candidate.slug = slug;
101753
+ path4 = getRouteFullPath(candidate, existing);
101754
+ }
101755
+ return {
101756
+ name,
101757
+ path: path4,
101758
+ route: {
101759
+ slug,
101760
+ parentPageId,
101761
+ isIndex,
101762
+ sortOrder: getNextSortOrder(parentPageId, pages)
101763
+ }
101764
+ };
101765
+ }
101766
+ var init_routeCreation = __esm({
101767
+ "../shared/dist/ai/executor/routeCreation.js"() {
101768
+ "use strict";
101769
+ init_page();
101770
+ init_route_helpers();
101771
+ init_canvas_authoring();
101215
101772
  }
101216
101773
  });
101217
101774
 
@@ -101803,6 +102360,8 @@ function executeAction(action, context) {
101803
102360
  return executeDeleteComponent(action, context);
101804
102361
  case "createPage":
101805
102362
  return executeCreatePage(action, context);
102363
+ case "createRoute":
102364
+ return executeCreateRoute(action, context);
101806
102365
  case "updatePage":
101807
102366
  return executeUpdatePage(action, context);
101808
102367
  case "moveNode":
@@ -103128,6 +103687,34 @@ function executeCreatePage(action, context) {
103128
103687
  const page = createPageInBranch(branch, name);
103129
103688
  return { action, success: true, data: { pageId: page.id } };
103130
103689
  }
103690
+ function executeCreateRoute(action, context) {
103691
+ var _a2;
103692
+ const definition = OPAQUE_ACTIONS.find((entry) => entry.type === "createRoute");
103693
+ const parsed = definition.input.safeParse(action);
103694
+ if (!parsed.success) {
103695
+ return { action, success: false, error: parsed.error.message };
103696
+ }
103697
+ const pages = Array.from(getBranchPages(context.branch)).filter((page2) => page2 != null);
103698
+ const plan = planRouteCreation(Object.assign({ type: "createRoute" }, parsed.data), pages);
103699
+ if (plan.error !== void 0) {
103700
+ return { action, success: false, error: plan.error };
103701
+ }
103702
+ const page = createRouteInBranch(context.branch, plan.name, plan.route);
103703
+ const body = findPageBodyNode(pageNodes(page));
103704
+ return {
103705
+ action,
103706
+ success: true,
103707
+ data: {
103708
+ pageId: page.id,
103709
+ bodyNodeId: body.id,
103710
+ name: plan.name,
103711
+ slug: plan.route.slug,
103712
+ path: plan.path,
103713
+ isIndex: plan.route.isIndex,
103714
+ parentPageId: (_a2 = plan.route.parentPageId) !== null && _a2 !== void 0 ? _a2 : null
103715
+ }
103716
+ };
103717
+ }
103131
103718
  function executeDeletePage(action, context) {
103132
103719
  const { branch } = context;
103133
103720
  if (!action.pageId) {
@@ -103256,8 +103843,8 @@ function executeCreateComponentProp(action, context) {
103256
103843
  }
103257
103844
  const exposedIds = new Set(Array.from(propsOf(component)).filter((p4) => p4 !== null).map((p4) => p4.variableId));
103258
103845
  const themeVariables = getDefaultThemeVariables2(branch);
103259
- const allVariables = themeVariables ? Array.from(themeVariablesVariables(themeVariables)).filter((v14) => v14 !== null) : [];
103260
- const exposedNames = new Set(allVariables.filter((v14) => exposedIds.has(v14.id)).map((v14) => v14.name));
103846
+ const allVariables = themeVariables ? Array.from(themeVariablesVariables(themeVariables)).filter((v15) => v15 !== null) : [];
103847
+ const exposedNames = new Set(allVariables.filter((v15) => exposedIds.has(v15.id)).map((v15) => v15.name));
103261
103848
  if (exposedNames.has(normalizedName)) {
103262
103849
  return {
103263
103850
  action,
@@ -103343,7 +103930,7 @@ function executeSetPropValue(action, context) {
103343
103930
  };
103344
103931
  }
103345
103932
  const themeVariables = getDefaultThemeVariables2(branch);
103346
- const variable = themeVariables ? Array.from(themeVariablesVariables(themeVariables)).find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === prop.variableId) : void 0;
103933
+ const variable = themeVariables ? Array.from(themeVariablesVariables(themeVariables)).find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === prop.variableId) : void 0;
103347
103934
  if (!variable) {
103348
103935
  return {
103349
103936
  action,
@@ -103726,11 +104313,11 @@ function executeGetCanvasState(action, context) {
103726
104313
  };
103727
104314
  const themeVariables = getDefaultThemeVariables2(branch);
103728
104315
  if (themeVariables) {
103729
- for (const v14 of themeVariablesVariables(themeVariables)) {
103730
- if (!v14 || v14.componentId)
104316
+ for (const v15 of themeVariablesVariables(themeVariables)) {
104317
+ if (!v15 || v15.componentId)
103731
104318
  continue;
103732
104319
  variablesSummary.totalCount++;
103733
- const type = v14.type || "unknown";
104320
+ const type = v15.type || "unknown";
103734
104321
  variablesSummary.byType[type] = (variablesSummary.byType[type] || 0) + 1;
103735
104322
  }
103736
104323
  }
@@ -103975,14 +104562,14 @@ function serializeNodeDetailsForAI(rawNode, branchId, branch, hasChildren = fals
103975
104562
  appearance && branchId ? resolveLiveRef(appearance[side], branchId) : appearance === null || appearance === void 0 ? void 0 : appearance[side]
103976
104563
  ]);
103977
104564
  let bg;
103978
- const val = (v14) => {
104565
+ const val = (v15) => {
103979
104566
  var _a3;
103980
- return (_a3 = derefEntity(v14, branchId)) === null || _a3 === void 0 ? void 0 : _a3.value;
104567
+ return (_a3 = derefEntity(v15, branchId)) === null || _a3 === void 0 ? void 0 : _a3.value;
103981
104568
  };
103982
- const measure = (v14) => measurementText(derefEntity(v14, branchId));
103983
- const put = (key, v14) => {
103984
- if (v14 !== void 0 && v14 !== null)
103985
- styles[key] = v14;
104569
+ const measure = (v15) => measurementText(derefEntity(v15, branchId));
104570
+ const put = (key, v15) => {
104571
+ if (v15 !== void 0 && v15 !== null)
104572
+ styles[key] = v15;
103986
104573
  };
103987
104574
  if (layout) {
103988
104575
  const l = layout;
@@ -104066,7 +104653,7 @@ function serializeNodeDetailsForAI(rawNode, branchId, branch, hasChildren = fals
104066
104653
  corners[corner] = text2;
104067
104654
  }
104068
104655
  const values = Object.values(corners);
104069
- styles.borderRadius = values.length === 4 && values.every((v14) => v14 === values[0]) ? values[0] : corners;
104656
+ styles.borderRadius = values.length === 4 && values.every((v15) => v15 === values[0]) ? values[0] : corners;
104070
104657
  }
104071
104658
  if (text) {
104072
104659
  if (((_b = text.fontSize) === null || _b === void 0 ? void 0 : _b.value) !== void 0) {
@@ -104338,10 +104925,10 @@ function executeQueryVariants(action, context) {
104338
104925
  continue;
104339
104926
  const values = [];
104340
104927
  if (group.validValues) {
104341
- for (const v14 of group.validValues) {
104342
- if (!v14)
104928
+ for (const v15 of group.validValues) {
104929
+ if (!v15)
104343
104930
  continue;
104344
- values.push({ id: v14.id, name: v14.name });
104931
+ values.push({ id: v15.id, name: v15.name });
104345
104932
  }
104346
104933
  }
104347
104934
  variantGroups.push({
@@ -104538,7 +105125,7 @@ function executeAddVariantGroupValue(action, context) {
104538
105125
  }
104539
105126
  const group = component.variantGroups[groupIndex];
104540
105127
  const currentValues = group.validValues || [];
104541
- if (currentValues.some((v14) => v14.name === action.valueName)) {
105128
+ if (currentValues.some((v15) => v15.name === action.valueName)) {
104542
105129
  return {
104543
105130
  action,
104544
105131
  success: false,
@@ -104606,10 +105193,10 @@ function executeCreateVariant(action, context) {
104606
105193
  error: `Component not found: ${action.componentId}`
104607
105194
  };
104608
105195
  }
104609
- const existingVariants = componentVariants(component).filter((v14) => v14 !== null && v14 !== void 0);
105196
+ const existingVariants = componentVariants(component).filter((v15) => v15 !== null && v15 !== void 0);
104610
105197
  let sourceVariant;
104611
105198
  if (action.sourceVariantId) {
104612
- sourceVariant = existingVariants.find((v14) => v14.id === action.sourceVariantId);
105199
+ sourceVariant = existingVariants.find((v15) => v15.id === action.sourceVariantId);
104613
105200
  if (!sourceVariant) {
104614
105201
  return {
104615
105202
  action,
@@ -104618,7 +105205,7 @@ function executeCreateVariant(action, context) {
104618
105205
  };
104619
105206
  }
104620
105207
  } else {
104621
- sourceVariant = existingVariants.find((v14) => !v14.variantGroups);
105208
+ sourceVariant = existingVariants.find((v15) => !v15.variantGroups);
104622
105209
  if (!sourceVariant && existingVariants.length > 0) {
104623
105210
  sourceVariant = existingVariants[0];
104624
105211
  }
@@ -104638,16 +105225,16 @@ function executeCreateVariant(action, context) {
104638
105225
  return {
104639
105226
  action,
104640
105227
  success: false,
104641
- error: `createVariant: ${valueId} is not a value of group "${group.name}". Its values are ${((_b = group.validValues) !== null && _b !== void 0 ? _b : []).map((v14) => `${v14.name} (${v14.id})`).join(", ")}.`
105228
+ error: `createVariant: ${valueId} is not a value of group "${group.name}". Its values are ${((_b = group.validValues) !== null && _b !== void 0 ? _b : []).map((v15) => `${v15.name} (${v15.id})`).join(", ")}.`
104642
105229
  };
104643
105230
  }
104644
105231
  }
104645
- const requested = Object.entries(action.variantGroupValues).sort(([a5], [b4]) => a5.localeCompare(b4)).map(([g2, v14]) => `${g2}=${v14}`).join(",");
105232
+ const requested = Object.entries(action.variantGroupValues).sort(([a5], [b4]) => a5.localeCompare(b4)).map(([g2, v15]) => `${g2}=${v15}`).join(",");
104646
105233
  const collision = existingVariants.find((variant) => {
104647
105234
  const groupsOf = variant === null || variant === void 0 ? void 0 : variant.variantGroups;
104648
105235
  if (!groupsOf)
104649
105236
  return false;
104650
- const key = Object.entries(groupsOf).sort(([a5], [b4]) => a5.localeCompare(b4)).map(([g2, v14]) => `${g2}=${v14}`).join(",");
105237
+ const key = Object.entries(groupsOf).sort(([a5], [b4]) => a5.localeCompare(b4)).map(([g2, v15]) => `${g2}=${v15}`).join(",");
104651
105238
  return key === requested;
104652
105239
  });
104653
105240
  if (collision) {
@@ -105826,9 +106413,9 @@ function findBranchVariable(branch, variableId) {
105826
106413
  const themeVariables = getDefaultThemeVariables2(branch);
105827
106414
  if (!themeVariables)
105828
106415
  return void 0;
105829
- for (const v14 of themeVariablesVariables(themeVariables)) {
105830
- if (v14 && v14.id === variableId)
105831
- return v14;
106416
+ for (const v15 of themeVariablesVariables(themeVariables)) {
106417
+ if (v15 && v15.id === variableId)
106418
+ return v15;
105832
106419
  }
105833
106420
  return void 0;
105834
106421
  }
@@ -105918,8 +106505,8 @@ function executeCreateSlot(action, context) {
105918
106505
  error: `createSlot: node ${action.nodeId} already holds slot ${box.slotId}. One box, one slot.`
105919
106506
  };
105920
106507
  }
105921
- const existing = ((_a2 = component.slots) !== null && _a2 !== void 0 ? _a2 : []).filter((v14) => !!v14);
105922
- const clash = existing.find((v14) => v14.name === action.name);
106508
+ const existing = ((_a2 = component.slots) !== null && _a2 !== void 0 ? _a2 : []).filter((v15) => !!v15);
106509
+ const clash = existing.find((v15) => v15.name === action.name);
105923
106510
  if (clash) {
105924
106511
  return {
105925
106512
  action,
@@ -106474,7 +107061,7 @@ function executeCreateNodeEvent(action, context) {
106474
107061
  };
106475
107062
  }
106476
107063
  const themeVariables = getDefaultThemeVariables2(branch);
106477
- targetVariable = themeVariables ? (_b = Array.from(themeVariablesVariables(themeVariables)).find((v14) => (v14 === null || v14 === void 0 ? void 0 : v14.id) === prop.variableId)) !== null && _b !== void 0 ? _b : void 0 : void 0;
107064
+ targetVariable = themeVariables ? (_b = Array.from(themeVariablesVariables(themeVariables)).find((v15) => (v15 === null || v15 === void 0 ? void 0 : v15.id) === prop.variableId)) !== null && _b !== void 0 ? _b : void 0 : void 0;
106478
107065
  if (!targetVariable) {
106479
107066
  return {
106480
107067
  action,
@@ -106889,6 +107476,8 @@ var init_actionExecutor = __esm({
106889
107476
  init_pageStructure();
106890
107477
  init_nodeUtils();
106891
107478
  init_canvas_authoring();
107479
+ init_routeCreation();
107480
+ init_opaqueActions();
106892
107481
  init_sanitizeIdentifier();
106893
107482
  init_variableCreation();
106894
107483
  init_codeFileVerbs();
@@ -107968,8 +108557,8 @@ var init_ai_action_api = __esm({
107968
108557
  instanceComponentId: "string (optional) - Required when nodeType is 'instance': the component this instance renders (e.g. 'cp_...'; older ids use 'op_...').",
107969
108558
  instanceVariantId: "string (optional) - Optional: the variant of instanceComponentId this instance points at. Defaults to the master component's default variant.",
107970
108559
  formElementType: "string (optional) - For nodeType 'input': which form control this node renders (default 'text').",
107971
- svgPath: "string (optional) - Required when nodeType is 'vector': the SVG markup/path.",
107972
- shaderLayers: "string[] (optional) - Shader layer specs, one per layer. Each matches the ShaderLayer shape: name (string), sortOrder (number), visible (boolean), effectType (e.g. 'meshGradient', 'perlinNoise'), blendMode, opacity/animated/animationSpeed/scale/offsetX/offsetY/rotation and effect-specific numeric params as plain numbers, color1/color2/color3/colorBack as hex or rgb(a) strings, colors as an array of such strings.",
108560
+ svgPath: "string (optional) - Required when nodeType is 'vector'. Accepts a complete SVG document or bare path data. Imports supported geometry into an editable vector network. The renderer uses SVG baked from that network, not the original document. Supply a viewBox to define the artwork dimensions. Check warnings for unsupported elements. This is not a runtime for scripts or SVG/CSS animation.",
108561
+ shaderLayers: "string[] (optional) - Shader layer specs, one per layer. Each matches the ShaderLayer shape: name (string), sortOrder (number), visible (boolean), effectType (e.g. 'meshGradient', 'perlinNoise'), blendMode, opacity/animated/animationSpeed/scale/offsetX/offsetY/rotation and effect-specific numeric params as plain numbers, color1/color2/color3/colorBack as hex or rgb(a) strings, colors as an array of such strings. Only catalog effects are supported; this field does not accept custom GLSL or WGSL source.",
107973
108562
  updates: "object (optional) - Initial/updated values: `styles` for visual properties, `name` for the layer name, `innerText` for text content (text nodes only), `svgPath` to promote to vector, `shaderLayers` for shader effects, plus the semantic node fields (placeholder, inputValue, inputTextType, htmlTag, className, url, target, frameUrl)."
107974
108563
  }
107975
108564
  },
@@ -108012,11 +108601,21 @@ var init_ai_action_api = __esm({
108012
108601
  },
108013
108602
  {
108014
108603
  type: "createPage",
108015
- description: "Create a new draft page with no nodes. Auto-names 'Page N' (deduped) when name is omitted.",
108604
+ description: "Create a new draft page with no nodes. Auto-names 'Page N' (deduped) when name is omitted. Use createRoute for a page that publishes to a URL.",
108016
108605
  parameters: {
108017
108606
  name: "string (optional) - Name for the new page (auto-generated if omitted)"
108018
108607
  }
108019
108608
  },
108609
+ {
108610
+ type: "createRoute",
108611
+ description: "Create a publishable route with one Body node. Returns pageId, bodyNodeId, slug, path, and isIndex. Add content inside bodyNodeId with createNode or applyCanvasEdits. The first root route becomes the homepage automatically. An explicit isIndex claim transfers the homepage from the current route. Use parentPageId to nest routes; slug is one URL segment. Deployment remains a separate action.",
108612
+ parameters: {
108613
+ name: "string (optional) - Display name. Defaults to a unique Route N.",
108614
+ slug: "string (optional) - URL segment, such as signal-noise. Omit to generate a unique slug from the name. Explicit collisions are rejected.",
108615
+ parentPageId: "string (optional) - ID of the page (e.g. 'pg_...'; older ids use 'op_...')",
108616
+ isIndex: "boolean (optional) - Set true to make this root route the homepage. The first root route is always the homepage."
108617
+ }
108618
+ },
108020
108619
  {
108021
108620
  type: "moveNode",
108022
108621
  description: "Reparent a node within its page or variant. Pass no newParentNodeId to move it to the top level. Cannot move a node between pages or variants, or into its own subtree.",
@@ -111774,11 +112373,11 @@ function TextInput({
111774
112373
  }
111775
112374
  if (key.backspace || key.delete) {
111776
112375
  setTouched(true);
111777
- setValue((v14) => v14.slice(0, -1));
112376
+ setValue((v15) => v15.slice(0, -1));
111778
112377
  return;
111779
112378
  }
111780
112379
  if (input && !key.ctrl && !key.meta && !key.escape) {
111781
- setValue((v14) => touched ? v14 + input : input);
112380
+ setValue((v15) => touched ? v15 + input : input);
111782
112381
  setTouched(true);
111783
112382
  }
111784
112383
  });
@@ -111854,7 +112453,7 @@ var confirm = (prompt, yes, no) => function Confirm({ value, onFinish }) {
111854
112453
  { value: "yes", label: yes },
111855
112454
  { value: "no", label: no }
111856
112455
  ],
111857
- onSelect: (v14) => onFinish?.(v14 === "yes")
112456
+ onSelect: (v15) => onFinish?.(v15 === "yes")
111858
112457
  }
111859
112458
  )
111860
112459
  ] });
@@ -111977,7 +112576,7 @@ function createFlow() {
111977
112576
  /* @__PURE__ */ jsx2(Em, { children: spec.prompt }),
111978
112577
  spec.hint ? /* @__PURE__ */ jsx2(Dim, { children: spec.hint }) : null
111979
112578
  ] }),
111980
- /* @__PURE__ */ jsx2(Select, { items: spec.options, onSelect: (v14) => onFinish?.(v14) })
112579
+ /* @__PURE__ */ jsx2(Select, { items: spec.options, onSelect: (v15) => onFinish?.(v15) })
111981
112580
  ] });
111982
112581
  };
111983
112582
  do {
@@ -112103,7 +112702,7 @@ var intro = ({
112103
112702
  { value: "continue", label: copy.goLabel },
112104
112703
  { value: "exit", label: "Exit" }
112105
112704
  ],
112106
- onSelect: (v14) => onFinish?.(v14 === "continue")
112705
+ onSelect: (v15) => onFinish?.(v15 === "continue")
112107
112706
  }
112108
112707
  ) : null
112109
112708
  ] });
@@ -112162,7 +112761,7 @@ var askProjectName = (initial) => function AskProjectName({ value, onFinish }) {
112162
112761
  TextInput,
112163
112762
  {
112164
112763
  initial,
112165
- onSubmit: (v14) => onFinish?.(v14.trim() || initial)
112764
+ onSubmit: (v15) => onFinish?.(v15.trim() || initial)
112166
112765
  }
112167
112766
  )
112168
112767
  ] });
@@ -112259,7 +112858,7 @@ function payloadToScanReport(local) {
112259
112858
  const payloadComponent = local.payload.components.find(
112260
112859
  (p4) => p4.tempId === c3.tempId
112261
112860
  );
112262
- const variants = payloadComponent?.variants?.map((v14) => v14.name) ?? [];
112861
+ const variants = payloadComponent?.variants?.map((v15) => v15.name) ?? [];
112263
112862
  return {
112264
112863
  name: c3.name,
112265
112864
  file: path.relative(process.cwd(), c3.filePath),