@beyondwork/docx-react-component 1.0.134 → 1.0.136

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 (89) hide show
  1. package/dist/api/public-types.cjs +20 -2
  2. package/dist/api/public-types.d.cts +2 -2
  3. package/dist/api/public-types.d.ts +2 -2
  4. package/dist/api/public-types.js +2 -2
  5. package/dist/api/v3.cjs +203 -41
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +4 -4
  9. package/dist/{canonical-document-CfZIc-fC.d.cts → canonical-document-COmM7v11.d.cts} +1 -1
  10. package/dist/{canonical-document-CfZIc-fC.d.ts → canonical-document-COmM7v11.d.ts} +1 -1
  11. package/dist/{chunk-REFHJ2FN.js → chunk-2BNXARVO.js} +3 -3
  12. package/dist/{chunk-INLRCC4N.js → chunk-4CIHTMCH.js} +2 -2
  13. package/dist/{chunk-MQ5GAJ54.js → chunk-BJXSMPHD.js} +1 -1
  14. package/dist/{chunk-XBQFDBXE.js → chunk-EZFF6GKF.js} +9 -2
  15. package/dist/{chunk-3YR47WTD.js → chunk-FGJTOFZY.js} +21 -9
  16. package/dist/{chunk-74R5B2EZ.js → chunk-H4HI6RUE.js} +1 -1
  17. package/dist/{chunk-IJD6D7HU.js → chunk-HUWZ7AHE.js} +125 -2
  18. package/dist/{chunk-7Y6JCIK3.js → chunk-HWMPNLEF.js} +1 -1
  19. package/dist/{chunk-EBSI6VQX.js → chunk-JZZKTL7K.js} +800 -93
  20. package/dist/{chunk-VA24T4EB.js → chunk-NEMOQ4QR.js} +1 -1
  21. package/dist/{chunk-ESEEWELA.js → chunk-NX7W6T7L.js} +171 -39
  22. package/dist/{chunk-O4EDZR44.js → chunk-P7XDEVS6.js} +12 -1
  23. package/dist/{chunk-QTRJLKR2.js → chunk-TSNK4ECL.js} +1 -1
  24. package/dist/{chunk-WDDFU2N2.js → chunk-UR2LW63N.js} +1 -1
  25. package/dist/compare.d.cts +1 -1
  26. package/dist/compare.d.ts +1 -1
  27. package/dist/core/commands/formatting-commands.d.cts +2 -2
  28. package/dist/core/commands/formatting-commands.d.ts +2 -2
  29. package/dist/core/commands/image-commands.cjs +9 -2
  30. package/dist/core/commands/image-commands.d.cts +2 -2
  31. package/dist/core/commands/image-commands.d.ts +2 -2
  32. package/dist/core/commands/image-commands.js +4 -4
  33. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  34. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  35. package/dist/core/commands/style-commands.d.cts +2 -2
  36. package/dist/core/commands/style-commands.d.ts +2 -2
  37. package/dist/core/commands/table-structure-commands.cjs +9 -2
  38. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  39. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  40. package/dist/core/commands/table-structure-commands.js +3 -3
  41. package/dist/core/commands/text-commands.cjs +9 -2
  42. package/dist/core/commands/text-commands.d.cts +2 -2
  43. package/dist/core/commands/text-commands.d.ts +2 -2
  44. package/dist/core/commands/text-commands.js +4 -4
  45. package/dist/core/selection/mapping.d.cts +2 -2
  46. package/dist/core/selection/mapping.d.ts +2 -2
  47. package/dist/core/state/editor-state.d.cts +2 -2
  48. package/dist/core/state/editor-state.d.ts +2 -2
  49. package/dist/index.cjs +1287 -198
  50. package/dist/index.d.cts +5 -5
  51. package/dist/index.d.ts +5 -5
  52. package/dist/index.js +135 -34
  53. package/dist/io/docx-session.d.cts +4 -4
  54. package/dist/io/docx-session.d.ts +4 -4
  55. package/dist/legal.d.cts +1 -1
  56. package/dist/legal.d.ts +1 -1
  57. package/dist/{loader-CK3lZy4h.d.cts → loader-Cr35kVUi.d.cts} +3 -3
  58. package/dist/{loader-CQXplstv.d.ts → loader-uGY6nDZP.d.ts} +3 -3
  59. package/dist/{public-types-DXNZVKrS.d.ts → public-types-8kVIB5HW.d.ts} +22 -8
  60. package/dist/{public-types-BR1SYK2F.d.cts → public-types-CSSH2Whc.d.cts} +22 -8
  61. package/dist/public-types.cjs +20 -2
  62. package/dist/public-types.d.cts +2 -2
  63. package/dist/public-types.d.ts +2 -2
  64. package/dist/public-types.js +2 -2
  65. package/dist/runtime/collab.d.cts +3 -3
  66. package/dist/runtime/collab.d.ts +3 -3
  67. package/dist/runtime/document-runtime.cjs +929 -83
  68. package/dist/runtime/document-runtime.d.cts +2 -2
  69. package/dist/runtime/document-runtime.d.ts +2 -2
  70. package/dist/runtime/document-runtime.js +10 -10
  71. package/dist/{session-CSbwkgII.d.cts → session-Beg8ihOi.d.cts} +3 -3
  72. package/dist/{session-C9UjrhJF.d.ts → session-Dgp-2uYw.d.ts} +3 -3
  73. package/dist/session.d.cts +5 -5
  74. package/dist/session.d.ts +5 -5
  75. package/dist/tailwind.cjs +27 -8
  76. package/dist/tailwind.d.cts +2 -2
  77. package/dist/tailwind.d.ts +2 -2
  78. package/dist/tailwind.js +5 -5
  79. package/dist/{types-RzkCXDNV.d.ts → types-Cin_abw3.d.ts} +2 -2
  80. package/dist/{types-CZtAueri.d.cts → types-qsS39ZkQ.d.cts} +2 -2
  81. package/dist/ui-tailwind/editor-surface/search-plugin.cjs +11 -0
  82. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  83. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  84. package/dist/ui-tailwind/editor-surface/search-plugin.js +3 -3
  85. package/dist/ui-tailwind.cjs +27 -8
  86. package/dist/ui-tailwind.d.cts +3 -3
  87. package/dist/ui-tailwind.d.ts +3 -3
  88. package/dist/ui-tailwind.js +5 -5
  89. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -12983,10 +12983,16 @@ var FormattingContextImpl = class {
12983
12983
  // surface-projection calls `resolveParagraphCascade` on the same
12984
12984
  // paragraph via `resolveParagraph` + numbering resolve + marker-rPr;
12985
12985
  // each of those re-walked the style catalog before.
12986
- paragraphCascadeCache = /* @__PURE__ */ new WeakMap();
12986
+ //
12987
+ // Defaults to a per-context instance, but the runtime can supply a
12988
+ // persistent `WeakMap` via `FormattingContextOptions.paragraphCascadeCache`
12989
+ // so unchanged paragraphs don't re-cascade on every keystroke. See the
12990
+ // contract on the option for invalidation semantics.
12991
+ paragraphCascadeCache;
12987
12992
  constructor(doc, opts) {
12988
12993
  this.doc = doc;
12989
12994
  this.opts = opts;
12995
+ this.paragraphCascadeCache = opts.paragraphCascadeCache ?? /* @__PURE__ */ new WeakMap();
12990
12996
  const canonicalTheme = doc.subParts?.canonicalTheme;
12991
12997
  this.theme = opts.themeResolver ?? (canonicalTheme ? new ThemeColorResolver(canonicalTheme) : void 0);
12992
12998
  this.numbering = opts.numberingPrefixResolver ?? createNumberingPrefixResolver(doc.numbering);
@@ -13552,7 +13558,8 @@ function createEditorSurfaceSnapshot(document2, _selection, activeStory = { kind
13552
13558
  const formattingContext = createFormattingContext(document2, {
13553
13559
  ...options.revisionMarkupMode ? { revisionMarkupMode: options.revisionMarkupMode } : {},
13554
13560
  ...options.getEffectiveMarkupMode ? { getEffectiveMarkupMode: options.getEffectiveMarkupMode } : {},
13555
- ...options.authorColorPalette ? { authorColorPalette: options.authorColorPalette } : {}
13561
+ ...options.authorColorPalette ? { authorColorPalette: options.authorColorPalette } : {},
13562
+ ...options.paragraphCascadeCache ? { paragraphCascadeCache: options.paragraphCascadeCache } : {}
13556
13563
  });
13557
13564
  const editableTargetsByBlockPath = options.editableTargetsByBlockPath ?? indexEditableTargetsByBlockPath(document2);
13558
13565
  const layoutIdentitiesByBlockPath = options.layoutIdentitiesByBlockPath;
@@ -22575,6 +22582,8 @@ function buildSearchPattern(query, options = {}) {
22575
22582
  function findSearchMatches(text, query, options = {}) {
22576
22583
  const pattern = buildSearchPattern(query, options);
22577
22584
  if (!pattern) return [];
22585
+ const limit = normalizeSearchLimit(options.limit);
22586
+ if (limit === 0) return [];
22578
22587
  const results = [];
22579
22588
  let match;
22580
22589
  pattern.lastIndex = 0;
@@ -22585,12 +22594,21 @@ function findSearchMatches(text, query, options = {}) {
22585
22594
  text: match[0],
22586
22595
  index: results.length
22587
22596
  });
22597
+ if (results.length >= limit) {
22598
+ break;
22599
+ }
22588
22600
  if (match[0].length === 0) {
22589
22601
  pattern.lastIndex += 1;
22590
22602
  }
22591
22603
  }
22592
22604
  return results;
22593
22605
  }
22606
+ function normalizeSearchLimit(limit) {
22607
+ if (limit === void 0 || !Number.isFinite(limit)) {
22608
+ return Number.POSITIVE_INFINITY;
22609
+ }
22610
+ return Math.max(0, Math.floor(limit));
22611
+ }
22594
22612
  function createSearchExcerpt(text, from, to, radius = 24) {
22595
22613
  const safeFrom = Math.max(0, Math.min(from, text.length));
22596
22614
  const safeTo = Math.max(safeFrom, Math.min(to, text.length));
@@ -24362,6 +24380,106 @@ function setStartOverride(catalog, numberingInstanceId, level, startAt) {
24362
24380
  overrides: mergeOverride(instance.overrides, { level, startAt })
24363
24381
  };
24364
24382
  }
24383
+ function mergeFragmentNumberingCatalog(target, fragment) {
24384
+ const catalog = cloneNumberingCatalog(target);
24385
+ const abstractIdMap = /* @__PURE__ */ new Map();
24386
+ const instanceIdMap = /* @__PURE__ */ new Map();
24387
+ const picBulletIdMap = /* @__PURE__ */ new Map();
24388
+ if (!fragment) {
24389
+ return { catalog, abstractIdMap, instanceIdMap, picBulletIdMap };
24390
+ }
24391
+ for (const [picBulletId, entry] of Object.entries(fragment.numPicBullets ?? {})) {
24392
+ const mappedId = mapPicBulletId(catalog, picBulletId, entry);
24393
+ picBulletIdMap.set(picBulletId, mappedId);
24394
+ }
24395
+ for (const [abstractId, definition] of Object.entries(fragment.abstractDefinitions)) {
24396
+ const mappedId = mapAbstractDefinition(catalog, definition, picBulletIdMap);
24397
+ abstractIdMap.set(abstractId, mappedId);
24398
+ }
24399
+ for (const [instanceId, instance] of Object.entries(fragment.instances)) {
24400
+ const mappedAbstractId = abstractIdMap.get(instance.abstractNumberingId) ?? instance.abstractNumberingId;
24401
+ const mappedId = mapNumberingInstance(
24402
+ catalog,
24403
+ instance,
24404
+ mappedAbstractId,
24405
+ picBulletIdMap
24406
+ );
24407
+ instanceIdMap.set(instanceId, mappedId);
24408
+ }
24409
+ return { catalog, abstractIdMap, instanceIdMap, picBulletIdMap };
24410
+ }
24411
+ function mapPicBulletId(catalog, picBulletId, entry) {
24412
+ const existing = catalog.numPicBullets?.[picBulletId];
24413
+ if (existing && existing.rawXml === entry.rawXml) return picBulletId;
24414
+ const mappedId = existing ? nextNumericString(Object.keys(catalog.numPicBullets ?? {})) : picBulletId;
24415
+ const numPicBullets = { ...catalog.numPicBullets ?? {} };
24416
+ numPicBullets[mappedId] = {
24417
+ ...stripSourceRef(structuredClone(entry)),
24418
+ numPicBulletId: mappedId
24419
+ };
24420
+ catalog.numPicBullets = numPicBullets;
24421
+ return mappedId;
24422
+ }
24423
+ function mapAbstractDefinition(catalog, definition, picBulletIdMap) {
24424
+ const existing = catalog.abstractDefinitions[definition.abstractNumberingId];
24425
+ if (existing && sameJson(comparableAbstract(existing), comparableAbstract(definition))) {
24426
+ return definition.abstractNumberingId;
24427
+ }
24428
+ const mappedId = existing ? nextCanonicalNumericId("abstract-num:", Object.keys(catalog.abstractDefinitions)) : definition.abstractNumberingId;
24429
+ catalog.abstractDefinitions[mappedId] = {
24430
+ ...stripSourceRef(structuredClone(definition)),
24431
+ abstractNumberingId: mappedId,
24432
+ nsid: freshLongHex(catalog, mappedId, "nsid"),
24433
+ tplc: freshLongHex(catalog, mappedId, "tmpl"),
24434
+ levels: definition.levels.map((level) => remapLevelPicBullet(level, picBulletIdMap))
24435
+ };
24436
+ return mappedId;
24437
+ }
24438
+ function mapNumberingInstance(catalog, instance, abstractNumberingId, picBulletIdMap) {
24439
+ const existing = catalog.instances[instance.numberingInstanceId];
24440
+ const candidate = {
24441
+ ...instance,
24442
+ abstractNumberingId,
24443
+ overrides: instance.overrides.map(
24444
+ (override) => remapOverridePicBullet(override, picBulletIdMap)
24445
+ )
24446
+ };
24447
+ if (existing && sameJson(comparableInstance(existing), comparableInstance(candidate))) {
24448
+ return instance.numberingInstanceId;
24449
+ }
24450
+ const mappedId = existing ? nextCanonicalNumericId("num:", Object.keys(catalog.instances)) : instance.numberingInstanceId;
24451
+ catalog.instances[mappedId] = {
24452
+ ...stripSourceRef(structuredClone(instance)),
24453
+ overrides: candidate.overrides.map((override) => stripOverrideSourceRefs(override)),
24454
+ numberingInstanceId: mappedId,
24455
+ abstractNumberingId
24456
+ };
24457
+ return mappedId;
24458
+ }
24459
+ function remapLevelPicBullet(level, picBulletIdMap) {
24460
+ const cloned = stripSourceRef(structuredClone(level));
24461
+ if (!level.picBulletId) return cloned;
24462
+ return {
24463
+ ...cloned,
24464
+ picBulletId: picBulletIdMap.get(level.picBulletId) ?? level.picBulletId
24465
+ };
24466
+ }
24467
+ function remapOverridePicBullet(override, picBulletIdMap) {
24468
+ const cloned = stripOverrideSourceRefs(structuredClone(override));
24469
+ if (!override.levelDefinition) return cloned;
24470
+ return {
24471
+ ...cloned,
24472
+ levelDefinition: remapLevelPicBullet(override.levelDefinition, picBulletIdMap)
24473
+ };
24474
+ }
24475
+ function stripOverrideSourceRefs(override) {
24476
+ const cloned = stripSourceRef(override);
24477
+ if (!override.levelDefinition) return cloned;
24478
+ return {
24479
+ ...cloned,
24480
+ levelDefinition: stripSourceRef(override.levelDefinition)
24481
+ };
24482
+ }
24365
24483
  function mergeOverride(overrides, nextOverride) {
24366
24484
  return [
24367
24485
  ...overrides.filter((override) => override.level !== nextOverride.level),
@@ -24433,6 +24551,28 @@ function hashLongHex(input) {
24433
24551
  }
24434
24552
  return hash.toString(16).toUpperCase().padStart(8, "0").slice(-8);
24435
24553
  }
24554
+ function stripSourceRef(value) {
24555
+ const { sourceRef: _sourceRef, ...rest } = value;
24556
+ return rest;
24557
+ }
24558
+ function comparableAbstract(definition) {
24559
+ return {
24560
+ ...stripSourceRef(definition),
24561
+ levels: definition.levels.map((level) => stripSourceRef(level))
24562
+ };
24563
+ }
24564
+ function comparableInstance(instance) {
24565
+ return {
24566
+ ...stripSourceRef(instance),
24567
+ overrides: instance.overrides.map((override) => ({
24568
+ ...stripSourceRef(override),
24569
+ ...override.levelDefinition ? { levelDefinition: stripSourceRef(override.levelDefinition) } : {}
24570
+ }))
24571
+ };
24572
+ }
24573
+ function sameJson(left, right) {
24574
+ return JSON.stringify(left) === JSON.stringify(right);
24575
+ }
24436
24576
 
24437
24577
  // src/core/commands/list-commands.ts
24438
24578
  function toggleNumberedList(document2, paragraphIndexes, context, options = {}) {
@@ -24480,7 +24620,7 @@ function splitListParagraph(document2, paragraphIndex, paragraphIsEmpty, context
24480
24620
  action: "split"
24481
24621
  };
24482
24622
  }
24483
- const target = paragraphs[resolvedParagraphIndex];
24623
+ const target = paragraphs[resolvedParagraphIndex]?.paragraph;
24484
24624
  if (!target?.numbering) {
24485
24625
  return {
24486
24626
  document: working,
@@ -24532,7 +24672,7 @@ function backspaceAtListStart(document2, paragraphIndex, context, options = {})
24532
24672
  handled: false
24533
24673
  };
24534
24674
  }
24535
- const target = paragraphs[resolvedParagraphIndex];
24675
+ const target = paragraphs[resolvedParagraphIndex]?.paragraph;
24536
24676
  if (!target?.numbering) {
24537
24677
  return {
24538
24678
  document: working,
@@ -24578,7 +24718,7 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1, optio
24578
24718
  affectedParagraphIndexes: []
24579
24719
  };
24580
24720
  }
24581
- const target = paragraphs[resolvedParagraphIndex];
24721
+ const target = paragraphs[resolvedParagraphIndex]?.paragraph;
24582
24722
  if (!target?.numbering) {
24583
24723
  return {
24584
24724
  document: working,
@@ -24600,8 +24740,13 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1, optio
24600
24740
  );
24601
24741
  setStartOverride(catalog, numberingInstanceId, target.numbering.level, startAt);
24602
24742
  const affectedParagraphIndexes = [];
24743
+ const targetStoryKey = paragraphs[resolvedParagraphIndex]?.storyKey;
24603
24744
  for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
24604
- const paragraph = paragraphs[index];
24745
+ const entry = paragraphs[index];
24746
+ if (entry?.storyKey !== targetStoryKey) {
24747
+ break;
24748
+ }
24749
+ const paragraph = entry.paragraph;
24605
24750
  if (!paragraph?.numbering) {
24606
24751
  break;
24607
24752
  }
@@ -24645,7 +24790,7 @@ function continueNumbering(document2, paragraphIndex, context, options = {}) {
24645
24790
  affectedParagraphIndexes: []
24646
24791
  };
24647
24792
  }
24648
- const target = paragraphs[resolvedParagraphIndex];
24793
+ const target = paragraphs[resolvedParagraphIndex]?.paragraph;
24649
24794
  if (!target?.numbering) {
24650
24795
  return {
24651
24796
  document: working,
@@ -24674,8 +24819,13 @@ function continueNumbering(document2, paragraphIndex, context, options = {}) {
24674
24819
  };
24675
24820
  }
24676
24821
  const affectedParagraphIndexes = [];
24822
+ const targetStoryKey = paragraphs[resolvedParagraphIndex]?.storyKey;
24677
24823
  for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
24678
- const paragraph = paragraphs[index];
24824
+ const entry = paragraphs[index];
24825
+ if (entry?.storyKey !== targetStoryKey) {
24826
+ break;
24827
+ }
24828
+ const paragraph = entry.paragraph;
24679
24829
  if (!paragraph?.numbering) {
24680
24830
  break;
24681
24831
  }
@@ -24721,12 +24871,13 @@ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
24721
24871
  }
24722
24872
  const catalog = cloneNumberingCatalog(working.numbering);
24723
24873
  const allAlreadyKind = normalizedIndexes.every((index) => {
24724
- const paragraph = paragraphs[index];
24725
- return paragraph.numbering ? getListKind(catalog, paragraph.numbering.numberingInstanceId) === kind : false;
24874
+ const paragraph = paragraphs[index]?.paragraph;
24875
+ return paragraph?.numbering ? getListKind(catalog, paragraph.numbering.numberingInstanceId) === kind : false;
24726
24876
  });
24727
24877
  if (allAlreadyKind) {
24728
24878
  for (const index of normalizedIndexes) {
24729
- delete paragraphs[index].numbering;
24879
+ const paragraph = paragraphs[index]?.paragraph;
24880
+ if (paragraph) delete paragraph.numbering;
24730
24881
  }
24731
24882
  working.numbering = catalog;
24732
24883
  return {
@@ -24736,7 +24887,8 @@ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
24736
24887
  }
24737
24888
  const numberingInstanceId = findAdjacentCompatibleInstance(paragraphs, catalog, normalizedIndexes[0], kind) ?? ensureDefaultListInstance(catalog, kind);
24738
24889
  for (const index of normalizedIndexes) {
24739
- const paragraph = paragraphs[index];
24890
+ const paragraph = paragraphs[index]?.paragraph;
24891
+ if (!paragraph) continue;
24740
24892
  paragraph.numbering = {
24741
24893
  numberingInstanceId,
24742
24894
  level: clampLevel(paragraph.numbering?.level ?? 0)
@@ -24767,10 +24919,11 @@ function adjustListLevels(document2, paragraphIndexes, delta, context, options)
24767
24919
  };
24768
24920
  }
24769
24921
  const affectedParagraphIndexes = resolved.paragraphIndexes.filter(
24770
- (index) => Boolean(paragraphs[index]?.numbering)
24922
+ (index) => Boolean(paragraphs[index]?.paragraph.numbering)
24771
24923
  );
24772
24924
  for (const index of affectedParagraphIndexes) {
24773
- const paragraph = paragraphs[index];
24925
+ const paragraph = paragraphs[index]?.paragraph;
24926
+ if (!paragraph) continue;
24774
24927
  if (!paragraph.numbering) {
24775
24928
  continue;
24776
24929
  }
@@ -24790,17 +24943,21 @@ function normalizeListCommandTargets(options) {
24790
24943
  }
24791
24944
  function resolveListCommandParagraphIndexes(document2, paragraphs, paragraphIndexes, context, editableTargets) {
24792
24945
  if (editableTargets.length === 0) {
24793
- return { paragraphIndexes: normalizeParagraphIndexes(paragraphs, paragraphIndexes) };
24946
+ return {
24947
+ paragraphIndexes: normalizeParagraphIndexesForStory(
24948
+ paragraphs,
24949
+ paragraphIndexes,
24950
+ context.activeStoryKey
24951
+ )
24952
+ };
24794
24953
  }
24795
24954
  const currentTargets = collectEditableTargetRefs(document2, context.editableTargetCache);
24796
- const paragraphIndexByTargetKey = /* @__PURE__ */ new Map();
24797
- let paragraphIndex = 0;
24798
- for (const target of currentTargets) {
24799
- if (!isParagraphTextTarget(target)) continue;
24800
- if (!paragraphIndexByTargetKey.has(target.targetKey)) {
24801
- paragraphIndexByTargetKey.set(target.targetKey, paragraphIndex);
24802
- paragraphIndex += 1;
24803
- }
24955
+ const paragraphIndexByAddress = /* @__PURE__ */ new Map();
24956
+ for (let index = 0; index < paragraphs.length; index += 1) {
24957
+ const entry = paragraphs[index];
24958
+ if (!entry) continue;
24959
+ paragraphIndexByAddress.set(`${entry.storyKey}
24960
+ ${entry.blockPath}`, index);
24804
24961
  }
24805
24962
  const resolvedIndexes = [];
24806
24963
  for (const target of editableTargets) {
@@ -24825,7 +24982,8 @@ function resolveListCommandParagraphIndexes(document2, paragraphs, paragraphInde
24825
24982
  }
24826
24983
  };
24827
24984
  }
24828
- const currentIndex = paragraphIndexByTargetKey.get(current.targetKey);
24985
+ const currentIndex = paragraphIndexByAddress.get(`${current.storyKey}
24986
+ ${current.blockPath}`);
24829
24987
  if (currentIndex === void 0) {
24830
24988
  return {
24831
24989
  paragraphIndexes: [],
@@ -24900,18 +25058,28 @@ function sortJson(value) {
24900
25058
  return value;
24901
25059
  }
24902
25060
  function findAdjacentCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
25061
+ const current = paragraphs[fromIndex];
24903
25062
  const previous = paragraphs[fromIndex - 1];
24904
- if (previous?.numbering) {
24905
- const previousKind = getListKind(catalog, previous.numbering.numberingInstanceId);
25063
+ if (previous?.storyKey !== current?.storyKey) {
25064
+ return void 0;
25065
+ }
25066
+ const previousParagraph = previous?.paragraph;
25067
+ if (previousParagraph?.numbering) {
25068
+ const previousKind = getListKind(catalog, previousParagraph.numbering.numberingInstanceId);
24906
25069
  if (previousKind === kind) {
24907
- return previous.numbering.numberingInstanceId;
25070
+ return previousParagraph.numbering.numberingInstanceId;
24908
25071
  }
24909
25072
  }
24910
25073
  return void 0;
24911
25074
  }
24912
25075
  function findPreviousCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
25076
+ const storyKey2 = paragraphs[fromIndex]?.storyKey;
24913
25077
  for (let index = fromIndex - 1; index >= 0; index -= 1) {
24914
- const paragraph = paragraphs[index];
25078
+ const entry = paragraphs[index];
25079
+ if (entry?.storyKey !== storyKey2) {
25080
+ break;
25081
+ }
25082
+ const paragraph = entry.paragraph;
24915
25083
  if (!paragraph?.numbering) {
24916
25084
  continue;
24917
25085
  }
@@ -24930,7 +25098,14 @@ function cloneEnvelope(document2, timestamp) {
24930
25098
  function captureEditableParagraphs(document2) {
24931
25099
  if (isDocumentRoot(document2.content)) {
24932
25100
  const paragraphs = [];
24933
- collectEditableParagraphs(document2.content.children, paragraphs);
25101
+ for (const context of collectStoryBlockContexts(document2)) {
25102
+ collectEditableParagraphs(
25103
+ context.blocks,
25104
+ paragraphs,
25105
+ context.storyKey,
25106
+ context.basePath
25107
+ );
25108
+ }
24934
25109
  return paragraphs;
24935
25110
  }
24936
25111
  const fallback = {
@@ -24938,23 +25113,39 @@ function captureEditableParagraphs(document2) {
24938
25113
  children: [{ type: "paragraph", children: [] }]
24939
25114
  };
24940
25115
  document2.content = fallback;
24941
- return fallback.children;
25116
+ return [{
25117
+ paragraph: fallback.children[0],
25118
+ storyKey: "main",
25119
+ blockPath: "main/block[0]"
25120
+ }];
24942
25121
  }
24943
- function collectEditableParagraphs(blocks, output) {
24944
- for (const block of blocks) {
25122
+ function collectEditableParagraphs(blocks, output, storyKey2, basePath) {
25123
+ for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
25124
+ const block = blocks[blockIndex];
25125
+ if (!block) continue;
25126
+ const blockPath = `${basePath}/block[${blockIndex}]`;
24945
25127
  switch (block.type) {
24946
25128
  case "paragraph":
24947
- output.push(block);
25129
+ output.push({ paragraph: block, storyKey: storyKey2, blockPath });
24948
25130
  break;
24949
25131
  case "table":
24950
- for (const row2 of block.rows) {
24951
- for (const cell of row2.cells) {
24952
- collectEditableParagraphs(cell.children, output);
25132
+ for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
25133
+ const row2 = block.rows[rowIndex];
25134
+ if (!row2) continue;
25135
+ for (let cellIndex = 0; cellIndex < row2.cells.length; cellIndex += 1) {
25136
+ const cell = row2.cells[cellIndex];
25137
+ if (!cell) continue;
25138
+ collectEditableParagraphs(
25139
+ cell.children,
25140
+ output,
25141
+ storyKey2,
25142
+ `${blockPath}/row[${rowIndex}]/cell[${cellIndex}]`
25143
+ );
24953
25144
  }
24954
25145
  }
24955
25146
  break;
24956
25147
  case "sdt":
24957
- collectEditableParagraphs(block.children, output);
25148
+ collectEditableParagraphs(block.children, output, storyKey2, blockPath);
24958
25149
  break;
24959
25150
  case "custom_xml":
24960
25151
  break;
@@ -24966,6 +25157,18 @@ function collectEditableParagraphs(blocks, output) {
24966
25157
  function normalizeParagraphIndexes(paragraphs, paragraphIndexes) {
24967
25158
  return [...new Set(paragraphIndexes)].filter((index) => Number.isInteger(index) && index >= 0 && index < paragraphs.length).sort((left, right) => left - right);
24968
25159
  }
25160
+ function normalizeParagraphIndexesForStory(paragraphs, paragraphIndexes, storyKey2) {
25161
+ if (storyKey2 === void 0) {
25162
+ return normalizeParagraphIndexes(paragraphs, paragraphIndexes);
25163
+ }
25164
+ const storyParagraphIndexes = [];
25165
+ for (let index = 0; index < paragraphs.length; index += 1) {
25166
+ if (paragraphs[index]?.storyKey === storyKey2) {
25167
+ storyParagraphIndexes.push(index);
25168
+ }
25169
+ }
25170
+ return [...new Set(paragraphIndexes)].filter((index) => Number.isInteger(index) && index >= 0 && index < storyParagraphIndexes.length).map((index) => storyParagraphIndexes[index]).sort((left, right) => left - right);
25171
+ }
24969
25172
  function clampLevel(level) {
24970
25173
  return Math.max(0, Math.min(8, level));
24971
25174
  }
@@ -31261,9 +31464,9 @@ function findTableStructureTargetForSelection(document2, descriptor, operation2,
31261
31464
  if (descriptor.editability === "non-editable" && descriptor.nonEditableReason !== "nested-table-not-editable") {
31262
31465
  return null;
31263
31466
  }
31264
- const activeStoryKey = editableTargetStoryKey(activeStory);
31467
+ const activeStoryKey2 = editableTargetStoryKey(activeStory);
31265
31468
  const targets = collectEditableTargetRefs(document2).filter(
31266
- (target) => target.commandFamily === "table-structure" && target.table !== void 0 && target.storyKey === activeStoryKey && tableStructureTargetMatchesDescriptor2(target, descriptor)
31469
+ (target) => target.commandFamily === "table-structure" && target.table !== void 0 && target.storyKey === activeStoryKey2 && tableStructureTargetMatchesDescriptor2(target, descriptor)
31267
31470
  );
31268
31471
  const scope = preferredTableStructureScope(operation2);
31269
31472
  return targets.find((target) => {
@@ -36526,8 +36729,9 @@ function applyFragmentInsert(document2, selection, fragment, context) {
36526
36729
  workingDocument = collapseResult.document;
36527
36730
  workingSelection = collapseResult.selection;
36528
36731
  if (context.textTarget?.kind === "table-paragraph" || context.textTarget?.kind === "text-leaf") {
36732
+ const { precomputedSurface: _precomputedSurface, ...contextWithoutPrecomputedSurface } = context;
36529
36733
  workingContext = {
36530
- ...context,
36734
+ ...contextWithoutPrecomputedSurface,
36531
36735
  textTarget: {
36532
36736
  ...context.textTarget,
36533
36737
  paragraphEnd: Math.max(
@@ -36539,7 +36743,11 @@ function applyFragmentInsert(document2, selection, fragment, context) {
36539
36743
  }
36540
36744
  }
36541
36745
  const splitResult = splitParagraph(workingDocument, workingSelection, workingContext);
36542
- const splitRoot = splitResult.document.content;
36746
+ const preparedFragment = prepareFragmentNumberingForInsertion(
36747
+ splitResult.document,
36748
+ fragment
36749
+ );
36750
+ const splitRoot = preparedFragment.document.content;
36543
36751
  if (!splitRoot || splitRoot.type !== "doc") {
36544
36752
  return {
36545
36753
  changed: false,
@@ -36550,9 +36758,9 @@ function applyFragmentInsert(document2, selection, fragment, context) {
36550
36758
  const targetedBlockPath = workingContext.textTarget?.kind === "table-paragraph" || workingContext.textTarget?.kind === "text-leaf" ? workingContext.textTarget.blockPath : void 0;
36551
36759
  if (targetedBlockPath) {
36552
36760
  const targeted = insertFragmentBlocksAfterPath(
36553
- splitResult.document,
36761
+ preparedFragment.document,
36554
36762
  targetedBlockPath,
36555
- fragment.blocks
36763
+ preparedFragment.blocks
36556
36764
  );
36557
36765
  if (targeted) {
36558
36766
  return {
@@ -36584,7 +36792,7 @@ function applyFragmentInsert(document2, selection, fragment, context) {
36584
36792
  const rightHalfIndex = scope.blockIndex + 1;
36585
36793
  const splicedChildren = [
36586
36794
  ...splitRoot.children.slice(0, rightHalfIndex),
36587
- ...fragment.blocks.map((block) => cloneBlock(block)),
36795
+ ...preparedFragment.blocks.map((block) => cloneBlock(block)),
36588
36796
  ...splitRoot.children.slice(rightHalfIndex)
36589
36797
  ];
36590
36798
  const nextRoot = {
@@ -36592,7 +36800,7 @@ function applyFragmentInsert(document2, selection, fragment, context) {
36592
36800
  children: splicedChildren
36593
36801
  };
36594
36802
  const nextDocument = {
36595
- ...splitResult.document,
36803
+ ...preparedFragment.document,
36596
36804
  updatedAt: context.timestamp,
36597
36805
  content: nextRoot
36598
36806
  };
@@ -36604,14 +36812,47 @@ function applyFragmentInsert(document2, selection, fragment, context) {
36604
36812
  mapping: createEmptyMapping()
36605
36813
  };
36606
36814
  }
36607
- function cloneBlock(block) {
36608
- if (block.type === "paragraph") {
36609
- return {
36610
- ...block,
36611
- children: block.children.map((child) => ({ ...child }))
36815
+ function prepareFragmentNumberingForInsertion(document2, fragment) {
36816
+ if (!fragment.numbering) {
36817
+ return { document: document2, blocks: fragment.blocks };
36818
+ }
36819
+ const merged = mergeFragmentNumberingCatalog(document2.numbering, fragment.numbering);
36820
+ return {
36821
+ document: {
36822
+ ...document2,
36823
+ numbering: merged.catalog
36824
+ },
36825
+ blocks: fragment.blocks.map((block) => cloneBlock(block, merged.instanceIdMap))
36826
+ };
36827
+ }
36828
+ function cloneBlock(block, numberingInstanceIdMap) {
36829
+ const cloned = structuredClone(block);
36830
+ remapNumberingReferences(cloned, numberingInstanceIdMap);
36831
+ return cloned;
36832
+ }
36833
+ function remapNumberingReferences(value, numberingInstanceIdMap) {
36834
+ if (!numberingInstanceIdMap?.size || !value || typeof value !== "object") {
36835
+ return;
36836
+ }
36837
+ if (Array.isArray(value)) {
36838
+ for (const entry of value) {
36839
+ remapNumberingReferences(entry, numberingInstanceIdMap);
36840
+ }
36841
+ return;
36842
+ }
36843
+ const record = value;
36844
+ if (record.numbering?.numberingInstanceId) {
36845
+ const mappedId = numberingInstanceIdMap.get(record.numbering.numberingInstanceId) ?? record.numbering.numberingInstanceId;
36846
+ record.numbering = {
36847
+ ...record.numbering,
36848
+ numberingInstanceId: mappedId
36612
36849
  };
36613
36850
  }
36614
- return JSON.parse(JSON.stringify(block));
36851
+ remapNumberingReferences(record.children, numberingInstanceIdMap);
36852
+ remapNumberingReferences(record.rows, numberingInstanceIdMap);
36853
+ remapNumberingReferences(record.cells, numberingInstanceIdMap);
36854
+ remapNumberingReferences(record.txbxBlocks, numberingInstanceIdMap);
36855
+ remapNumberingReferences(record.content, numberingInstanceIdMap);
36615
36856
  }
36616
36857
  function insertFragmentBlocksAfterPath(document2, blockPath, fragmentBlocks) {
36617
36858
  const tokens = parseCanonicalBlockPath2(blockPath);
@@ -56458,6 +56699,16 @@ function coerceIssueValue2(value) {
56458
56699
  function insertScopeMarkers(document2, params) {
56459
56700
  const { scopeId } = params;
56460
56701
  const root = document2.content;
56702
+ if (!Number.isFinite(params.from) || !Number.isFinite(params.to)) {
56703
+ const from = Number.isFinite(params.from) ? params.from : 0;
56704
+ const to = Number.isFinite(params.to) ? params.to : from;
56705
+ return {
56706
+ status: "non-finite-range",
56707
+ scopeId,
56708
+ from,
56709
+ to
56710
+ };
56711
+ }
56461
56712
  const normalizedFrom = Math.min(params.from, params.to);
56462
56713
  const normalizedTo = Math.max(params.from, params.to);
56463
56714
  if (!root || root.type !== "doc" || root.children.length === 0) {
@@ -56910,6 +57161,14 @@ function isRecord3(value) {
56910
57161
  }
56911
57162
 
56912
57163
  // src/runtime/workflow/coordinator.ts
57164
+ function createScopeMarkerMutationMapping() {
57165
+ return {
57166
+ steps: [],
57167
+ metadata: {
57168
+ layoutNeutralScopeMarkers: true
57169
+ }
57170
+ };
57171
+ }
56913
57172
  var MODE_RESTRICTIVENESS = {
56914
57173
  edit: 0,
56915
57174
  suggest: 1,
@@ -57101,12 +57360,12 @@ function createWorkflowCoordinator(deps) {
57101
57360
  function getCachedInteractionGuardSnapshot() {
57102
57361
  const state = deps.getState();
57103
57362
  const activeStory = deps.getActiveStory();
57104
- const activeStoryKey = storyTargetKey(activeStory);
57363
+ const activeStoryKey2 = storyTargetKey(activeStory);
57105
57364
  const protectionSnapshot = deps.getProtectionSnapshot();
57106
57365
  const documentMode = deps.getDocumentMode();
57107
57366
  const overlay = overlayStore.getOverlay();
57108
57367
  const sharedWorkflowState = overlayStore.getSharedWorkflowState();
57109
- if (cachedInteractionGuardSnapshot && cachedInteractionGuardSnapshot.activeStoryKey === activeStoryKey && cachedInteractionGuardSnapshot.selection === state.selection && cachedInteractionGuardSnapshot.readOnly === state.readOnly && cachedInteractionGuardSnapshot.documentMode === documentMode && cachedInteractionGuardSnapshot.protectionSnapshot === protectionSnapshot && cachedInteractionGuardSnapshot.overlay === overlay && cachedInteractionGuardSnapshot.sharedWorkflowState === sharedWorkflowState) {
57368
+ if (cachedInteractionGuardSnapshot && cachedInteractionGuardSnapshot.activeStoryKey === activeStoryKey2 && cachedInteractionGuardSnapshot.selection === state.selection && cachedInteractionGuardSnapshot.readOnly === state.readOnly && cachedInteractionGuardSnapshot.documentMode === documentMode && cachedInteractionGuardSnapshot.protectionSnapshot === protectionSnapshot && cachedInteractionGuardSnapshot.overlay === overlay && cachedInteractionGuardSnapshot.sharedWorkflowState === sharedWorkflowState) {
57110
57369
  return cachedInteractionGuardSnapshot.snapshot;
57111
57370
  }
57112
57371
  const blockedReasons = evaluateBlockedReasons(state.selection);
@@ -57147,7 +57406,7 @@ function createWorkflowCoordinator(deps) {
57147
57406
  blockedReasons
57148
57407
  };
57149
57408
  cachedInteractionGuardSnapshot = {
57150
- activeStoryKey,
57409
+ activeStoryKey: activeStoryKey2,
57151
57410
  selection: state.selection,
57152
57411
  readOnly: state.readOnly,
57153
57412
  documentMode,
@@ -57176,13 +57435,13 @@ function createWorkflowCoordinator(deps) {
57176
57435
  function getCachedWorkflowMarkupSnapshot() {
57177
57436
  const state = deps.getState();
57178
57437
  const activeStory = deps.getActiveStory();
57179
- const activeStoryKey = storyTargetKey(activeStory);
57438
+ const activeStoryKey2 = storyTargetKey(activeStory);
57180
57439
  const protectionSnapshot = deps.getProtectionSnapshot();
57181
57440
  const preservation = deps.getDocument().preservation;
57182
57441
  const overlay = overlayStore.getOverlay();
57183
57442
  const metadataDefinitions = overlayStore.getMetadataDefinitions();
57184
57443
  const metadataEntries = overlayStore.getMetadataEntries();
57185
- if (cachedWorkflowMarkupSnapshot && cachedWorkflowMarkupSnapshot.activeStoryKey === activeStoryKey && cachedWorkflowMarkupSnapshot.protectionSnapshot === protectionSnapshot && cachedWorkflowMarkupSnapshot.preservation === preservation && cachedWorkflowMarkupSnapshot.overlay === overlay && cachedWorkflowMarkupSnapshot.metadataDefinitions === metadataDefinitions && cachedWorkflowMarkupSnapshot.metadataEntries === metadataEntries) {
57444
+ if (cachedWorkflowMarkupSnapshot && cachedWorkflowMarkupSnapshot.activeStoryKey === activeStoryKey2 && cachedWorkflowMarkupSnapshot.protectionSnapshot === protectionSnapshot && cachedWorkflowMarkupSnapshot.preservation === preservation && cachedWorkflowMarkupSnapshot.overlay === overlay && cachedWorkflowMarkupSnapshot.metadataDefinitions === metadataDefinitions && cachedWorkflowMarkupSnapshot.metadataEntries === metadataEntries) {
57186
57445
  return cachedWorkflowMarkupSnapshot.snapshot;
57187
57446
  }
57188
57447
  const snapshot = collectWorkflowMarkupSnapshot({
@@ -57193,7 +57452,7 @@ function createWorkflowCoordinator(deps) {
57193
57452
  workflowMetadataSnapshot: overlayStore.getMetadataSnapshot()
57194
57453
  });
57195
57454
  cachedWorkflowMarkupSnapshot = {
57196
- activeStoryKey,
57455
+ activeStoryKey: activeStoryKey2,
57197
57456
  protectionSnapshot,
57198
57457
  preservation,
57199
57458
  overlay,
@@ -57217,6 +57476,60 @@ function createWorkflowCoordinator(deps) {
57217
57476
  activeStory: deps.getActiveStory()
57218
57477
  };
57219
57478
  }
57479
+ function createPlantFailureResult(input) {
57480
+ const { scopeId, anchor, assoc, plantResult } = input;
57481
+ return {
57482
+ scopeId: "",
57483
+ anchor: {
57484
+ kind: "range",
57485
+ from: anchor.from,
57486
+ to: anchor.to,
57487
+ assoc
57488
+ },
57489
+ plantStatus: {
57490
+ planted: false,
57491
+ reason: plantResult.status,
57492
+ ...plantResult.status === "non-paragraph-target" ? {
57493
+ blockIndex: plantResult.blockIndex,
57494
+ blockKind: plantResult.blockKind
57495
+ } : {},
57496
+ ...plantResult.status === "range-out-of-bounds" ? { storyLength: plantResult.storyLength } : {},
57497
+ requestedFrom: plantResult.from,
57498
+ requestedTo: plantResult.to
57499
+ }
57500
+ };
57501
+ }
57502
+ function buildWorkflowScope(input) {
57503
+ const { params, scopeId, publicAnchor } = input;
57504
+ return {
57505
+ scopeId,
57506
+ mode: params.mode ?? "comment",
57507
+ anchor: publicAnchor,
57508
+ ...params.storyTarget ? { storyTarget: params.storyTarget } : {},
57509
+ ...params.label ? { label: params.label } : {},
57510
+ ...params.visibility ? { visibility: params.visibility } : {},
57511
+ ...params.guardPolicy ? { guardPolicy: params.guardPolicy } : {},
57512
+ ...params.scopeMetadataFields && params.scopeMetadataFields.length > 0 ? { metadata: [...params.scopeMetadataFields] } : {}
57513
+ };
57514
+ }
57515
+ function buildWorkflowMetadataEntry(input) {
57516
+ const { params, scopeId, publicAnchor } = input;
57517
+ if (!params.persistence || params.persistence === "runtime-only") return null;
57518
+ const requestedMetadata = params.metadata ?? {};
57519
+ const entryPersistence = requestedMetadata.metadataPersistence ?? (params.persistence === "session" ? "external" : "internal");
57520
+ return {
57521
+ entryId: requestedMetadata.entryId ?? `scope-metadata-${scopeId}`,
57522
+ metadataId: requestedMetadata.metadataId ?? "workflow.scope",
57523
+ anchor: publicAnchor,
57524
+ ...params.storyTarget ? { storyTarget: params.storyTarget } : {},
57525
+ scopeId,
57526
+ ...requestedMetadata.workItemId ? { workItemId: requestedMetadata.workItemId } : {},
57527
+ ...requestedMetadata.value !== void 0 ? { value: requestedMetadata.value } : params.persistence === "document-metadata" && params.label ? { value: { label: params.label } } : {},
57528
+ metadataPersistence: entryPersistence,
57529
+ ...requestedMetadata.storageRef !== void 0 ? { storageRef: requestedMetadata.storageRef } : {},
57530
+ ...requestedMetadata.metadataVersion !== void 0 ? { metadataVersion: requestedMetadata.metadataVersion } : {}
57531
+ };
57532
+ }
57220
57533
  function addScope(params) {
57221
57534
  const state = deps.getState();
57222
57535
  const scopeId = params.scopeId ?? `scope-${clock().replace(/[^0-9]/gu, "")}-${Math.floor(Math.random() * 1e6)}`;
@@ -57259,6 +57572,7 @@ function createWorkflowCoordinator(deps) {
57259
57572
  deps.dispatch({
57260
57573
  type: "document.replace",
57261
57574
  document: nextDocument,
57575
+ mapping: createScopeMarkerMutationMapping(),
57262
57576
  origin: { source: "api", at: clock() }
57263
57577
  });
57264
57578
  const callerAssoc = params.anchor.kind === "range" ? params.anchor.assoc : { start: -1, end: 1 };
@@ -57315,6 +57629,84 @@ function createWorkflowCoordinator(deps) {
57315
57629
  }
57316
57630
  return { scopeId, anchor: publicAnchor };
57317
57631
  }
57632
+ function addScopes(paramsList) {
57633
+ if (paramsList.length === 0) return [];
57634
+ let nextDocument = deps.getDocument();
57635
+ let documentChanged = false;
57636
+ const results = [];
57637
+ const scopesToAdd = [];
57638
+ const metadataEntriesToAdd = [];
57639
+ const newScopeIds = /* @__PURE__ */ new Set();
57640
+ for (const params of paramsList) {
57641
+ const scopeId = params.scopeId ?? `scope-${clock().replace(/[^0-9]/gu, "")}-${Math.floor(Math.random() * 1e6)}`;
57642
+ const anchor = params.anchor.kind === "range" ? { from: params.anchor.from, to: params.anchor.to } : null;
57643
+ if (!anchor) {
57644
+ results.push({ scopeId, anchor: params.anchor });
57645
+ continue;
57646
+ }
57647
+ const callerAssoc = params.anchor.kind === "range" ? params.anchor.assoc : { start: -1, end: 1 };
57648
+ const plantResult = insertScopeMarkers(nextDocument, {
57649
+ scopeId,
57650
+ from: anchor.from,
57651
+ to: anchor.to
57652
+ });
57653
+ if (plantResult.status !== "planted") {
57654
+ results.push(
57655
+ createPlantFailureResult({
57656
+ scopeId,
57657
+ anchor,
57658
+ assoc: callerAssoc,
57659
+ plantResult
57660
+ })
57661
+ );
57662
+ continue;
57663
+ }
57664
+ nextDocument = plantResult.document;
57665
+ documentChanged = true;
57666
+ const publicAnchor = {
57667
+ kind: "range",
57668
+ from: plantResult.plantedRange.from,
57669
+ to: plantResult.plantedRange.to,
57670
+ assoc: callerAssoc
57671
+ };
57672
+ newScopeIds.add(scopeId);
57673
+ scopesToAdd.push(buildWorkflowScope({ params, scopeId, publicAnchor }));
57674
+ const entry = buildWorkflowMetadataEntry({ params, scopeId, publicAnchor });
57675
+ if (entry) metadataEntriesToAdd.push(entry);
57676
+ results.push({ scopeId, anchor: publicAnchor });
57677
+ }
57678
+ if (documentChanged) {
57679
+ deps.dispatch({
57680
+ type: "document.replace",
57681
+ document: nextDocument,
57682
+ mapping: createScopeMarkerMutationMapping(),
57683
+ origin: { source: "api", at: clock() }
57684
+ });
57685
+ }
57686
+ if (scopesToAdd.length > 0) {
57687
+ const currentOverlay = overlayStore.getOverlay() ?? {
57688
+ overlayVersion: "workflow-overlay/1",
57689
+ scopes: []
57690
+ };
57691
+ const existingScopes = currentOverlay.scopes.filter(
57692
+ (existing) => !newScopeIds.has(existing.scopeId)
57693
+ );
57694
+ deps.dispatch({
57695
+ type: "workflow.set-overlay",
57696
+ overlay: { ...currentOverlay, scopes: [...existingScopes, ...scopesToAdd] },
57697
+ origin: { source: "api", at: clock() }
57698
+ });
57699
+ }
57700
+ if (metadataEntriesToAdd.length > 0) {
57701
+ const priorEntries = overlayStore.getMetadataEntries();
57702
+ deps.dispatch({
57703
+ type: "workflow.set-metadata-entries",
57704
+ entries: [...priorEntries, ...metadataEntriesToAdd],
57705
+ origin: { source: "api", at: clock() }
57706
+ });
57707
+ }
57708
+ return results;
57709
+ }
57318
57710
  function removeScope(scopeId) {
57319
57711
  const overlay = overlayStore.getOverlay();
57320
57712
  if (overlay) {
@@ -57332,6 +57724,7 @@ function createWorkflowCoordinator(deps) {
57332
57724
  deps.dispatch({
57333
57725
  type: "document.replace",
57334
57726
  document: nextDocument,
57727
+ mapping: createScopeMarkerMutationMapping(),
57335
57728
  origin: { source: "api", at: clock() }
57336
57729
  });
57337
57730
  }
@@ -57725,6 +58118,7 @@ function createWorkflowCoordinator(deps) {
57725
58118
  }
57726
58119
  return {
57727
58120
  addScope,
58121
+ addScopes,
57728
58122
  removeScope,
57729
58123
  addInvisibleScope,
57730
58124
  setScopeVisibility,
@@ -69706,8 +70100,8 @@ function resolveEditableTextTarget(input) {
69706
70100
  `Editable target ref is malformed: ${shapeIssues[0]?.path ?? "$"}.`
69707
70101
  );
69708
70102
  }
69709
- const activeStoryKey = input.activeStoryKey ?? "main";
69710
- if (input.target.storyKey !== activeStoryKey) {
70103
+ const activeStoryKey2 = input.activeStoryKey ?? "main";
70104
+ if (input.target.storyKey !== activeStoryKey2) {
69711
70105
  return reject(
69712
70106
  "editable_target_wrong_story",
69713
70107
  "Editable target ref does not belong to the active story."
@@ -69803,8 +70197,8 @@ function resolveEditableCommandTarget(input) {
69803
70197
  `Editable target ref is malformed: ${shapeIssues[0]?.path ?? "$"}.`
69804
70198
  );
69805
70199
  }
69806
- const activeStoryKey = input.activeStoryKey ?? input.target.storyKey;
69807
- if (input.target.storyKey !== activeStoryKey) {
70200
+ const activeStoryKey2 = input.activeStoryKey ?? input.target.storyKey;
70201
+ if (input.target.storyKey !== activeStoryKey2) {
69808
70202
  return rejectCommand(
69809
70203
  "editable_target_wrong_story",
69810
70204
  "Editable target ref does not belong to the active story."
@@ -70219,8 +70613,8 @@ function resolveEditableTableStructureTarget(input) {
70219
70613
  `Editable target ref is malformed: ${shapeIssues[0]?.path ?? "$"}.`
70220
70614
  );
70221
70615
  }
70222
- const activeStoryKey = input.activeStoryKey ?? input.target.storyKey;
70223
- if (input.target.storyKey !== activeStoryKey) {
70616
+ const activeStoryKey2 = input.activeStoryKey ?? input.target.storyKey;
70617
+ if (input.target.storyKey !== activeStoryKey2) {
70224
70618
  return reject2(
70225
70619
  "editable_target_wrong_story",
70226
70620
  "Editable target ref does not belong to the active story."
@@ -70555,6 +70949,36 @@ function createDocumentRuntime(options) {
70555
70949
  let viewportBlockRanges = null;
70556
70950
  let viewportRangesKey = serializeViewportRanges(viewportBlockRanges);
70557
70951
  let viewportBlocksPerPageEstimate = null;
70952
+ let fullSurfaceWarmupScheduled = false;
70953
+ let fullSurfaceWarmupCompleted = false;
70954
+ function scheduleFullSurfaceWarmupAfterCull() {
70955
+ if (fullSurfaceWarmupScheduled || fullSurfaceWarmupCompleted) return;
70956
+ fullSurfaceWarmupScheduled = true;
70957
+ perfCounters.increment("surface.fullSurfaceWarmup.scheduled");
70958
+ runOnIdle(() => {
70959
+ fullSurfaceWarmupScheduled = false;
70960
+ if (cachedFullSurface) {
70961
+ perfCounters.increment("surface.fullSurfaceWarmup.alreadyCached");
70962
+ fullSurfaceWarmupCompleted = true;
70963
+ return;
70964
+ }
70965
+ const t0 = performance.now();
70966
+ try {
70967
+ getCachedFullSurface(state.document, activeStory);
70968
+ fullSurfaceWarmupCompleted = true;
70969
+ perfCounters.increment("surface.fullSurfaceWarmup.committed");
70970
+ } catch (error) {
70971
+ perfCounters.increment("surface.fullSurfaceWarmup.failed");
70972
+ fullSurfaceWarmupCompleted = false;
70973
+ void error;
70974
+ } finally {
70975
+ perfCounters.increment(
70976
+ "surface.fullSurfaceWarmup.us",
70977
+ Math.round((performance.now() - t0) * 1e3)
70978
+ );
70979
+ }
70980
+ });
70981
+ }
70558
70982
  const getRuntimeForLayoutFacet = () => {
70559
70983
  if (!runtimeRef) {
70560
70984
  throw new Error("Document runtime viewport methods are not initialized");
@@ -70747,6 +71171,15 @@ function createDocumentRuntime(options) {
70747
71171
  let cachedSurface;
70748
71172
  let cachedFullSurface;
70749
71173
  const editableTargetBlockCache = createEditableTargetBlockCache();
71174
+ let paragraphCascadeCache = /* @__PURE__ */ new WeakMap();
71175
+ let paragraphCascadeCacheStylesRef = null;
71176
+ function ensureParagraphCascadeCacheForStyles(nextStyles) {
71177
+ if (paragraphCascadeCacheStylesRef !== nextStyles) {
71178
+ paragraphCascadeCache = /* @__PURE__ */ new WeakMap();
71179
+ paragraphCascadeCacheStylesRef = nextStyles;
71180
+ }
71181
+ return paragraphCascadeCache;
71182
+ }
70750
71183
  let cachedEditableTargetMap = null;
70751
71184
  function getEditableTargetsByBlockPath(document2) {
70752
71185
  if (cachedEditableTargetMap !== null && cachedEditableTargetMap.document === document2) {
@@ -70796,10 +71229,11 @@ function createDocumentRuntime(options) {
70796
71229
  if (cached) {
70797
71230
  return cached;
70798
71231
  }
70799
- const activeStoryKey = storyTargetKey(nextActiveStory);
71232
+ const activeStoryKey2 = storyTargetKey(nextActiveStory);
70800
71233
  const snapshot = createEditorSurfaceSnapshot(document2, state.selection, nextActiveStory, {
70801
71234
  viewportBlockRanges: null,
70802
71235
  editableTargetsByBlockPath: getEditableTargetsByBlockPath(document2),
71236
+ paragraphCascadeCache: ensureParagraphCascadeCacheForStyles(document2.styles),
70803
71237
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
70804
71238
  });
70805
71239
  recordPerfSample("snapshot.surface");
@@ -70813,33 +71247,34 @@ function createDocumentRuntime(options) {
70813
71247
  preservation: document2.preservation,
70814
71248
  review: document2.review,
70815
71249
  effectiveMarkupModeProvider,
70816
- activeStoryKey,
71250
+ activeStoryKey: activeStoryKey2,
70817
71251
  snapshot
70818
71252
  };
70819
71253
  return snapshot;
70820
71254
  }
70821
71255
  function getReusableCachedFullSurface(document2, nextActiveStory) {
70822
- const activeStoryKey = storyTargetKey(nextActiveStory);
70823
- if (cachedFullSurface && cachedFullSurface.content === document2.content && cachedFullSurface.subParts === document2.subParts && cachedFullSurface.styles === document2.styles && cachedFullSurface.numbering === document2.numbering && cachedFullSurface.media === document2.media && cachedFullSurface.preservation === document2.preservation && cachedFullSurface.review === document2.review && cachedFullSurface.effectiveMarkupModeProvider === effectiveMarkupModeProvider && cachedFullSurface.activeStoryKey === activeStoryKey) {
71256
+ const activeStoryKey2 = storyTargetKey(nextActiveStory);
71257
+ if (cachedFullSurface && cachedFullSurface.content === document2.content && cachedFullSurface.subParts === document2.subParts && cachedFullSurface.styles === document2.styles && cachedFullSurface.numbering === document2.numbering && cachedFullSurface.media === document2.media && cachedFullSurface.preservation === document2.preservation && cachedFullSurface.review === document2.review && cachedFullSurface.effectiveMarkupModeProvider === effectiveMarkupModeProvider && cachedFullSurface.activeStoryKey === activeStoryKey2) {
70824
71258
  return cachedFullSurface.snapshot;
70825
71259
  }
70826
71260
  return void 0;
70827
71261
  }
70828
71262
  function getCachedSurface(document2, nextActiveStory, options2 = {}) {
70829
- const activeStoryKey = storyTargetKey(nextActiveStory);
71263
+ const activeStoryKey2 = storyTargetKey(nextActiveStory);
70830
71264
  const surfaceViewportRanges = "viewportBlockRangesOverride" in options2 ? options2.viewportBlockRangesOverride ?? null : viewportBlockRanges;
70831
71265
  const surfaceViewportRangesKey = "viewportBlockRangesOverride" in options2 ? serializeViewportRanges(surfaceViewportRanges) : viewportRangesKey;
70832
71266
  const surfaceCacheKey = options2.enrichCulledPlaceholders === false ? `${surfaceViewportRangesKey}|raw-placeholders` : surfaceViewportRangesKey;
70833
- if (cachedSurface && cachedSurface.content === document2.content && cachedSurface.subParts === document2.subParts && cachedSurface.styles === document2.styles && cachedSurface.numbering === document2.numbering && cachedSurface.media === document2.media && cachedSurface.preservation === document2.preservation && cachedSurface.review === document2.review && cachedSurface.effectiveMarkupModeProvider === effectiveMarkupModeProvider && cachedSurface.activeStoryKey === activeStoryKey && cachedSurface.viewportRangesKey === surfaceCacheKey) {
71267
+ if (cachedSurface && cachedSurface.content === document2.content && cachedSurface.subParts === document2.subParts && cachedSurface.styles === document2.styles && cachedSurface.numbering === document2.numbering && cachedSurface.media === document2.media && cachedSurface.preservation === document2.preservation && cachedSurface.review === document2.review && cachedSurface.effectiveMarkupModeProvider === effectiveMarkupModeProvider && cachedSurface.activeStoryKey === activeStoryKey2 && cachedSurface.viewportRangesKey === surfaceCacheKey) {
70834
71268
  return cachedSurface.snapshot;
70835
71269
  }
70836
71270
  const snapshot = createEditorSurfaceSnapshot(document2, state.selection, nextActiveStory, {
70837
71271
  viewportBlockRanges: surfaceViewportRanges,
70838
71272
  editableTargetsByBlockPath: options2.editableTargetsByBlockPathOverride ?? getEditableTargetsByBlockPathForRanges(
70839
71273
  document2,
70840
- activeStoryKey,
71274
+ activeStoryKey2,
70841
71275
  surfaceViewportRanges
70842
71276
  ),
71277
+ paragraphCascadeCache: ensureParagraphCascadeCacheForStyles(document2.styles),
70843
71278
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
70844
71279
  });
70845
71280
  recordPerfSample("snapshot.surface");
@@ -70859,7 +71294,7 @@ function createDocumentRuntime(options) {
70859
71294
  preservation: document2.preservation,
70860
71295
  review: document2.review,
70861
71296
  effectiveMarkupModeProvider,
70862
- activeStoryKey,
71297
+ activeStoryKey: activeStoryKey2,
70863
71298
  snapshot: enrichedSnapshot
70864
71299
  };
70865
71300
  }
@@ -70872,11 +71307,11 @@ function createDocumentRuntime(options) {
70872
71307
  preservation: document2.preservation,
70873
71308
  review: document2.review,
70874
71309
  effectiveMarkupModeProvider,
70875
- activeStoryKey,
71310
+ activeStoryKey: activeStoryKey2,
70876
71311
  viewportRangesKey: surfaceCacheKey,
70877
71312
  snapshot: enrichedSnapshot
70878
71313
  };
70879
- cachedSurfaceFingerprint = `${activeStoryKey}|${surfaceCacheKey}|${String(state.selection.anchor)}:${String(state.selection.head)}`;
71314
+ cachedSurfaceFingerprint = `${activeStoryKey2}|${surfaceCacheKey}|${String(state.selection.anchor)}:${String(state.selection.head)}`;
70880
71315
  return enrichedSnapshot;
70881
71316
  }
70882
71317
  function getSelectionCorridorViewportRanges(previousSurface) {
@@ -70907,7 +71342,7 @@ function createDocumentRuntime(options) {
70907
71342
  return -1;
70908
71343
  }
70909
71344
  function cachePatchedLocalTextSurface(surface, fullSurfaceForCache) {
70910
- const activeStoryKey = storyTargetKey(activeStory);
71345
+ const activeStoryKey2 = storyTargetKey(activeStory);
70911
71346
  const rangesKey = serializeViewportRanges(surface.viewportBlockRanges);
70912
71347
  cachedSurface = {
70913
71348
  content: state.document.content,
@@ -70918,7 +71353,7 @@ function createDocumentRuntime(options) {
70918
71353
  preservation: state.document.preservation,
70919
71354
  review: state.document.review,
70920
71355
  effectiveMarkupModeProvider,
70921
- activeStoryKey,
71356
+ activeStoryKey: activeStoryKey2,
70922
71357
  viewportRangesKey: rangesKey,
70923
71358
  snapshot: surface
70924
71359
  };
@@ -70933,11 +71368,11 @@ function createDocumentRuntime(options) {
70933
71368
  preservation: state.document.preservation,
70934
71369
  review: state.document.review,
70935
71370
  effectiveMarkupModeProvider,
70936
- activeStoryKey,
71371
+ activeStoryKey: activeStoryKey2,
70937
71372
  snapshot: fullSurface
70938
71373
  };
70939
71374
  }
70940
- cachedSurfaceFingerprint = `${activeStoryKey}|${rangesKey}|${String(state.selection.anchor)}:${String(state.selection.head)}`;
71375
+ cachedSurfaceFingerprint = `${activeStoryKey2}|${rangesKey}|${String(state.selection.anchor)}:${String(state.selection.head)}`;
70941
71376
  }
70942
71377
  function createLocalTextCorridorSurfaceFromFullSurface(fullSurface) {
70943
71378
  const ranges = getSelectionCorridorViewportRanges(fullSurface);
@@ -71051,7 +71486,17 @@ function createDocumentRuntime(options) {
71051
71486
  }
71052
71487
  }
71053
71488
  function tryPatchNestedLocalTextSurface(previousSurface, editFrom, editTo, insertedText) {
71054
- const shiftBudget = estimateLocalTextPatchShiftBudget(previousSurface.blocks, 0);
71489
+ const containerIndex = previousSurface.blocks.findIndex(
71490
+ (block) => editFrom >= block.from && editTo <= block.to
71491
+ );
71492
+ if (containerIndex < 0) {
71493
+ perfCounters.increment("surface.localText.patchMiss");
71494
+ return null;
71495
+ }
71496
+ const shiftBudget = estimateLocalTextPatchShiftBudget(
71497
+ previousSurface.blocks,
71498
+ containerIndex + 1
71499
+ );
71055
71500
  perfCounters.increment("surface.localText.shiftedBlocks", shiftBudget.shiftedBlocks);
71056
71501
  perfCounters.increment("surface.localText.shiftedNodes", shiftBudget.shiftedNodes);
71057
71502
  if (!shiftBudget.withinBudget) {
@@ -71131,19 +71576,9 @@ function createDocumentRuntime(options) {
71131
71576
  for (let index = startIndex; index < blocks.length; index += 1) {
71132
71577
  const shiftedBlockNodes = countSurfaceShiftNodesUpTo(
71133
71578
  blocks[index],
71134
- Math.min(
71135
- policy.maxShiftedNodesPerBlock,
71136
- policy.maxShiftedSurfaceNodes - shiftedNodes
71137
- ) + 1
71579
+ policy.maxShiftedSurfaceNodes - shiftedNodes + 1
71138
71580
  );
71139
71581
  shiftedNodes += shiftedBlockNodes;
71140
- if (shiftedBlockNodes > policy.maxShiftedNodesPerBlock) {
71141
- return {
71142
- shiftedBlocks,
71143
- shiftedNodes,
71144
- withinBudget: false
71145
- };
71146
- }
71147
71582
  if (shiftedNodes > policy.maxShiftedSurfaceNodes) {
71148
71583
  return {
71149
71584
  shiftedBlocks,
@@ -71332,7 +71767,7 @@ function createDocumentRuntime(options) {
71332
71767
  return snapshot.suggestions.find((suggestion) => suggestion.changeIds.includes(changeId));
71333
71768
  }
71334
71769
  function getCachedDocumentNavigationSnapshot(nextState, nextActiveStory) {
71335
- const activeStoryKey = storyTargetKey(nextActiveStory);
71770
+ const activeStoryKey2 = storyTargetKey(nextActiveStory);
71336
71771
  const buildSnapshot = () => layoutEngine.getNavigationSnapshot(
71337
71772
  {
71338
71773
  document: nextState.document,
@@ -71345,7 +71780,7 @@ function createDocumentRuntime(options) {
71345
71780
  nextState.selection,
71346
71781
  nextActiveStory
71347
71782
  );
71348
- if (cachedNavigation && cachedNavigation.document === nextState.document && cachedNavigation.activeStoryKey === activeStoryKey && cachedNavigation.workspaceMode === viewState.workspaceMode && cachedNavigation.zoomLevel === viewState.zoomLevel) {
71783
+ if (cachedNavigation && cachedNavigation.document === nextState.document && cachedNavigation.activeStoryKey === activeStoryKey2 && cachedNavigation.workspaceMode === viewState.workspaceMode && cachedNavigation.zoomLevel === viewState.zoomLevel) {
71349
71784
  if (cachedNavigation.selectionHead === nextState.selection.head) {
71350
71785
  return cachedNavigation.snapshot;
71351
71786
  }
@@ -71353,7 +71788,7 @@ function createDocumentRuntime(options) {
71353
71788
  if (snapshot2.activePageIndex === cachedNavigation.snapshot.activePageIndex && snapshot2.activeSectionIndex === cachedNavigation.snapshot.activeSectionIndex) {
71354
71789
  cachedNavigation = {
71355
71790
  document: nextState.document,
71356
- activeStoryKey,
71791
+ activeStoryKey: activeStoryKey2,
71357
71792
  workspaceMode: viewState.workspaceMode,
71358
71793
  zoomLevel: viewState.zoomLevel,
71359
71794
  selectionHead: nextState.selection.head,
@@ -71363,7 +71798,7 @@ function createDocumentRuntime(options) {
71363
71798
  }
71364
71799
  cachedNavigation = {
71365
71800
  document: nextState.document,
71366
- activeStoryKey,
71801
+ activeStoryKey: activeStoryKey2,
71367
71802
  workspaceMode: viewState.workspaceMode,
71368
71803
  zoomLevel: viewState.zoomLevel,
71369
71804
  selectionHead: nextState.selection.head,
@@ -71376,7 +71811,7 @@ function createDocumentRuntime(options) {
71376
71811
  incrementInvalidationCounter("runtime.snapshot.navigationMisses");
71377
71812
  cachedNavigation = {
71378
71813
  document: nextState.document,
71379
- activeStoryKey,
71814
+ activeStoryKey: activeStoryKey2,
71380
71815
  workspaceMode: viewState.workspaceMode,
71381
71816
  zoomLevel: viewState.zoomLevel,
71382
71817
  selectionHead: nextState.selection.head,
@@ -71394,18 +71829,18 @@ function createDocumentRuntime(options) {
71394
71829
  return storyTargetKey(nextActiveStory);
71395
71830
  }
71396
71831
  function getCachedPageLayoutSnapshot(nextState, nextActiveStory) {
71397
- const activeStoryKey = storyTargetKey(nextActiveStory);
71832
+ const activeStoryKey2 = storyTargetKey(nextActiveStory);
71398
71833
  const activeSectionIndex = resolvePageLayoutActiveSectionIndex(
71399
71834
  nextState,
71400
71835
  nextActiveStory
71401
71836
  );
71402
- if (cachedPageLayout && cachedPageLayout.revisionToken === nextState.revisionToken && cachedPageLayout.activeStoryKey === activeStoryKey && cachedPageLayout.activeSectionIndex === activeSectionIndex) {
71837
+ if (cachedPageLayout && cachedPageLayout.revisionToken === nextState.revisionToken && cachedPageLayout.activeStoryKey === activeStoryKey2 && cachedPageLayout.activeSectionIndex === activeSectionIndex) {
71403
71838
  return cachedPageLayout.snapshot;
71404
71839
  }
71405
71840
  const snapshot = derivePageLayoutSnapshot(nextState, nextActiveStory, storySelections);
71406
71841
  cachedPageLayout = {
71407
71842
  revisionToken: nextState.revisionToken,
71408
- activeStoryKey,
71843
+ activeStoryKey: activeStoryKey2,
71409
71844
  activeSectionIndex,
71410
71845
  snapshot
71411
71846
  };
@@ -71475,8 +71910,8 @@ function createDocumentRuntime(options) {
71475
71910
  if (activeStory.kind === "main") {
71476
71911
  return surface.blocks;
71477
71912
  }
71478
- const activeStoryKey = storyTargetKey(activeStory);
71479
- return surface.secondaryStories.find((story) => storyTargetKey(story.target) === activeStoryKey)?.blocks ?? null;
71913
+ const activeStoryKey2 = storyTargetKey(activeStory);
71914
+ return surface.secondaryStories.find((story) => storyTargetKey(story.target) === activeStoryKey2)?.blocks ?? null;
71480
71915
  }
71481
71916
  function findSurfaceOpaqueTargetIntersectingRange(blocks, range) {
71482
71917
  for (const block of blocks) {
@@ -71651,12 +72086,12 @@ function createDocumentRuntime(options) {
71651
72086
  };
71652
72087
  }
71653
72088
  function getCachedRuntimeContextAnalytics(query) {
71654
- const activeStoryKey = storyTargetKey(activeStory);
72089
+ const activeStoryKey2 = storyTargetKey(activeStory);
71655
72090
  const queryKey = getRuntimeContextAnalyticsQueryKey(query);
71656
72091
  const cachedEntry = cachedContextAnalyticsSnapshots.get(queryKey);
71657
72092
  const effectiveScopeKind = query?.scopeKind ?? "selection";
71658
72093
  const selectionCacheKey = effectiveScopeKind === "selection" ? state.selection : null;
71659
- if (cachedEntry && cachedEntry.revisionToken === state.revisionToken && cachedEntry.activeStoryKey === activeStoryKey && cachedEntry.selection === selectionCacheKey && cachedEntry.readOnly === state.readOnly && cachedEntry.documentMode === viewState.documentMode && cachedEntry.workflowOverlay === overlayStore.getOverlay() && cachedEntry.protectionSnapshot === protectionSnapshot && cachedEntry.warnings === state.warnings && cachedEntry.fatalError === state.fatalError) {
72094
+ if (cachedEntry && cachedEntry.revisionToken === state.revisionToken && cachedEntry.activeStoryKey === activeStoryKey2 && cachedEntry.selection === selectionCacheKey && cachedEntry.readOnly === state.readOnly && cachedEntry.documentMode === viewState.documentMode && cachedEntry.workflowOverlay === overlayStore.getOverlay() && cachedEntry.protectionSnapshot === protectionSnapshot && cachedEntry.warnings === state.warnings && cachedEntry.fatalError === state.fatalError) {
71660
72095
  return cachedEntry.snapshot;
71661
72096
  }
71662
72097
  const tWf = performance.now();
@@ -71713,7 +72148,7 @@ function createDocumentRuntime(options) {
71713
72148
  perfCounters.increment("ctxa.build.us", Math.round((performance.now() - tBuild) * 1e3));
71714
72149
  cachedContextAnalyticsSnapshots.set(queryKey, {
71715
72150
  revisionToken: state.revisionToken,
71716
- activeStoryKey,
72151
+ activeStoryKey: activeStoryKey2,
71717
72152
  // L7 Phase 1.6: store the selectionCacheKey we tested against, so the
71718
72153
  // same scopeKind invariant applies to future reads.
71719
72154
  selection: selectionCacheKey,
@@ -71815,6 +72250,9 @@ function createDocumentRuntime(options) {
71815
72250
  viewportBlockRangesOverride: firstSurfaceViewportBlockRanges
71816
72251
  }) : getCachedSurface(state.document, activeStory)
71817
72252
  );
72253
+ if (firstSurfaceViewportBlockRanges) {
72254
+ scheduleFullSurfaceWarmupAfterCull();
72255
+ }
71818
72256
  const snapshot = {
71819
72257
  documentId: state.documentId,
71820
72258
  sessionId: state.sessionId,
@@ -71908,7 +72346,7 @@ function createDocumentRuntime(options) {
71908
72346
  }
71909
72347
  let cachedSurfaceFingerprint = null;
71910
72348
  function refreshSurfaceOnly(options2 = {}) {
71911
- const activeStoryKey = storyTargetKey(activeStory);
72349
+ const activeStoryKey2 = storyTargetKey(activeStory);
71912
72350
  if (options2.forceProjection) {
71913
72351
  cachedFullSurface = void 0;
71914
72352
  }
@@ -71925,9 +72363,12 @@ function createDocumentRuntime(options) {
71925
72363
  viewportBlockRanges,
71926
72364
  editableTargetsByBlockPath: getEditableTargetsByBlockPathForRanges(
71927
72365
  state.document,
71928
- activeStoryKey,
72366
+ activeStoryKey2,
71929
72367
  viewportBlockRanges
71930
72368
  ),
72369
+ paragraphCascadeCache: ensureParagraphCascadeCacheForStyles(
72370
+ state.document.styles
72371
+ ),
71931
72372
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
71932
72373
  }
71933
72374
  );
@@ -71952,7 +72393,7 @@ function createDocumentRuntime(options) {
71952
72393
  preservation: state.document.preservation,
71953
72394
  review: state.document.review,
71954
72395
  effectiveMarkupModeProvider,
71955
- activeStoryKey,
72396
+ activeStoryKey: activeStoryKey2,
71956
72397
  snapshot: newSurface
71957
72398
  };
71958
72399
  }
@@ -71967,7 +72408,7 @@ function createDocumentRuntime(options) {
71967
72408
  preservation: state.document.preservation,
71968
72409
  review: state.document.review,
71969
72410
  effectiveMarkupModeProvider,
71970
- activeStoryKey,
72411
+ activeStoryKey: activeStoryKey2,
71971
72412
  viewportRangesKey,
71972
72413
  snapshot: newSurface
71973
72414
  };
@@ -72028,10 +72469,10 @@ function createDocumentRuntime(options) {
72028
72469
  return true;
72029
72470
  }
72030
72471
  function getCachedViewStateSnapshot() {
72031
- const activeStoryKey = storyTargetKey(activeStory);
72472
+ const activeStoryKey2 = storyTargetKey(activeStory);
72032
72473
  const surface = cachedRenderSnapshot.surface;
72033
72474
  const pageLayout = cachedRenderSnapshot.pageLayout;
72034
- if (cachedViewStateSnapshot && cachedViewStateSnapshot.activeStoryKey === activeStoryKey && cachedViewStateSnapshot.selection === state.selection && cachedViewStateSnapshot.viewStateRef === viewState && cachedViewStateSnapshot.surface === surface && cachedViewStateSnapshot.pageLayout === pageLayout && cachedViewStateSnapshot.numbering === state.document.numbering) {
72475
+ if (cachedViewStateSnapshot && cachedViewStateSnapshot.activeStoryKey === activeStoryKey2 && cachedViewStateSnapshot.selection === state.selection && cachedViewStateSnapshot.viewStateRef === viewState && cachedViewStateSnapshot.surface === surface && cachedViewStateSnapshot.pageLayout === pageLayout && cachedViewStateSnapshot.numbering === state.document.numbering) {
72035
72476
  return cachedViewStateSnapshot.snapshot;
72036
72477
  }
72037
72478
  const mainSurface = activeStory.kind === "main" ? surface : getCachedSurface(state.document, MAIN_STORY_TARGET);
@@ -72045,7 +72486,7 @@ function createDocumentRuntime(options) {
72045
72486
  state.document.numbering
72046
72487
  );
72047
72488
  cachedViewStateSnapshot = {
72048
- activeStoryKey,
72489
+ activeStoryKey: activeStoryKey2,
72049
72490
  selection: state.selection,
72050
72491
  viewStateRef: viewState,
72051
72492
  surface,
@@ -72579,6 +73020,17 @@ function createDocumentRuntime(options) {
72579
73020
  };
72580
73021
  resolvedReplayTextTarget = prepared.textTarget;
72581
73022
  } else {
73023
+ const listBoundaryJoinCommand = createListItemBoundaryJoinReplayCommand({
73024
+ command,
73025
+ document: replayState.document,
73026
+ selection: replayState.selection,
73027
+ surface: replaySnapshot.surface?.blocks ?? [],
73028
+ storyTarget: replayStory,
73029
+ timestamp: context.timestamp
73030
+ });
73031
+ if (listBoundaryJoinCommand) {
73032
+ executableCommand = listBoundaryJoinCommand;
73033
+ }
72582
73034
  const selectedListItemDeleteCommand = createSelectedListItemDeleteReplayCommand({
72583
73035
  command,
72584
73036
  document: replayState.document,
@@ -72736,6 +73188,17 @@ function createDocumentRuntime(options) {
72736
73188
  };
72737
73189
  resolvedReplayTextTarget = prepared.textTarget;
72738
73190
  } else {
73191
+ const listBoundaryJoinCommand = createListItemBoundaryJoinReplayCommand({
73192
+ command,
73193
+ document: stateForCommand.document,
73194
+ selection: stateForCommand.selection,
73195
+ surface: snapshotForCommand.surface?.blocks ?? [],
73196
+ storyTarget: replayStory,
73197
+ timestamp: context.timestamp
73198
+ });
73199
+ if (listBoundaryJoinCommand) {
73200
+ executableCommand = listBoundaryJoinCommand;
73201
+ }
72739
73202
  const selectedListItemDeleteCommand = createSelectedListItemDeleteReplayCommand({
72740
73203
  command,
72741
73204
  document: stateForCommand.document,
@@ -73045,8 +73508,8 @@ function createDocumentRuntime(options) {
73045
73508
  applyScopeReplacement(plan) {
73046
73509
  const resolveEditableTargetHint = (hint) => {
73047
73510
  if (!hint) return void 0;
73048
- const activeStoryKey = storyTargetKey(activeStory);
73049
- if (hint.storyKey !== activeStoryKey) return null;
73511
+ const activeStoryKey2 = storyTargetKey(activeStory);
73512
+ if (hint.storyKey !== activeStoryKey2) return null;
73050
73513
  const currentTargets = collectEditableTargetRefs(
73051
73514
  state.document,
73052
73515
  editableTargetBlockCache
@@ -73065,7 +73528,7 @@ function createDocumentRuntime(options) {
73065
73528
  document: state.document,
73066
73529
  surface: cachedRenderSnapshot.surface?.blocks ?? [],
73067
73530
  target,
73068
- activeStoryKey,
73531
+ activeStoryKey: activeStoryKey2,
73069
73532
  editableTargetCache: editableTargetBlockCache
73070
73533
  });
73071
73534
  if (resolved.kind === "rejected") {
@@ -73765,6 +74228,9 @@ function createDocumentRuntime(options) {
73765
74228
  addScope(params) {
73766
74229
  return workflowCoordinator.addScope(params);
73767
74230
  },
74231
+ addScopes(params) {
74232
+ return workflowCoordinator.addScopes(params);
74233
+ },
73768
74234
  getScope(scopeId) {
73769
74235
  return workflowCoordinator.getScope(scopeId);
73770
74236
  },
@@ -74748,6 +75214,9 @@ function createDocumentRuntime(options) {
74748
75214
  if (transaction.mapping.metadata?.scopeTagTouches) return false;
74749
75215
  return getLocalTextPatchMetadata(transaction.mapping) !== null;
74750
75216
  }
75217
+ function isLayoutNeutralScopeMarkerCommit(previous, next, transaction) {
75218
+ return transaction.markDirty && previous.document !== next.document && transaction.mapping.steps.length === 0 && transaction.mapping.metadata?.layoutNeutralScopeMarkers === true;
75219
+ }
74751
75220
  function applyTransactionToState(transaction, options2 = {}) {
74752
75221
  const effects = transaction.effects;
74753
75222
  const selectionUnchanged = transaction.nextState.selection === state.selection;
@@ -74776,6 +75245,11 @@ function createDocumentRuntime(options) {
74776
75245
  transaction,
74777
75246
  transaction.effects
74778
75247
  );
75248
+ const layoutNeutralScopeMarkerCommit = isLayoutNeutralScopeMarkerCommit(
75249
+ previous,
75250
+ state,
75251
+ transaction
75252
+ );
74779
75253
  perfCounters.increment("commit.refreshClassify.us", Math.round((performance.now() - tClassify0) * 1e3));
74780
75254
  const tOverlay0 = performance.now();
74781
75255
  const skipOverlaySync = useLocalTextCommitSnapshot && canSkipOverlaySyncForLocalText(transaction);
@@ -74824,9 +75298,12 @@ function createDocumentRuntime(options) {
74824
75298
  ...detachedWorkflowScopeWarnings.cleared
74825
75299
  ]
74826
75300
  };
74827
- if (!useLocalTextCommitSnapshot && transaction.markDirty && previous.document !== state.document) {
75301
+ if (!useLocalTextCommitSnapshot && !layoutNeutralScopeMarkerCommit && transaction.markDirty && previous.document !== state.document) {
74828
75302
  applyViewportRanges(getSelectionCorridorViewportRanges(cachedRenderSnapshot.surface));
74829
75303
  }
75304
+ if (layoutNeutralScopeMarkerCommit && viewportBlockRanges !== null) {
75305
+ getCachedFullSurface(state.document, activeStory);
75306
+ }
74830
75307
  const tValidation0 = performance.now();
74831
75308
  const patchSourceSurface = getReusableCachedFullSurface(previous.document, activeStory) ?? cachedRenderSnapshot.surface;
74832
75309
  const patchedFullLocalTextSurface = useLocalTextCommitSnapshot ? tryPatchLocalTextSurface(patchSourceSurface, transaction.mapping) : null;
@@ -75195,15 +75672,49 @@ function createDocumentRuntime(options) {
75195
75672
  const preSelection = selection;
75196
75673
  const preActiveStory = activeStory;
75197
75674
  const priorDocument = state.document;
75675
+ const listBoundaryJoin = createListItemBoundaryJoinReplacement({
75676
+ command: commandForDispatch,
75677
+ document: state.document,
75678
+ editableTarget,
75679
+ selection,
75680
+ storyTarget: activeStory,
75681
+ targetResolution,
75682
+ timestamp
75683
+ });
75684
+ if (listBoundaryJoin && context.documentMode !== "suggesting") {
75685
+ const replacementCommand = {
75686
+ type: "document.replace",
75687
+ document: listBoundaryJoin.document,
75688
+ selection: listBoundaryJoin.selection,
75689
+ mapping: listBoundaryJoin.mapping,
75690
+ protectionSelection: selection,
75691
+ origin: commandForDispatch.origin
75692
+ };
75693
+ const transaction = executeEditorCommand(baseState, replacementCommand, context);
75694
+ commit(transaction);
75695
+ options.onCommandApplied?.(commandForDispatch, transaction, context, {
75696
+ preSelection,
75697
+ activeStory: preActiveStory,
75698
+ priorDocument
75699
+ });
75700
+ return completeDispatch(classifyAck({
75701
+ command: commandForDispatch,
75702
+ opId,
75703
+ priorState: baseState,
75704
+ transaction,
75705
+ newRevisionToken: state.revisionToken
75706
+ }));
75707
+ }
75198
75708
  const selectedListItemDelete = createSelectedListItemDeleteReplacement({
75199
75709
  command: commandForDispatch,
75200
75710
  document: state.document,
75201
75711
  editableTarget,
75202
75712
  selection,
75713
+ storyTarget: activeStory,
75203
75714
  targetResolution,
75204
75715
  timestamp
75205
75716
  });
75206
- if (selectedListItemDelete && activeStory.kind === "main" && context.documentMode !== "suggesting") {
75717
+ if (selectedListItemDelete && context.documentMode !== "suggesting") {
75207
75718
  const replacementCommand = {
75208
75719
  type: "document.replace",
75209
75720
  document: selectedListItemDelete.document,
@@ -75468,6 +75979,9 @@ function createDocumentRuntime(options) {
75468
75979
  });
75469
75980
  }
75470
75981
  function scheduleIdleContextAnalytics(callback) {
75982
+ runOnIdle(callback);
75983
+ }
75984
+ function runOnIdle(callback) {
75471
75985
  const requestIdle = globalThis.requestIdleCallback;
75472
75986
  if (typeof requestIdle === "function") {
75473
75987
  requestIdle(callback, { timeout: 250 });
@@ -78098,8 +78612,58 @@ function stripStoryTarget2(selection) {
78098
78612
  function isTopLevelMainStoryBlockPath(blockPath) {
78099
78613
  return typeof blockPath === "string" && /^main\/block\[\d+\]$/u.test(blockPath);
78100
78614
  }
78615
+ function createListItemBoundaryJoinReplacement(input) {
78616
+ const { command, document: document2, editableTarget, selection, storyTarget, targetResolution, timestamp } = input;
78617
+ const direction = listItemBoundaryJoinDirection(command, selection, targetResolution);
78618
+ if (!direction || editableTarget?.listAddress?.operationScope !== "list-text" || targetResolution?.kind !== "accepted") {
78619
+ return null;
78620
+ }
78621
+ const storyBlocks = getStoryBlocks(document2, storyTarget);
78622
+ const replacement = joinNumberedParagraphAtStoryPath(
78623
+ storyBlocks,
78624
+ editableTarget.blockPath,
78625
+ storyTarget,
78626
+ direction
78627
+ );
78628
+ if (!replacement) {
78629
+ return null;
78630
+ }
78631
+ const nextDocument = replaceStoryBlocks({
78632
+ ...document2,
78633
+ updatedAt: timestamp
78634
+ }, storyTarget, replacement.blocks);
78635
+ const deletedFrom = direction === "backward" ? Math.max(0, selection.anchor - 1) : selection.anchor;
78636
+ const deletedTo = direction === "backward" ? selection.anchor : selection.anchor + 1;
78637
+ const nextAnchor = direction === "backward" ? deletedFrom : selection.anchor;
78638
+ return {
78639
+ document: nextDocument,
78640
+ selection: createSelectionSnapshot(nextAnchor, nextAnchor),
78641
+ mapping: {
78642
+ steps: [{
78643
+ from: deletedFrom,
78644
+ to: deletedTo,
78645
+ insertSize: 0
78646
+ }],
78647
+ metadata: {
78648
+ invalidatesStructures: true
78649
+ }
78650
+ }
78651
+ };
78652
+ }
78653
+ function listItemBoundaryJoinDirection(command, selection, targetResolution) {
78654
+ if (selection.isCollapsed !== true || targetResolution?.kind !== "accepted") {
78655
+ return null;
78656
+ }
78657
+ if (command.type === "text.delete-backward" && selection.anchor === targetResolution.range.from) {
78658
+ return "backward";
78659
+ }
78660
+ if (command.type === "text.delete-forward" && selection.anchor === targetResolution.range.to) {
78661
+ return "forward";
78662
+ }
78663
+ return null;
78664
+ }
78101
78665
  function createSelectedListItemDeleteReplacement(input) {
78102
- const { command, document: document2, editableTarget, selection, targetResolution, timestamp } = input;
78666
+ const { command, document: document2, editableTarget, selection, storyTarget, targetResolution, timestamp } = input;
78103
78667
  if (command.type !== "text.delete-backward" && command.type !== "text.delete-forward") {
78104
78668
  return null;
78105
78669
  }
@@ -78111,20 +78675,19 @@ function createSelectedListItemDeleteReplacement(input) {
78111
78675
  if (selectionFrom !== targetResolution.range.from || selectionTo !== targetResolution.range.to) {
78112
78676
  return null;
78113
78677
  }
78114
- const root = document2.content;
78115
- const replacement = removeNumberedParagraphAtMainStoryPath(root.children, editableTarget.blockPath);
78678
+ const storyBlocks = getStoryBlocks(document2, storyTarget);
78679
+ const replacement = removeNumberedParagraphAtStoryPath(storyBlocks, editableTarget.blockPath, storyTarget);
78116
78680
  if (!replacement) {
78117
78681
  return null;
78118
78682
  }
78119
- const nextDocument = {
78683
+ const nextDocument = replaceStoryBlocks({
78120
78684
  ...document2,
78121
- updatedAt: timestamp,
78122
- content: {
78123
- ...root,
78124
- children: replacement.blocks
78125
- }
78126
- };
78127
- const nextStorySize = parseTextStory(nextDocument.content).size;
78685
+ updatedAt: timestamp
78686
+ }, storyTarget, replacement.blocks);
78687
+ const nextStorySize = parseTextStory({
78688
+ type: "doc",
78689
+ children: [...getStoryBlocks(nextDocument, storyTarget)]
78690
+ }).size;
78128
78691
  const nextAnchor = Math.min(selectionFrom, nextStorySize);
78129
78692
  return {
78130
78693
  document: nextDocument,
@@ -78141,11 +78704,157 @@ function createSelectedListItemDeleteReplacement(input) {
78141
78704
  }
78142
78705
  };
78143
78706
  }
78144
- function removeNumberedParagraphAtMainStoryPath(blocks, blockPath) {
78145
- const tokens = parseMainStoryBlockPathTokens(blockPath);
78707
+ function removeNumberedParagraphAtStoryPath(blocks, blockPath, storyTarget) {
78708
+ const tokens = parseStoryBlockPathTokens(blockPath, storyTarget);
78146
78709
  if (!tokens) return null;
78147
78710
  return removeNumberedParagraphFromBlocks(blocks, tokens);
78148
78711
  }
78712
+ function joinNumberedParagraphAtStoryPath(blocks, blockPath, storyTarget, direction) {
78713
+ const tokens = parseStoryBlockPathTokens(blockPath, storyTarget);
78714
+ if (!tokens) return null;
78715
+ return joinNumberedParagraphFromBlocks(blocks, tokens, direction);
78716
+ }
78717
+ function joinNumberedParagraphFromBlocks(blocks, tokens, direction) {
78718
+ const [token, ...rest] = tokens;
78719
+ if (!token || token.kind !== "block") return null;
78720
+ const block = blocks[token.index];
78721
+ if (!block) return null;
78722
+ if (rest.length === 0) {
78723
+ return joinAdjacentNumberedParagraphs(blocks, token.index, direction);
78724
+ }
78725
+ const next = rest[0];
78726
+ if (block.type === "table" && next?.kind === "row") {
78727
+ const updatedTable = joinNumberedParagraphInTable(block, rest, direction);
78728
+ if (!updatedTable) return null;
78729
+ return {
78730
+ blocks: [
78731
+ ...blocks.slice(0, token.index),
78732
+ updatedTable,
78733
+ ...blocks.slice(token.index + 1)
78734
+ ]
78735
+ };
78736
+ }
78737
+ if ((block.type === "sdt" || block.type === "custom_xml") && next?.kind === "block") {
78738
+ const updatedChildren = joinNumberedParagraphFromBlocks(block.children, rest, direction);
78739
+ if (!updatedChildren) return null;
78740
+ return {
78741
+ blocks: [
78742
+ ...blocks.slice(0, token.index),
78743
+ { ...block, children: updatedChildren.blocks },
78744
+ ...blocks.slice(token.index + 1)
78745
+ ]
78746
+ };
78747
+ }
78748
+ if (block.type === "paragraph" && next?.kind === "inline") {
78749
+ const updatedParagraph = joinNumberedParagraphInTextBoxInline(block, rest, direction);
78750
+ if (!updatedParagraph) return null;
78751
+ return {
78752
+ blocks: [
78753
+ ...blocks.slice(0, token.index),
78754
+ updatedParagraph,
78755
+ ...blocks.slice(token.index + 1)
78756
+ ]
78757
+ };
78758
+ }
78759
+ return null;
78760
+ }
78761
+ function joinAdjacentNumberedParagraphs(blocks, targetIndex, direction) {
78762
+ const target = blocks[targetIndex];
78763
+ if (target?.type !== "paragraph" || !target.numbering) {
78764
+ return null;
78765
+ }
78766
+ if (direction === "backward") {
78767
+ const previousIndex = targetIndex - 1;
78768
+ const previous = blocks[previousIndex];
78769
+ if (previous?.type !== "paragraph" || !previous.numbering) {
78770
+ return null;
78771
+ }
78772
+ const merged2 = {
78773
+ ...previous,
78774
+ children: [...previous.children, ...target.children]
78775
+ };
78776
+ return {
78777
+ blocks: [
78778
+ ...blocks.slice(0, previousIndex),
78779
+ merged2,
78780
+ ...blocks.slice(targetIndex + 1)
78781
+ ]
78782
+ };
78783
+ }
78784
+ const nextIndex = targetIndex + 1;
78785
+ const next = blocks[nextIndex];
78786
+ if (next?.type !== "paragraph" || !next.numbering) {
78787
+ return null;
78788
+ }
78789
+ const merged = {
78790
+ ...target,
78791
+ children: [...target.children, ...next.children]
78792
+ };
78793
+ return {
78794
+ blocks: [
78795
+ ...blocks.slice(0, targetIndex),
78796
+ merged,
78797
+ ...blocks.slice(nextIndex + 1)
78798
+ ]
78799
+ };
78800
+ }
78801
+ function joinNumberedParagraphInTable(table, tokens, direction) {
78802
+ const [rowToken, cellToken, ...childTokens] = tokens;
78803
+ if (rowToken?.kind !== "row" || cellToken?.kind !== "cell" || childTokens[0]?.kind !== "block") {
78804
+ return null;
78805
+ }
78806
+ const row2 = table.rows[rowToken.index];
78807
+ const cell = row2?.cells[cellToken.index];
78808
+ if (!row2 || !cell) return null;
78809
+ const updatedChildren = joinNumberedParagraphFromBlocks(cell.children, childTokens, direction);
78810
+ if (!updatedChildren) return null;
78811
+ const nextCells = [
78812
+ ...row2.cells.slice(0, cellToken.index),
78813
+ { ...cell, children: updatedChildren.blocks },
78814
+ ...row2.cells.slice(cellToken.index + 1)
78815
+ ];
78816
+ const nextRows = [
78817
+ ...table.rows.slice(0, rowToken.index),
78818
+ { ...row2, cells: nextCells },
78819
+ ...table.rows.slice(rowToken.index + 1)
78820
+ ];
78821
+ return { ...table, rows: nextRows };
78822
+ }
78823
+ function joinNumberedParagraphInTextBoxInline(paragraph, tokens, direction) {
78824
+ const [inlineToken, textBoxToken, ...childTokens] = tokens;
78825
+ if (inlineToken?.kind !== "inline" || textBoxToken?.kind !== "txbx" || childTokens[0]?.kind !== "block") {
78826
+ return null;
78827
+ }
78828
+ const inline = paragraph.children[inlineToken.index];
78829
+ if (!inline) return null;
78830
+ const updatedInline = joinNumberedParagraphInInlineTextBox(inline, childTokens, direction);
78831
+ if (!updatedInline) return null;
78832
+ return {
78833
+ ...paragraph,
78834
+ children: [
78835
+ ...paragraph.children.slice(0, inlineToken.index),
78836
+ updatedInline,
78837
+ ...paragraph.children.slice(inlineToken.index + 1)
78838
+ ]
78839
+ };
78840
+ }
78841
+ function joinNumberedParagraphInInlineTextBox(inline, tokens, direction) {
78842
+ if (inline.type === "shape" && inline.txbxBlocks) {
78843
+ const updatedBlocks = joinNumberedParagraphFromBlocks(inline.txbxBlocks, tokens, direction);
78844
+ return updatedBlocks ? { ...inline, txbxBlocks: updatedBlocks.blocks } : null;
78845
+ }
78846
+ if (inline.type === "drawing_frame" && inline.content.type === "shape" && inline.content.txbxBlocks) {
78847
+ const updatedBlocks = joinNumberedParagraphFromBlocks(inline.content.txbxBlocks, tokens, direction);
78848
+ return updatedBlocks ? {
78849
+ ...inline,
78850
+ content: {
78851
+ ...inline.content,
78852
+ txbxBlocks: updatedBlocks.blocks
78853
+ }
78854
+ } : null;
78855
+ }
78856
+ return null;
78857
+ }
78149
78858
  function removeNumberedParagraphFromBlocks(blocks, tokens) {
78150
78859
  const [token, ...rest] = tokens;
78151
78860
  if (!token || token.kind !== "block") return null;
@@ -78188,6 +78897,52 @@ function removeNumberedParagraphFromBlocks(blocks, tokens) {
78188
78897
  ]
78189
78898
  };
78190
78899
  }
78900
+ if (block.type === "paragraph" && next?.kind === "inline") {
78901
+ const updatedParagraph = removeNumberedParagraphFromTextBoxInline(block, rest);
78902
+ if (!updatedParagraph) return null;
78903
+ return {
78904
+ blocks: [
78905
+ ...blocks.slice(0, token.index),
78906
+ updatedParagraph,
78907
+ ...blocks.slice(token.index + 1)
78908
+ ]
78909
+ };
78910
+ }
78911
+ return null;
78912
+ }
78913
+ function removeNumberedParagraphFromTextBoxInline(paragraph, tokens) {
78914
+ const [inlineToken, textBoxToken, ...childTokens] = tokens;
78915
+ if (inlineToken?.kind !== "inline" || textBoxToken?.kind !== "txbx" || childTokens[0]?.kind !== "block") {
78916
+ return null;
78917
+ }
78918
+ const inline = paragraph.children[inlineToken.index];
78919
+ if (!inline) return null;
78920
+ const updatedInline = removeNumberedParagraphFromInlineTextBox(inline, childTokens);
78921
+ if (!updatedInline) return null;
78922
+ return {
78923
+ ...paragraph,
78924
+ children: [
78925
+ ...paragraph.children.slice(0, inlineToken.index),
78926
+ updatedInline,
78927
+ ...paragraph.children.slice(inlineToken.index + 1)
78928
+ ]
78929
+ };
78930
+ }
78931
+ function removeNumberedParagraphFromInlineTextBox(inline, tokens) {
78932
+ if (inline.type === "shape" && inline.txbxBlocks) {
78933
+ const updatedBlocks = removeNumberedParagraphFromBlocks(inline.txbxBlocks, tokens);
78934
+ return updatedBlocks ? { ...inline, txbxBlocks: updatedBlocks.blocks } : null;
78935
+ }
78936
+ if (inline.type === "drawing_frame" && inline.content.type === "shape" && inline.content.txbxBlocks) {
78937
+ const updatedBlocks = removeNumberedParagraphFromBlocks(inline.content.txbxBlocks, tokens);
78938
+ return updatedBlocks ? {
78939
+ ...inline,
78940
+ content: {
78941
+ ...inline.content,
78942
+ txbxBlocks: updatedBlocks.blocks
78943
+ }
78944
+ } : null;
78945
+ }
78191
78946
  return null;
78192
78947
  }
78193
78948
  function removeNumberedParagraphFromTable(table, tokens) {
@@ -78228,15 +78983,29 @@ function createSelectedListItemDeleteReplayCommand(input) {
78228
78983
  target: editableTarget,
78229
78984
  activeStoryKey: canonicalEditableTargetStoryKey(storyTarget)
78230
78985
  });
78986
+ const resolvedEditableTarget = targetResolution.kind === "accepted" ? editableTarget : storyTarget.kind !== "main" && blockPathBelongsToStoryTarget(editableTarget.blockPath, storyTarget) ? resolveEditableCommandTarget({
78987
+ document: document2,
78988
+ target: editableTarget,
78989
+ activeStoryKey: canonicalEditableTargetStoryKey(storyTarget),
78990
+ commandFamilies: ["text-leaf"]
78991
+ }) : null;
78992
+ const selectedRange = {
78993
+ from: Math.min(selection.anchor, selection.head),
78994
+ to: Math.max(selection.anchor, selection.head)
78995
+ };
78231
78996
  const replacement = createSelectedListItemDeleteReplacement({
78232
78997
  command,
78233
78998
  document: document2,
78234
- editableTarget,
78999
+ editableTarget: resolvedEditableTarget && resolvedEditableTarget.kind === "accepted" ? resolvedEditableTarget.target : editableTarget,
78235
79000
  selection,
78236
- targetResolution,
79001
+ storyTarget,
79002
+ targetResolution: resolvedEditableTarget && resolvedEditableTarget.kind === "accepted" ? {
79003
+ kind: "accepted",
79004
+ range: selectedRange
79005
+ } : targetResolution,
78237
79006
  timestamp
78238
79007
  });
78239
- if (!replacement || storyTarget.kind !== "main") {
79008
+ if (!replacement) {
78240
79009
  return null;
78241
79010
  }
78242
79011
  return {
@@ -78248,22 +79017,99 @@ function createSelectedListItemDeleteReplayCommand(input) {
78248
79017
  origin: command.origin
78249
79018
  };
78250
79019
  }
78251
- function parseMainStoryBlockPathTokens(blockPath) {
78252
- const parts = blockPath?.split("/") ?? [];
78253
- if (parts[0] !== "main" || parts.length < 2) {
79020
+ function createListItemBoundaryJoinReplayCommand(input) {
79021
+ const { command, document: document2, selection, surface, storyTarget, timestamp } = input;
79022
+ if (command.type !== "text.delete-backward" && command.type !== "text.delete-forward") {
78254
79023
  return null;
78255
79024
  }
79025
+ const editableTarget = command.editableTarget;
79026
+ if (!editableTarget) {
79027
+ return null;
79028
+ }
79029
+ const targetResolution = resolveEditableTextTarget({
79030
+ document: document2,
79031
+ selection,
79032
+ surface,
79033
+ target: editableTarget,
79034
+ activeStoryKey: canonicalEditableTargetStoryKey(storyTarget)
79035
+ });
79036
+ const resolvedEditableTarget = targetResolution.kind === "accepted" ? editableTarget : storyTarget.kind !== "main" && blockPathBelongsToStoryTarget(editableTarget.blockPath, storyTarget) ? resolveEditableCommandTarget({
79037
+ document: document2,
79038
+ target: editableTarget,
79039
+ activeStoryKey: canonicalEditableTargetStoryKey(storyTarget),
79040
+ commandFamilies: ["text-leaf"]
79041
+ }) : null;
79042
+ const selectedRange = {
79043
+ from: Math.min(selection.anchor, selection.head),
79044
+ to: Math.max(selection.anchor, selection.head)
79045
+ };
79046
+ const replacement = createListItemBoundaryJoinReplacement({
79047
+ command,
79048
+ document: document2,
79049
+ editableTarget: resolvedEditableTarget && resolvedEditableTarget.kind === "accepted" ? resolvedEditableTarget.target : editableTarget,
79050
+ selection,
79051
+ storyTarget,
79052
+ targetResolution: resolvedEditableTarget && resolvedEditableTarget.kind === "accepted" ? {
79053
+ kind: "accepted",
79054
+ range: selectedRange
79055
+ } : targetResolution,
79056
+ timestamp
79057
+ });
79058
+ if (!replacement) {
79059
+ return null;
79060
+ }
79061
+ return {
79062
+ type: "document.replace",
79063
+ document: replacement.document,
79064
+ selection: replacement.selection,
79065
+ mapping: replacement.mapping,
79066
+ protectionSelection: selection,
79067
+ origin: command.origin
79068
+ };
79069
+ }
79070
+ function parseStoryBlockPathTokens(blockPath, storyTarget) {
79071
+ if (!blockPath) {
79072
+ return null;
79073
+ }
79074
+ const firstTokenMatch = /\/(?:block|row|cell)\[\d+\]/u.exec(blockPath);
79075
+ if (!firstTokenMatch?.index) {
79076
+ return null;
79077
+ }
79078
+ const storyPrefix = blockPath.slice(0, firstTokenMatch.index);
79079
+ if (!blockPathBelongsToStoryTarget(storyPrefix, storyTarget)) {
79080
+ return null;
79081
+ }
79082
+ const parts = blockPath.slice(firstTokenMatch.index + 1).split("/");
78256
79083
  const tokens = [];
78257
- for (const part of parts.slice(1)) {
78258
- const match = /^(block|row|cell)\[(\d+)\]$/u.exec(part);
79084
+ for (const part of parts) {
79085
+ if (part === "txbx") {
79086
+ tokens.push({ kind: "txbx" });
79087
+ continue;
79088
+ }
79089
+ const match = /^(block|row|cell|inline)\[(\d+)\]$/u.exec(part);
78259
79090
  if (!match) return null;
79091
+ const kind = match[1];
78260
79092
  tokens.push({
78261
- kind: match[1],
79093
+ kind,
78262
79094
  index: Number.parseInt(match[2], 10)
78263
79095
  });
78264
79096
  }
78265
79097
  return tokens;
78266
79098
  }
79099
+ function blockPathBelongsToStoryTarget(storyPrefix, storyTarget) {
79100
+ switch (storyTarget.kind) {
79101
+ case "main":
79102
+ return storyPrefix === "main" || storyPrefix.startsWith("main/");
79103
+ case "header":
79104
+ return storyPrefix.startsWith("header:");
79105
+ case "footer":
79106
+ return storyPrefix.startsWith("footer:");
79107
+ case "footnote":
79108
+ return storyPrefix === `footnote:${storyTarget.noteId}` || storyPrefix.startsWith(`footnote:${storyTarget.noteId}/`);
79109
+ case "endnote":
79110
+ return storyPrefix === `endnote:${storyTarget.noteId}` || storyPrefix.startsWith(`endnote:${storyTarget.noteId}/`);
79111
+ }
79112
+ }
78267
79113
  function toInternalSelectionSnapshot2(selection) {
78268
79114
  return {
78269
79115
  anchor: selection.anchor,
@@ -94387,6 +95233,9 @@ function createLoadingRuntimeBridge(input) {
94387
95233
  addScope: () => {
94388
95234
  throw createLoadingBoundaryError(input.snapshot.documentId, "scope");
94389
95235
  },
95236
+ addScopes: () => {
95237
+ throw createLoadingBoundaryError(input.snapshot.documentId, "scope");
95238
+ },
94390
95239
  getScope: () => null,
94391
95240
  compileScopeBundleById: () => null,
94392
95241
  compileScopeList: () => [],
@@ -94737,7 +95586,8 @@ async function persistAndExport(input) {
94737
95586
  });
94738
95587
  result = withExportDelivery(result, {
94739
95588
  mode: "persisted-by-host",
94740
- savedAt: saveResult.savedAt
95589
+ savedAt: saveResult.savedAt,
95590
+ ...input.options?.download === false ? { downloadSuppressed: true } : {}
94741
95591
  });
94742
95592
  } catch (error) {
94743
95593
  const normalized = normalizeStorageError(error, {
@@ -108247,6 +109097,10 @@ function TwTableGripLayer({
108247
109097
  tableGeometry,
108248
109098
  plan.columnsTwips
108249
109099
  );
109100
+ const columnWidthCapability = tableContext.operations.setColumnWidth;
109101
+ const rowHeightCapability = tableContext.operations.setRowHeight;
109102
+ const columnResizeDisabled = !!disabled || !onSetColumnWidth || columnWidthCapability?.enabled === false;
109103
+ const rowResizeDisabled = !!disabled || !onSetRowHeight || rowHeightCapability?.enabled === false;
108250
109104
  return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
108251
109105
  plan.columnResizeHandles.map((handle) => {
108252
109106
  const rect3 = resolveColumnEdgeRect(
@@ -108261,7 +109115,8 @@ function TwTableGripLayer({
108261
109115
  colIndex: handle.columnIndex,
108262
109116
  originalTwips: plan.columnsTwips[handle.columnIndex] ?? 720,
108263
109117
  pxPerTwip,
108264
- disabled: !!disabled || !onSetColumnWidth,
109118
+ disabled: columnResizeDisabled,
109119
+ disabledReason: columnWidthCapability?.reason,
108265
109120
  onCommit: onSetColumnWidth
108266
109121
  },
108267
109122
  `col-${blockId}-${handle.columnIndex}`
@@ -108282,7 +109137,8 @@ function TwTableGripLayer({
108282
109137
  rowIndex,
108283
109138
  originalTwips,
108284
109139
  pxPerTwip,
108285
- disabled: !!disabled || !onSetRowHeight,
109140
+ disabled: rowResizeDisabled,
109141
+ disabledReason: rowHeightCapability?.reason,
108286
109142
  onCommit: onSetRowHeight
108287
109143
  },
108288
109144
  `row-${blockId}-${rowIndex}`
@@ -108372,6 +109228,7 @@ function ColResizeGrip({
108372
109228
  originalTwips,
108373
109229
  pxPerTwip,
108374
109230
  disabled,
109231
+ disabledReason,
108375
109232
  onCommit
108376
109233
  }) {
108377
109234
  const dragRef = (0, import_react34.useRef)(null);
@@ -108430,11 +109287,13 @@ function ColResizeGrip({
108430
109287
  role: "separator",
108431
109288
  "aria-orientation": "vertical",
108432
109289
  "aria-label": `Resize column ${colIndex + 1}`,
109290
+ "aria-disabled": disabled ? "true" : void 0,
108433
109291
  "data-testid": `col-resize-grip-${colIndex}`,
108434
109292
  "data-active": isActive ? "true" : "false",
109293
+ title: disabled ? disabledReason : void 0,
108435
109294
  className: [
108436
- "wre-table-grip-col pointer-events-auto absolute",
108437
- disabled ? "opacity-0 cursor-default" : ""
109295
+ "wre-table-grip-col absolute",
109296
+ disabled ? "pointer-events-none opacity-0 cursor-default" : "pointer-events-auto"
108438
109297
  ].filter(Boolean).join(" "),
108439
109298
  style: {
108440
109299
  left: `calc(${pos.left} - ${GRIP_HIT_PX / 2}px)`,
@@ -108452,6 +109311,7 @@ function RowResizeGrip({
108452
109311
  originalTwips,
108453
109312
  pxPerTwip,
108454
109313
  disabled,
109314
+ disabledReason,
108455
109315
  onCommit
108456
109316
  }) {
108457
109317
  const dragRef = (0, import_react34.useRef)(null);
@@ -108511,11 +109371,13 @@ function RowResizeGrip({
108511
109371
  role: "separator",
108512
109372
  "aria-orientation": "horizontal",
108513
109373
  "aria-label": `Resize row ${rowIndex + 1}`,
109374
+ "aria-disabled": disabled ? "true" : void 0,
108514
109375
  "data-testid": `row-resize-grip-${rowIndex}`,
108515
109376
  "data-active": isActive ? "true" : "false",
109377
+ title: disabled ? disabledReason : void 0,
108516
109378
  className: [
108517
- "wre-table-grip-row pointer-events-auto absolute",
108518
- disabled ? "opacity-0 cursor-default" : ""
109379
+ "wre-table-grip-row absolute",
109380
+ disabled ? "pointer-events-none opacity-0 cursor-default" : "pointer-events-auto"
108519
109381
  ].filter(Boolean).join(" "),
108520
109382
  style: {
108521
109383
  left: pos.left,
@@ -126641,7 +127503,7 @@ var LAYER_DEBUG_PANES = [
126641
127503
  snippets: [
126642
127504
  { label: "Selection context", expression: "ref?.getRuntimeContextAnalytics?.()" },
126643
127505
  { label: "Document context", expression: "ref?.getRuntimeContextAnalytics?.({ scopeKind: 'document' })" },
126644
- { label: "Hot edit trace", expression: "runtime?.debug?.getHotEditTraces?.().at(-1)" },
127506
+ { label: "Hot edit trace", expression: "runtime?.debug?.getHotEditTraces?.()?.at(-1)" },
126645
127507
  { label: "View state", expression: "ref?.getViewState?.()" }
126646
127508
  ],
126647
127509
  routed: [
@@ -126655,8 +127517,8 @@ var LAYER_DEBUG_PANES = [
126655
127517
  focus: "Workflow scopes, markup, metadata, candidates, and scope-derived context.",
126656
127518
  snippets: [
126657
127519
  { label: "Scope snapshot", expression: "ref?.getWorkflowScopeSnapshot?.()" },
126658
- { label: "Query scopes", expression: "ref?.queryScopes?.({ includeHidden: true, includeInvisible: true })" },
126659
- { label: "Workflow markup", expression: "ref?.getWorkflowMarkupSnapshot?.()" }
127520
+ { label: "Query scopes", expression: "ref?.queryScopes?.({ includeHidden: true, includeInvisible: true, limit: 50 })" },
127521
+ { label: "Workflow markup", expression: "(() => { const m = ref?.getWorkflowMarkupSnapshot?.(); return m ? { itemCount: m.items?.length ?? 0, items: m.items?.slice(0, 50) ?? [] } : m; })()" }
126660
127522
  ],
126661
127523
  routed: [
126662
127524
  "Compiler replacement planning and semantic scope normalization remain Layer 08-owned."
@@ -126670,7 +127532,7 @@ var LAYER_DEBUG_PANES = [
126670
127532
  snippets: [
126671
127533
  { label: "Document analytics", expression: "ref?.getRuntimeContextAnalytics?.({ scopeKind: 'document' })" },
126672
127534
  { label: "Workflow analytics", expression: "ref?.getRuntimeContextAnalytics?.({ scopeKind: 'workflow_scope', scopeId: ref?.getInteractionGuardSnapshot?.()?.matchedScopeId })" },
126673
- { label: "Available scopes", expression: "ref?.queryScopes?.({ includeHidden: true, includeInvisible: true })" }
127535
+ { label: "Available scopes", expression: "ref?.queryScopes?.({ includeHidden: true, includeInvisible: true, limit: 50 })" }
126674
127536
  ],
126675
127537
  routed: [
126676
127538
  "AI audit references and action policy payloads are Layer 09-owned."
@@ -126698,7 +127560,7 @@ var LAYER_DEBUG_PANES = [
126698
127560
  snippets: [
126699
127561
  { label: "Navigation", expression: "ref?.getDocumentNavigationSnapshot?.()" },
126700
127562
  { label: "Review surface", expression: "({ comments: ref?.getCommentSidebarSnapshot?.(), changes: ref?.getTrackedChangesSnapshot?.() })" },
126701
- { label: "Hot edit traces", expression: "runtime?.debug?.getHotEditTraces?.()" },
127563
+ { label: "Hot edit traces", expression: "runtime?.debug?.getHotEditTraces?.()?.slice?.(-10)" },
126702
127564
  { label: "Compatibility", expression: "ref?.getCompatibilityReport?.()" }
126703
127565
  ],
126704
127566
  routed: [
@@ -126731,6 +127593,11 @@ var import_jsx_runtime83 = require("react/jsx-runtime");
126731
127593
  var MAX_HISTORY = 30;
126732
127594
  var MAX_ENTRIES = 50;
126733
127595
  var MAX_OUTPUT_CHARS = 8e3;
127596
+ var MAX_SERIALIZE_DEPTH = 6;
127597
+ var MAX_SERIALIZE_STRING_CHARS = 1e3;
127598
+ var MAX_SERIALIZE_ARRAY_ITEMS = 40;
127599
+ var MAX_SERIALIZE_OBJECT_KEYS = 80;
127600
+ var MAX_SERIALIZE_NODES = 2500;
126734
127601
  var HISTORY_STORAGE_KEY = "wre-runtime-repl-history";
126735
127602
  var HISTORY_STORAGE_VERSION = 1;
126736
127603
  function TwRuntimeReplDialog(props) {
@@ -127196,7 +128063,7 @@ function formatReplValue(value) {
127196
128063
  if (value === void 0) return "undefined";
127197
128064
  if (value === null) return "null";
127198
128065
  const type = typeof value;
127199
- if (type === "string") return JSON.stringify(value);
128066
+ if (type === "string") return truncate2(JSON.stringify(value), MAX_OUTPUT_CHARS);
127200
128067
  if (type === "number" || type === "boolean" || type === "bigint") {
127201
128068
  return String(value);
127202
128069
  }
@@ -127206,7 +128073,7 @@ function formatReplValue(value) {
127206
128073
  return `[Function${fn.name ? `: ${fn.name}` : ""}]`;
127207
128074
  }
127208
128075
  try {
127209
- const serialized = JSON.stringify(value, createCircularReplacer(), 2);
128076
+ const serialized = JSON.stringify(createReplPreview(value), null, 2);
127210
128077
  if (serialized === void 0) {
127211
128078
  return String(value);
127212
128079
  }
@@ -127222,21 +128089,113 @@ function formatReplError(error) {
127222
128089
  }
127223
128090
  return truncate2(String(error), MAX_OUTPUT_CHARS);
127224
128091
  }
127225
- function createCircularReplacer() {
127226
- const seen = /* @__PURE__ */ new WeakSet();
127227
- return function replacer(_key, value) {
127228
- if (typeof value === "bigint") return `${value.toString()}n`;
127229
- if (typeof value === "function") {
127230
- const fn = value;
127231
- return `[Function${fn.name ? `: ${fn.name}` : ""}]`;
128092
+ function createReplPreview(value) {
128093
+ return createReplPreviewValue(value, 0, {
128094
+ seen: /* @__PURE__ */ new WeakSet(),
128095
+ nodes: 0
128096
+ });
128097
+ }
128098
+ function createReplPreviewValue(value, depth, state) {
128099
+ if (value === null || typeof value === "number" || typeof value === "boolean") {
128100
+ return value;
128101
+ }
128102
+ if (typeof value === "string") {
128103
+ return value.length > MAX_SERIALIZE_STRING_CHARS ? `${value.slice(0, MAX_SERIALIZE_STRING_CHARS)}... [truncated ${value.length - MAX_SERIALIZE_STRING_CHARS} chars]` : value;
128104
+ }
128105
+ if (typeof value === "bigint") return `${value.toString()}n`;
128106
+ if (typeof value === "symbol") return value.toString();
128107
+ if (typeof value === "function") {
128108
+ const fn = value;
128109
+ return `[Function${fn.name ? `: ${fn.name}` : ""}]`;
128110
+ }
128111
+ if (typeof value !== "object") return String(value);
128112
+ state.nodes += 1;
128113
+ if (state.nodes > MAX_SERIALIZE_NODES) {
128114
+ return "[Max REPL preview nodes reached]";
128115
+ }
128116
+ const objectValue = value;
128117
+ if (state.seen.has(objectValue)) return "[Circular]";
128118
+ state.seen.add(objectValue);
128119
+ if (depth >= MAX_SERIALIZE_DEPTH) {
128120
+ return summarizePreviewBoundary(objectValue);
128121
+ }
128122
+ const domPreview = summarizeDomNode(objectValue);
128123
+ if (domPreview) return domPreview;
128124
+ if (Array.isArray(value)) {
128125
+ const preview = value.slice(0, MAX_SERIALIZE_ARRAY_ITEMS).map((item) => createReplPreviewValue(item, depth + 1, state));
128126
+ if (value.length > MAX_SERIALIZE_ARRAY_ITEMS) {
128127
+ preview.push(`[... ${value.length - MAX_SERIALIZE_ARRAY_ITEMS} more items]`);
127232
128128
  }
127233
- if (typeof value === "symbol") return value.toString();
127234
- if (value !== null && typeof value === "object") {
127235
- if (seen.has(value)) return "[Circular]";
127236
- seen.add(value);
128129
+ return preview;
128130
+ }
128131
+ if (value instanceof Date) {
128132
+ return Number.isNaN(value.getTime()) ? "[Invalid Date]" : value.toISOString();
128133
+ }
128134
+ if (value instanceof Map) {
128135
+ const entries = [];
128136
+ let index = 0;
128137
+ for (const [key, entryValue] of value.entries()) {
128138
+ if (index >= MAX_SERIALIZE_OBJECT_KEYS) {
128139
+ entries.push("[additional map entries omitted]");
128140
+ break;
128141
+ }
128142
+ entries.push([
128143
+ createReplPreviewValue(key, depth + 1, state),
128144
+ createReplPreviewValue(entryValue, depth + 1, state)
128145
+ ]);
128146
+ index += 1;
127237
128147
  }
127238
- return value;
127239
- };
128148
+ return { "[Map]": entries };
128149
+ }
128150
+ if (value instanceof Set) {
128151
+ const entries = [];
128152
+ let index = 0;
128153
+ for (const entryValue of value.values()) {
128154
+ if (index >= MAX_SERIALIZE_OBJECT_KEYS) {
128155
+ entries.push("[additional set entries omitted]");
128156
+ break;
128157
+ }
128158
+ entries.push(createReplPreviewValue(entryValue, depth + 1, state));
128159
+ index += 1;
128160
+ }
128161
+ return { "[Set]": entries };
128162
+ }
128163
+ const output = {};
128164
+ let count = 0;
128165
+ for (const key in value) {
128166
+ if (!Object.prototype.propertyIsEnumerable.call(value, key)) continue;
128167
+ if (count >= MAX_SERIALIZE_OBJECT_KEYS) {
128168
+ output["..."] = "[additional properties omitted]";
128169
+ break;
128170
+ }
128171
+ try {
128172
+ output[key] = createReplPreviewValue(
128173
+ value[key],
128174
+ depth + 1,
128175
+ state
128176
+ );
128177
+ } catch (error) {
128178
+ output[key] = `[unreadable property: ${formatReplError(error)}]`;
128179
+ }
128180
+ count += 1;
128181
+ }
128182
+ return output;
128183
+ }
128184
+ function summarizePreviewBoundary(value) {
128185
+ if (Array.isArray(value)) return `[Array(${value.length}) depth limit]`;
128186
+ const domPreview = summarizeDomNode(value);
128187
+ if (domPreview) return domPreview;
128188
+ const constructorName = value.constructor?.name;
128189
+ return constructorName && constructorName !== "Object" ? `[${constructorName} depth limit]` : "[Object depth limit]";
128190
+ }
128191
+ function summarizeDomNode(value) {
128192
+ const maybeNode = value;
128193
+ if (typeof maybeNode.nodeType !== "number" || typeof maybeNode.nodeName !== "string") {
128194
+ return null;
128195
+ }
128196
+ const id = typeof maybeNode.id === "string" && maybeNode.id.length > 0 ? `#${maybeNode.id}` : "";
128197
+ const className = typeof maybeNode.className === "string" && maybeNode.className.length > 0 ? `.${maybeNode.className.trim().replace(/\s+/g, ".")}` : "";
128198
+ return `[DOM ${maybeNode.nodeName.toLowerCase()}${id}${className}]`;
127240
128199
  }
127241
128200
  function truncate2(text, max) {
127242
128201
  if (text.length <= max) return text;
@@ -128586,9 +129545,23 @@ function findSurfaceBlockById(blocks, blockId) {
128586
129545
  }
128587
129546
  function createScopeFromAnchor(runtime, input) {
128588
129547
  const doc = runtime.getCanonicalDocument();
128589
- const storyTarget = input.anchor.storyTarget ?? { kind: "main" };
129548
+ const normalizedInputAnchor = normalizeCreateScopeAnchor(input.anchor);
129549
+ const storyTarget = normalizedInputAnchor.storyTarget ?? { kind: "main" };
128590
129550
  const storyLength = storyTarget.kind === "main" ? computeMainStoryLength(doc) : Number.MAX_SAFE_INTEGER;
128591
- const { from, to } = input.anchor;
129551
+ const { from, to } = normalizedInputAnchor;
129552
+ if (!Number.isFinite(from) || !Number.isFinite(to)) {
129553
+ const diagnosticFrom = Number.isFinite(from) ? from : 0;
129554
+ const diagnosticTo = Number.isFinite(to) ? to : diagnosticFrom;
129555
+ return {
129556
+ status: "range-invalid",
129557
+ reason: "non-finite-range",
129558
+ from: diagnosticFrom,
129559
+ to: diagnosticTo,
129560
+ storyLength,
129561
+ message: `createScopeFromAnchor requires finite numeric from/to offsets. Pass selection.activeRange or an object shaped as {from, to}; do not pass a malformed range.`,
129562
+ nextStep: "pass-selection-activeRange-or-finite-from-to"
129563
+ };
129564
+ }
128592
129565
  if (from < 0) {
128593
129566
  return {
128594
129567
  status: "range-invalid",
@@ -128686,6 +129659,29 @@ function createScopeFromAnchor(runtime, input) {
128686
129659
  }
128687
129660
  return { status: "created", scopeId: result.scopeId, anchor: result.anchor };
128688
129661
  }
129662
+ function normalizeCreateScopeAnchor(anchor) {
129663
+ const candidate = anchor;
129664
+ const activeRange = candidate.activeRange;
129665
+ if (activeRange?.kind === "range") {
129666
+ return {
129667
+ from: activeRange.from,
129668
+ to: activeRange.to,
129669
+ storyTarget: candidate.storyTarget
129670
+ };
129671
+ }
129672
+ if (candidate.kind === "range") {
129673
+ return {
129674
+ from: candidate.from ?? Number.NaN,
129675
+ to: candidate.to ?? Number.NaN,
129676
+ storyTarget: candidate.storyTarget
129677
+ };
129678
+ }
129679
+ return {
129680
+ from: candidate.from ?? Number.NaN,
129681
+ to: candidate.to ?? Number.NaN,
129682
+ storyTarget: candidate.storyTarget
129683
+ };
129684
+ }
128689
129685
 
128690
129686
  // src/api/v3/runtime/workflow.ts
128691
129687
  var createScopeMetadata = {
@@ -129932,7 +130928,8 @@ var SUPPORTED_COMMANDS2 = [
129932
130928
  "indent",
129933
130929
  "outdent",
129934
130930
  "restart-numbering",
129935
- "continue-numbering"
130931
+ "continue-numbering",
130932
+ "set-value"
129936
130933
  ];
129937
130934
  var UNSUPPORTED_COMMANDS2 = [
129938
130935
  "create",
@@ -129941,7 +130938,6 @@ var UNSUPPORTED_COMMANDS2 = [
129941
130938
  "join",
129942
130939
  "separate",
129943
130940
  "split",
129944
- "set-value",
129945
130941
  "apply-template",
129946
130942
  "capture-template",
129947
130943
  "apply-preset",
@@ -129990,10 +130986,10 @@ function createListsFamily2(runtime) {
129990
130986
  return resolved.kind === "resolved" ? toReadback(runtime.getCanonicalDocument(), resolved.target, resolved.paragraph) : null;
129991
130987
  },
129992
130988
  previewCommand(input) {
129993
- return previewListCommand(runtime.getCanonicalDocument(), input);
130989
+ return previewListCommand(runtime.getCanonicalDocument(), input, activeStoryKey(runtime));
129994
130990
  },
129995
130991
  applyCommand(input) {
129996
- const preview = previewListCommand(runtime.getCanonicalDocument(), input);
130992
+ const preview = previewListCommand(runtime.getCanonicalDocument(), input, activeStoryKey(runtime));
129997
130993
  if (!preview.supported || !preview.target) {
129998
130994
  return {
129999
130995
  applied: false,
@@ -130053,7 +131049,7 @@ function createListsFamily2(runtime) {
130053
131049
  }
130054
131050
  };
130055
131051
  }
130056
- function previewListCommand(document2, input) {
131052
+ function previewListCommand(document2, input, activeStoryKey2) {
130057
131053
  const resolved = resolveCurrentListTarget(document2, input);
130058
131054
  if (resolved.kind !== "resolved") {
130059
131055
  return {
@@ -130065,6 +131061,20 @@ function previewListCommand(document2, input) {
130065
131061
  }
130066
131062
  const target = toReadback(document2, resolved.target, resolved.paragraph);
130067
131063
  const targetRef = { targetKey: target.targetKey, addressKey: target.addressKey };
131064
+ if (activeStoryKey2 !== void 0 && target.storyKey !== activeStoryKey2) {
131065
+ return {
131066
+ command: input.command,
131067
+ supported: false,
131068
+ target,
131069
+ affectedTargets: [target],
131070
+ blockers: [{
131071
+ code: "list-target-wrong-story",
131072
+ ownerLayer: "L07",
131073
+ message: "List target does not belong to the runtime active story.",
131074
+ ...targetRef
131075
+ }]
131076
+ };
131077
+ }
130068
131078
  if (!SUPPORTED_COMMANDS2.includes(input.command)) {
130069
131079
  return {
130070
131080
  command: input.command,
@@ -130077,6 +131087,17 @@ function previewListCommand(document2, input) {
130077
131087
  const canContinuePrevious = canContinuePreviousSequence(document2, resolved.paragraphIndex);
130078
131088
  const canJoin = canJoinPreviousSequence(document2, resolved.paragraphIndex);
130079
131089
  const blockers = [];
131090
+ if (input.command === "set-value") {
131091
+ const value = input.startAt;
131092
+ if (!Number.isInteger(value) || value === void 0 || value < 1) {
131093
+ blockers.push({
131094
+ code: "list-command-preflight-blocked",
131095
+ ownerLayer: "L07",
131096
+ message: "runtime.lists.set-value requires a positive integer startAt value.",
131097
+ ...targetRef
131098
+ });
131099
+ }
131100
+ }
130080
131101
  if (input.command === "continue-numbering" && !canContinuePrevious) {
130081
131102
  blockers.push({
130082
131103
  code: "list-continue-target-missing",
@@ -130107,6 +131128,7 @@ function editorCommandForListCommand(command, editableTarget, timestamp, startAt
130107
131128
  case "outdent":
130108
131129
  return { type: "list.outdent", editableTargets: [editableTarget], origin };
130109
131130
  case "restart-numbering":
131131
+ case "set-value":
130110
131132
  return {
130111
131133
  type: "list.restart-numbering",
130112
131134
  editableTarget,
@@ -130190,33 +131212,35 @@ function resolveCurrentListTarget(document2, input) {
130190
131212
  return { kind: "resolved", ...resolved };
130191
131213
  }
130192
131214
  function currentListTargets(document2) {
130193
- const paragraphs = collectParagraphEntries(document2.content.children, "main");
131215
+ const paragraphs = collectParagraphEntries(document2);
130194
131216
  const targets = collectEditableTargetRefs(document2).filter(isListTextTarget);
130195
- const byBlockPath = /* @__PURE__ */ new Map();
130196
- for (const target of targets) byBlockPath.set(target.blockPath, target);
131217
+ const byStoryBlockPath = /* @__PURE__ */ new Map();
131218
+ for (const target of targets) byStoryBlockPath.set(storyBlockPathKey(target.storyKey, target.blockPath), target);
130197
131219
  const out = [];
130198
131220
  for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex += 1) {
130199
131221
  const entry = paragraphs[paragraphIndex];
130200
131222
  if (!entry?.paragraph.numbering) continue;
130201
- const target = byBlockPath.get(entry.blockPath);
131223
+ const target = byStoryBlockPath.get(storyBlockPathKey(entry.storyKey, entry.blockPath));
130202
131224
  if (!target) continue;
130203
- out.push({ target, paragraph: entry.paragraph, paragraphIndex });
131225
+ out.push({ target, paragraph: entry.paragraph, paragraphIndex, storyKey: entry.storyKey });
130204
131226
  }
130205
131227
  return out;
130206
131228
  }
130207
- function collectParagraphEntries(blocks, basePath) {
131229
+ function collectParagraphEntries(document2) {
130208
131230
  const out = [];
130209
- collectParagraphEntriesInto(blocks, basePath, out);
131231
+ for (const context of collectStoryBlockContexts(document2)) {
131232
+ collectParagraphEntriesInto(context.blocks, context.storyKey, context.basePath, out);
131233
+ }
130210
131234
  return out;
130211
131235
  }
130212
- function collectParagraphEntriesInto(blocks, basePath, out) {
131236
+ function collectParagraphEntriesInto(blocks, storyKey2, basePath, out) {
130213
131237
  for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
130214
131238
  const block = blocks[blockIndex];
130215
131239
  if (!block) continue;
130216
131240
  const blockPath = `${basePath}/block[${blockIndex}]`;
130217
131241
  switch (block.type) {
130218
131242
  case "paragraph":
130219
- out.push({ paragraph: block, blockPath });
131243
+ out.push({ paragraph: block, storyKey: storyKey2, blockPath });
130220
131244
  break;
130221
131245
  case "table":
130222
131246
  for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
@@ -130227,6 +131251,7 @@ function collectParagraphEntriesInto(blocks, basePath, out) {
130227
131251
  if (!cell) continue;
130228
131252
  collectParagraphEntriesInto(
130229
131253
  cell.children,
131254
+ storyKey2,
130230
131255
  `${blockPath}/row[${rowIndex}]/cell[${cellIndex}]`,
130231
131256
  out
130232
131257
  );
@@ -130234,7 +131259,7 @@ function collectParagraphEntriesInto(blocks, basePath, out) {
130234
131259
  }
130235
131260
  break;
130236
131261
  case "sdt":
130237
- collectParagraphEntriesInto(block.children, blockPath, out);
131262
+ collectParagraphEntriesInto(block.children, storyKey2, blockPath, out);
130238
131263
  break;
130239
131264
  case "custom_xml":
130240
131265
  break;
@@ -130278,13 +131303,16 @@ function toReadback(document2, target, paragraph) {
130278
131303
  };
130279
131304
  }
130280
131305
  function canContinuePreviousSequence(document2, paragraphIndex) {
130281
- const paragraphs = collectParagraphEntries(document2.content.children, "main");
130282
- const current = paragraphs[paragraphIndex]?.paragraph;
131306
+ const paragraphs = collectParagraphEntries(document2);
131307
+ const currentEntry = paragraphs[paragraphIndex];
131308
+ const current = currentEntry?.paragraph;
130283
131309
  if (!current?.numbering) return false;
130284
131310
  const currentKind = getListKind(document2.numbering, current.numbering.numberingInstanceId);
130285
131311
  if (!currentKind) return false;
130286
131312
  for (let index = paragraphIndex - 1; index >= 0; index -= 1) {
130287
- const previous = paragraphs[index]?.paragraph;
131313
+ const previousEntry = paragraphs[index];
131314
+ if (previousEntry?.storyKey !== currentEntry.storyKey) break;
131315
+ const previous = previousEntry.paragraph;
130288
131316
  if (!previous?.numbering) continue;
130289
131317
  const previousKind = getListKind(document2.numbering, previous.numbering.numberingInstanceId);
130290
131318
  return previousKind === currentKind && previous.numbering.numberingInstanceId !== current.numbering.numberingInstanceId;
@@ -130292,14 +131320,25 @@ function canContinuePreviousSequence(document2, paragraphIndex) {
130292
131320
  return false;
130293
131321
  }
130294
131322
  function canJoinPreviousSequence(document2, paragraphIndex) {
130295
- const paragraphs = collectParagraphEntries(document2.content.children, "main");
130296
- const current = paragraphs[paragraphIndex]?.paragraph;
130297
- const previous = paragraphs[paragraphIndex - 1]?.paragraph;
131323
+ const paragraphs = collectParagraphEntries(document2);
131324
+ const currentEntry = paragraphs[paragraphIndex];
131325
+ const previousEntry = paragraphs[paragraphIndex - 1];
131326
+ if (previousEntry?.storyKey !== currentEntry?.storyKey) return false;
131327
+ const current = currentEntry?.paragraph;
131328
+ const previous = previousEntry?.paragraph;
130298
131329
  if (!current?.numbering || !previous?.numbering) return false;
130299
131330
  const currentKind = getListKind(document2.numbering, current.numbering.numberingInstanceId);
130300
131331
  const previousKind = getListKind(document2.numbering, previous.numbering.numberingInstanceId);
130301
131332
  return Boolean(currentKind) && currentKind === previousKind && current.numbering.numberingInstanceId !== previous.numbering.numberingInstanceId;
130302
131333
  }
131334
+ function storyBlockPathKey(storyKey2, blockPath) {
131335
+ return `${storyKey2}
131336
+ ${blockPath}`;
131337
+ }
131338
+ function activeStoryKey(runtime) {
131339
+ const activeStory = runtime.getRenderSnapshot()?.activeStory;
131340
+ return activeStory ? storyTargetKey(activeStory) : void 0;
131341
+ }
130303
131342
  function unsupportedCommandBlocker(command, target) {
130304
131343
  return {
130305
131344
  code: "list-command-unsupported",
@@ -134594,33 +135633,51 @@ function createPlaceholderScopes(runtime, input) {
134594
135633
  blockerDetails: Object.freeze([detail])
134595
135634
  };
134596
135635
  }
134597
- const compiler = createScopeCompilerService(runtime);
134598
135636
  const byOriginalIndex = /* @__PURE__ */ new Map();
134599
- for (const item of orderedHits) {
135637
+ const createdScopeIds = [];
135638
+ const scopeRequests = orderedHits.map((item) => {
134600
135639
  const text = item.text || query;
134601
135640
  const label = input.labelPrefix === void 0 ? text : `${input.labelPrefix} ${item.originalIndex + 1}`;
134602
- const result = createScopeFromAnchor(runtime, {
134603
- anchor: { from: item.hit.from, to: item.hit.to },
135641
+ return {
135642
+ anchor: {
135643
+ kind: "range",
135644
+ from: item.hit.from,
135645
+ to: item.hit.to,
135646
+ assoc: input.assoc ?? { start: 1, end: -1 }
135647
+ },
134604
135648
  mode: input.mode ?? "edit",
134605
135649
  label,
134606
135650
  ...input.visibility ? { visibility: input.visibility } : {},
134607
135651
  ...input.guardPolicy ? { guardPolicy: input.guardPolicy } : {},
134608
135652
  ...input.assoc ? { assoc: input.assoc } : {},
134609
- ...input.stableRefHint ? { stableRefHint: input.stableRefHint } : {}
134610
- });
134611
- if (result.status === "created") {
134612
- const compiled = compiler.compileScopeById(result.scopeId)?.scope;
135653
+ ...input.stableRefHint ? {
135654
+ scopeMetadataFields: [
135655
+ {
135656
+ key: "stableRefHint",
135657
+ valueType: "string",
135658
+ value: input.stableRefHint
135659
+ }
135660
+ ]
135661
+ } : {}
135662
+ };
135663
+ });
135664
+ const scopeResults = runtime.addScopes(scopeRequests);
135665
+ orderedHits.forEach((item, requestIndex) => {
135666
+ const text = item.text || query;
135667
+ const result = scopeResults[requestIndex];
135668
+ if (result && result.scopeId && result.plantStatus?.planted !== false) {
135669
+ createdScopeIds.push(result.scopeId);
134613
135670
  byOriginalIndex.set(item.originalIndex, {
134614
135671
  status: "created",
134615
135672
  text,
134616
135673
  excerpt: excerpt(text),
134617
- scopeId: result.scopeId,
134618
- ...compiled?.handle ? { handle: compiled.handle } : {}
135674
+ scopeId: result.scopeId
134619
135675
  });
134620
- continue;
135676
+ return;
134621
135677
  }
135678
+ const reason = result?.plantStatus?.reason ?? "unknown";
134622
135679
  const detail = blockerWithOwner(
134623
- `actions:placeholder-scopes:create-refused:${result.reason}`,
135680
+ `actions:placeholder-scopes:create-refused:${reason}`,
134624
135681
  "blocked",
134625
135682
  "The placeholder match could not be converted into a workflow scope.",
134626
135683
  "Refresh the document and retry; if it still refuses, route the target to the workflow/scope writer owner.",
@@ -134633,6 +135690,38 @@ function createPlaceholderScopes(runtime, input) {
134633
135690
  blockers: Object.freeze([detail.code]),
134634
135691
  blockerDetails: Object.freeze([detail])
134635
135692
  });
135693
+ });
135694
+ if (createdScopeIds.length > 0) {
135695
+ const createdScopeIdSet = new Set(createdScopeIds);
135696
+ const handlesByScopeId = new Map(
135697
+ createScopeCompilerService(runtime).compileAllScopes().filter((scope) => createdScopeIdSet.has(scope.handle.scopeId)).map((scope) => [scope.handle.scopeId, scope.handle])
135698
+ );
135699
+ for (const [originalIndex, item] of byOriginalIndex) {
135700
+ if (item.status !== "created" || !item.scopeId) continue;
135701
+ const handle = handlesByScopeId.get(item.scopeId);
135702
+ if (!handle) {
135703
+ const detail = blockerWithOwner(
135704
+ `actions:placeholder-scopes:create-unresolved:${item.scopeId}`,
135705
+ "blocked",
135706
+ "The placeholder scope marker was planted but did not enumerate as a current semantic scope handle.",
135707
+ "Treat this target as unresolved, refresh scope enumeration, and route persistent misses to the semantic-scope compiler owner.",
135708
+ "L08"
135709
+ );
135710
+ byOriginalIndex.set(originalIndex, {
135711
+ status: "blocked",
135712
+ text: item.text,
135713
+ excerpt: item.excerpt,
135714
+ scopeId: item.scopeId,
135715
+ blockers: Object.freeze([detail.code]),
135716
+ blockerDetails: Object.freeze([detail])
135717
+ });
135718
+ continue;
135719
+ }
135720
+ byOriginalIndex.set(originalIndex, {
135721
+ ...item,
135722
+ handle
135723
+ });
135724
+ }
134636
135725
  }
134637
135726
  const scopes = orderedHits.map((item) => byOriginalIndex.get(item.originalIndex)).filter((value) => value !== void 0);
134638
135727
  const created = scopes.filter((scope) => scope.status === "created").length;