@beyondwork/docx-react-component 1.0.123 → 1.0.125

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 (101) hide show
  1. package/dist/api/public-types.cjs +147 -35
  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 +3 -3
  5. package/dist/api/v3.cjs +797 -99
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +10 -10
  9. package/dist/{canonical-document-CG2TgAzj.d.cts → canonical-document-CXCFCbAz.d.cts} +2 -0
  10. package/dist/{canonical-document-CG2TgAzj.d.ts → canonical-document-CXCFCbAz.d.ts} +2 -0
  11. package/dist/{chunk-PFYUJU3Q.js → chunk-2QL5DAKF.js} +98 -43
  12. package/dist/{chunk-4IPEZYQX.js → chunk-4EENH4FG.js} +1 -1
  13. package/dist/{chunk-BOHHIVQ2.js → chunk-4G3OS2H6.js} +3 -3
  14. package/dist/{chunk-MB7RJBSN.js → chunk-4YJVRIUB.js} +58 -19
  15. package/dist/{chunk-FNWKE74J.js → chunk-5DGKFNQT.js} +5 -1
  16. package/dist/{chunk-RSYN6FTS.js → chunk-6F5QW44A.js} +2 -2
  17. package/dist/{chunk-KOHQFZMM.js → chunk-BYSRJ4FE.js} +1 -1
  18. package/dist/{chunk-H6IL5ABU.js → chunk-CXSYRB37.js} +64 -20
  19. package/dist/{chunk-32ZAOQ54.js → chunk-D5HYZQTG.js} +1 -1
  20. package/dist/{chunk-ML4A4WUN.js → chunk-ESJ2MES5.js} +1 -1
  21. package/dist/{chunk-H2YQKA55.js → chunk-JN444Z5S.js} +505 -44
  22. package/dist/{chunk-IR7QV2BX.js → chunk-KV435YXO.js} +2 -2
  23. package/dist/{chunk-N4VIXI2Z.js → chunk-MWSBGJQO.js} +137 -18
  24. package/dist/{chunk-UHJLCPLU.js → chunk-OHTK7F3F.js} +96 -13
  25. package/dist/{chunk-SGSJ4DQA.js → chunk-QT3LX4FA.js} +321 -51
  26. package/dist/{chunk-NNPVA5VL.js → chunk-TQDQU2E3.js} +2 -2
  27. package/dist/{chunk-E5IBDE5E.js → chunk-V6XVZFFH.js} +2 -2
  28. package/dist/{chunk-RWERZWHR.js → chunk-YD2JE54B.js} +1 -1
  29. package/dist/{chunk-ZRHLLPSJ.js → chunk-YHZHPXDB.js} +85 -18
  30. package/dist/{chunk-HXHQA4BU.js → chunk-YIYM4ZAP.js} +1 -1
  31. package/dist/{chunk-LGWNN3L2.js → chunk-ZDOAUP3V.js} +2 -2
  32. package/dist/compare.d.cts +1 -1
  33. package/dist/compare.d.ts +1 -1
  34. package/dist/core/commands/formatting-commands.d.cts +2 -2
  35. package/dist/core/commands/formatting-commands.d.ts +2 -2
  36. package/dist/core/commands/image-commands.cjs +65 -20
  37. package/dist/core/commands/image-commands.d.cts +2 -2
  38. package/dist/core/commands/image-commands.d.ts +2 -2
  39. package/dist/core/commands/image-commands.js +5 -5
  40. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  41. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  42. package/dist/core/commands/style-commands.d.cts +2 -2
  43. package/dist/core/commands/style-commands.d.ts +2 -2
  44. package/dist/core/commands/table-structure-commands.cjs +65 -20
  45. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  46. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  47. package/dist/core/commands/table-structure-commands.js +4 -4
  48. package/dist/core/commands/text-commands.cjs +66 -21
  49. package/dist/core/commands/text-commands.d.cts +2 -2
  50. package/dist/core/commands/text-commands.d.ts +2 -2
  51. package/dist/core/commands/text-commands.js +5 -5
  52. package/dist/core/selection/mapping.d.cts +2 -2
  53. package/dist/core/selection/mapping.d.ts +2 -2
  54. package/dist/core/state/editor-state.d.cts +2 -2
  55. package/dist/core/state/editor-state.d.ts +2 -2
  56. package/dist/index.cjs +1347 -191
  57. package/dist/index.d.cts +5 -5
  58. package/dist/index.d.ts +5 -5
  59. package/dist/index.js +39 -21
  60. package/dist/io/docx-session.cjs +57 -18
  61. package/dist/io/docx-session.d.cts +4 -4
  62. package/dist/io/docx-session.d.ts +4 -4
  63. package/dist/io/docx-session.js +4 -4
  64. package/dist/legal.cjs +42 -10
  65. package/dist/legal.d.cts +1 -1
  66. package/dist/legal.d.ts +1 -1
  67. package/dist/legal.js +3 -3
  68. package/dist/{loader-D9y4ZRjj.d.ts → loader-B1MxvbeV.d.ts} +3 -3
  69. package/dist/{loader-D9KCtj4m.d.cts → loader-CJXsswcd.d.cts} +3 -3
  70. package/dist/{public-types-DajNGKV4.d.cts → public-types-BEGhv2YR.d.ts} +108 -6
  71. package/dist/{public-types-CNnMHZM9.d.ts → public-types-DrhlQ5Zy.d.cts} +108 -6
  72. package/dist/public-types.cjs +147 -35
  73. package/dist/public-types.d.cts +2 -2
  74. package/dist/public-types.d.ts +2 -2
  75. package/dist/public-types.js +3 -3
  76. package/dist/runtime/collab.d.cts +3 -3
  77. package/dist/runtime/collab.d.ts +3 -3
  78. package/dist/runtime/document-runtime.cjs +685 -98
  79. package/dist/runtime/document-runtime.d.cts +2 -2
  80. package/dist/runtime/document-runtime.d.ts +2 -2
  81. package/dist/runtime/document-runtime.js +14 -14
  82. package/dist/{session-DyQGlryH.d.cts → session-Bp3zqnkS.d.cts} +3 -3
  83. package/dist/{session-DEmaOEjA.d.ts → session-xMOU_NtL.d.ts} +3 -3
  84. package/dist/session.cjs +57 -18
  85. package/dist/session.d.cts +5 -5
  86. package/dist/session.d.ts +5 -5
  87. package/dist/session.js +5 -5
  88. package/dist/tailwind.cjs +238 -73
  89. package/dist/tailwind.d.cts +2 -2
  90. package/dist/tailwind.d.ts +2 -2
  91. package/dist/tailwind.js +7 -7
  92. package/dist/{types-DjJNaE9c.d.ts → types-BFT8536T.d.ts} +2 -2
  93. package/dist/{types-CxE1aZiv.d.cts → types-DDPxEygX.d.cts} +2 -2
  94. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  95. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  96. package/dist/ui-tailwind/editor-surface/search-plugin.js +4 -4
  97. package/dist/ui-tailwind.cjs +238 -73
  98. package/dist/ui-tailwind.d.cts +3 -3
  99. package/dist/ui-tailwind.d.ts +3 -3
  100. package/dist/ui-tailwind.js +7 -7
  101. package/package.json +2 -2
@@ -5525,7 +5525,7 @@ function createParagraphEditableTarget(paragraph, kind, storyKey2, blockPath, ta
5525
5525
  context: { storyKey: storyKey2, insideSdt: contentControl !== void 0 },
5526
5526
  ...tableTarget
5527
5527
  }) : void 0;
5528
- const listAddress = tableIdentity === void 0 && paragraph.numbering !== void 0 ? createCanonicalAddress({
5528
+ const listAddress = paragraph.numbering !== void 0 ? createCanonicalAddress({
5529
5529
  addressKind: "list-item-text",
5530
5530
  storyKey: storyKey2,
5531
5531
  staleCheckKind: "paragraph",
@@ -5559,6 +5559,7 @@ function createParagraphEditableTarget(paragraph, kind, storyKey2, blockPath, ta
5559
5559
  ...contentControl !== void 0 ? { contentControl } : {},
5560
5560
  ...tableIdentity !== void 0 ? { table: tableIdentity } : {},
5561
5561
  ...editableOwner !== void 0 ? { editableOwner } : {},
5562
+ ...listAddress !== void 0 ? { listAddress } : {},
5562
5563
  ...tableIdentity !== void 0 ? {
5563
5564
  canonicalAddress: createTableTargetCanonicalAddress(
5564
5565
  tableIdentity,
@@ -6422,6 +6423,9 @@ function validateEditableTargetRef(value, path = "$") {
6422
6423
  if (record.canonicalAddress !== void 0) {
6423
6424
  validateTargetCanonicalAddress(record.canonicalAddress, `${path}.canonicalAddress`, issues);
6424
6425
  }
6426
+ if (record.listAddress !== void 0) {
6427
+ validateTargetCanonicalAddress(record.listAddress, `${path}.listAddress`, issues);
6428
+ }
6425
6429
  const staleCheck = asPlainObject(record.staleCheck, `${path}.staleCheck`, issues);
6426
6430
  if (staleCheck) {
6427
6431
  if (staleCheck.paragraphTextHash !== void 0) {
@@ -9047,6 +9051,7 @@ function mergeLevelDefinition(base, override, startOverride, fallbackLevel) {
9047
9051
  );
9048
9052
  const runProperties = override?.runProperties ?? base?.runProperties;
9049
9053
  const restartAfterLevel = override?.restartAfterLevel ?? base?.restartAfterLevel;
9054
+ const picBulletId = override?.picBulletId ?? base?.picBulletId;
9050
9055
  return {
9051
9056
  level,
9052
9057
  format,
@@ -9057,7 +9062,8 @@ function mergeLevelDefinition(base, override, startOverride, fallbackLevel) {
9057
9062
  ...override?.suffix ?? base?.suffix ? { suffix: override?.suffix ?? base?.suffix } : {},
9058
9063
  ...paragraphGeometry ? { paragraphGeometry } : {},
9059
9064
  ...runProperties ? { runProperties } : {},
9060
- ...restartAfterLevel !== void 0 ? { restartAfterLevel } : {}
9065
+ ...restartAfterLevel !== void 0 ? { restartAfterLevel } : {},
9066
+ ...picBulletId !== void 0 ? { picBulletId } : {}
9061
9067
  };
9062
9068
  }
9063
9069
  function withDefaultStartAt(level) {
@@ -9185,7 +9191,7 @@ function resolveHangingWidth(indentation) {
9185
9191
  // src/runtime/formatting/numbering/prefix.ts
9186
9192
  function createNumberingPrefixResolver(catalog) {
9187
9193
  const sequenceStates = /* @__PURE__ */ new Map();
9188
- function resolveInternal(numbering, paragraph) {
9194
+ function resolveInternal(numbering, paragraph, options = {}) {
9189
9195
  const resolved = resolveNumberingDefinitionSet(
9190
9196
  catalog,
9191
9197
  paragraph?.numbering ?? numbering,
@@ -9198,29 +9204,44 @@ function createNumberingPrefixResolver(catalog) {
9198
9204
  if (!resolvedNumbering) {
9199
9205
  return null;
9200
9206
  }
9201
- const sequenceState = getSequenceState(sequenceStates, resolvedNumbering.numberingInstanceId);
9202
- advanceSequence(sequenceState, resolved.effectiveLevel.level, resolved.effectiveLevels);
9207
+ const advance = options.advance !== false;
9208
+ const sequenceState = getSequenceState(
9209
+ sequenceStates,
9210
+ resolvedNumbering.numberingInstanceId,
9211
+ { create: advance }
9212
+ );
9213
+ if (!sequenceState) {
9214
+ return null;
9215
+ }
9216
+ const workingState = advance ? sequenceState : cloneSequenceState(sequenceState);
9217
+ advanceSequence(workingState, resolved.effectiveLevel.level, resolved.effectiveLevels);
9218
+ const currentCounter = workingState.counters[resolved.effectiveLevel.level];
9203
9219
  const effectiveLevelDefs = resolved.effectiveLevel.isLegalNumbering ? new Map(
9204
9220
  Array.from(resolved.effectiveLevels.entries()).map(([level, definition]) => [
9205
9221
  level,
9206
9222
  { ...definition, format: "decimal" }
9207
9223
  ])
9208
9224
  ) : resolved.effectiveLevels;
9225
+ const picBulletId = resolved.effectiveLevel.picBulletId;
9209
9226
  const text = renderLevelText(
9210
9227
  resolved.effectiveLevel.text,
9211
- sequenceState.counters,
9228
+ workingState.counters,
9212
9229
  effectiveLevelDefs
9213
9230
  );
9214
- if (resolved.effectiveLevel.format !== "none" && text === null) {
9231
+ if (picBulletId == null && resolved.effectiveLevel.format !== "none" && text === null) {
9215
9232
  return null;
9216
9233
  }
9217
9234
  const visibleText = resolved.effectiveLevel.format === "none" ? null : text;
9218
- const picBulletId = resolved.effectiveLevel.picBulletId;
9235
+ const formatPosture = getNumberingFormatPosture(
9236
+ resolved.effectiveLevel.format,
9237
+ currentCounter
9238
+ );
9219
9239
  const picBulletMediaId = picBulletId != null ? catalog.numPicBullets?.[picBulletId]?.mediaId : void 0;
9220
9240
  return {
9221
9241
  text: visibleText,
9222
9242
  level: resolved.effectiveLevel.level,
9223
9243
  format: resolved.effectiveLevel.format,
9244
+ ...formatPosture !== void 0 ? { formatPosture } : {},
9224
9245
  startAt: resolved.effectiveLevel.startAt ?? DEFAULT_NUMBERING_START_AT,
9225
9246
  ...resolved.effectiveLevel.suffix ? { suffix: resolved.effectiveLevel.suffix } : {},
9226
9247
  ...resolved.effectiveLevel.paragraphStyleId ? { paragraphStyleId: resolved.effectiveLevel.paragraphStyleId } : {},
@@ -9231,23 +9252,26 @@ function createNumberingPrefixResolver(catalog) {
9231
9252
  };
9232
9253
  }
9233
9254
  return {
9234
- resolve(numbering) {
9235
- const result = resolveInternal(numbering);
9255
+ resolve(numbering, options) {
9256
+ const result = resolveInternal(numbering, void 0, options);
9236
9257
  return result?.text ?? null;
9237
9258
  },
9238
- resolveDetailed(numbering, paragraph) {
9239
- return resolveInternal(numbering, paragraph);
9259
+ resolveDetailed(numbering, paragraph, options) {
9260
+ return resolveInternal(numbering, paragraph, options);
9240
9261
  },
9241
- resolveParagraph(paragraph) {
9242
- return resolveInternal(paragraph.numbering, paragraph);
9262
+ resolveParagraph(paragraph, options) {
9263
+ return resolveInternal(paragraph.numbering, paragraph, options);
9243
9264
  }
9244
9265
  };
9245
9266
  }
9246
- function getSequenceState(states, numberingInstanceId) {
9267
+ function getSequenceState(states, numberingInstanceId, options = { create: true }) {
9247
9268
  const existing = states.get(numberingInstanceId);
9248
9269
  if (existing) {
9249
9270
  return existing;
9250
9271
  }
9272
+ if (options.create === false) {
9273
+ return { counters: [], lastLevel: null };
9274
+ }
9251
9275
  const created = {
9252
9276
  counters: [],
9253
9277
  lastLevel: null
@@ -9255,6 +9279,12 @@ function getSequenceState(states, numberingInstanceId) {
9255
9279
  states.set(numberingInstanceId, created);
9256
9280
  return created;
9257
9281
  }
9282
+ function cloneSequenceState(state) {
9283
+ return {
9284
+ counters: [...state.counters],
9285
+ lastLevel: state.lastLevel
9286
+ };
9287
+ }
9258
9288
  function advanceSequence(state, currentLevel, levelDefinitions) {
9259
9289
  for (let level = currentLevel + 1; level < state.counters.length; level += 1) {
9260
9290
  if (shouldResetDeeperLevel(level, currentLevel, levelDefinitions)) {
@@ -9286,6 +9316,25 @@ function shouldResetDeeperLevel(level, triggeringLevel, levelDefinitions) {
9286
9316
  function getLevelStartAt(level, levelDefinitions) {
9287
9317
  return levelDefinitions.get(level)?.startAt ?? DEFAULT_NUMBERING_START_AT;
9288
9318
  }
9319
+ function getNumberingFormatPosture(format, value) {
9320
+ if (!isSupportedNumberingFormat(format)) {
9321
+ return {
9322
+ status: "approximated",
9323
+ requestedFormat: format,
9324
+ renderedFormat: "decimal",
9325
+ reason: "unsupported-numbering-format-decimal-fallback"
9326
+ };
9327
+ }
9328
+ if (value !== void 0 && ((format === "upperRoman" || format === "lowerRoman") && (value <= 0 || value >= 4e3) || (format === "cardinalText" || format === "ordinalText") && (!Number.isInteger(value) || value < 1 || value > 999) || (format === "upperLetter" || format === "lowerLetter" || format === "chicago") && value < 1)) {
9329
+ return {
9330
+ status: "approximated",
9331
+ requestedFormat: format,
9332
+ renderedFormat: "decimal",
9333
+ reason: "numbering-format-range-decimal-fallback"
9334
+ };
9335
+ }
9336
+ return void 0;
9337
+ }
9289
9338
  function renderLevelText(text, counters, levelDefinitions) {
9290
9339
  if (!text) {
9291
9340
  return null;
@@ -10128,6 +10177,7 @@ function toNumberingLayoutInput(numbering) {
10128
10177
  associatedTabStops: toLayoutTabStops(numbering.geometry.tabStops, "numbering"),
10129
10178
  level: numbering.level,
10130
10179
  format: numbering.format,
10180
+ ...numbering.formatPosture !== void 0 ? { formatPosture: { ...numbering.formatPosture } } : {},
10131
10181
  startAt: numbering.startAt,
10132
10182
  ...numbering.isLegalNumbering ? { isLegalNumbering: true } : {},
10133
10183
  ...numbering.picBulletMediaId ? { pictureBulletMediaId: numbering.picBulletMediaId } : {}
@@ -10357,13 +10407,10 @@ var FormattingContextImpl = class {
10357
10407
  const effectiveNumbering = this.resolveEffectiveParagraphNumbering(para);
10358
10408
  if (!effectiveNumbering) return null;
10359
10409
  if (!emitGeometry) {
10360
- if (advance) this.numbering.resolve(effectiveNumbering);
10410
+ this.numbering.resolve(effectiveNumbering, { advance });
10361
10411
  return null;
10362
10412
  }
10363
- if (!advance) {
10364
- console.warn("[formatting-context] resolveParagraphNumbering({advance:false}) is not supported; counter always advances");
10365
- }
10366
- return this.numbering.resolveDetailed(effectiveNumbering, para);
10413
+ return this.numbering.resolveDetailed(effectiveNumbering, para, { advance });
10367
10414
  }
10368
10415
  resolveNumberingLayoutInput(para, options = {}) {
10369
10416
  return toNumberingLayoutInput(this.resolveParagraphNumbering(para, options));
@@ -12639,6 +12686,7 @@ function toSurfaceResolvedNumbering(numbering) {
12639
12686
  return {
12640
12687
  level: numbering.level,
12641
12688
  format: numbering.format,
12689
+ ...numbering.formatPosture !== void 0 ? { formatPosture: { ...numbering.formatPosture } } : {},
12642
12690
  ...numbering.text !== null ? { text: numbering.text } : {},
12643
12691
  startAt: numbering.startAt,
12644
12692
  ...numbering.paragraphStyleId ? { paragraphStyleId: numbering.paragraphStyleId } : {},
@@ -13653,7 +13701,7 @@ function parseCanonicalTextLeafPath(path) {
13653
13701
  if (normalized[offset] !== "/") return null;
13654
13702
  offset += 1;
13655
13703
  }
13656
- return tokens.some((token) => token.kind === "txbx") ? tokens : null;
13704
+ return tokens.length > 0 ? tokens : null;
13657
13705
  }
13658
13706
  function parseCanonicalHyperlinkPath(path) {
13659
13707
  const blockStart = path.indexOf("/block[");
@@ -19817,7 +19865,7 @@ function validateResult(result, context) {
19817
19865
  return { ...result, selection: validated };
19818
19866
  }
19819
19867
  function getPostMutationMaxOffset(result, context) {
19820
- if (typeof context.activeStorySize !== "number" || context.textTarget?.kind === "text-leaf") {
19868
+ if (typeof context.activeStorySize !== "number" || isTargetLocalTextLeaf(context.textTarget)) {
19821
19869
  return result.storyText.length;
19822
19870
  }
19823
19871
  let storySize = context.activeStorySize;
@@ -19826,6 +19874,9 @@ function getPostMutationMaxOffset(result, context) {
19826
19874
  }
19827
19875
  return Math.max(result.storyText.length, storySize);
19828
19876
  }
19877
+ function isTargetLocalTextLeaf(textTarget) {
19878
+ return textTarget?.kind === "text-leaf" && textTarget.blockPath.includes("/txbx/");
19879
+ }
19829
19880
  var editLayer = {
19830
19881
  applyTextInsert(doc, selection, text, context, formatting) {
19831
19882
  return validateResult(insertText(doc, selection, text, context, formatting), context);
@@ -24742,7 +24793,7 @@ function buildFormattingDebugEntry(inputs) {
24742
24793
  }
24743
24794
 
24744
24795
  // src/runtime/layout/layout-engine-version.ts
24745
- var LAYOUT_ENGINE_VERSION = 87;
24796
+ var LAYOUT_ENGINE_VERSION = 88;
24746
24797
 
24747
24798
  // src/runtime/layout/compat-input-ledger.ts
24748
24799
  var DEFAULT_COMPATIBILITY_MODE = 15;
@@ -24968,6 +25019,27 @@ function hitTestRegion(index, region, point) {
24968
25019
  (target2) => target2.regionId === region.regionId
24969
25020
  );
24970
25021
  const containing = targets.filter((target2) => containsPoint(target2.rect, point));
25022
+ const generatedTarget = containing.find(
25023
+ (target2) => target2.generatedContentKind === "numbering-marker"
25024
+ );
25025
+ if (generatedTarget) {
25026
+ const anchorHit2 = firstLineAnchor(index, generatedTarget)?.runtimeOffset !== void 0 ? {
25027
+ runtimeOffset: firstLineAnchor(index, generatedTarget).runtimeOffset,
25028
+ assoc: "before"
25029
+ } : resolveLineAnchorHit(index, generatedTarget, point);
25030
+ return {
25031
+ pageIndex: generatedTarget.pageIndex,
25032
+ regionKind: generatedTarget.regionKind,
25033
+ blockId: generatedTarget.blockId,
25034
+ fragmentId: generatedTarget.fragmentId,
25035
+ lineIndex: generatedTarget.lineIndex,
25036
+ runtimeOffset: anchorHit2?.runtimeOffset ?? 0,
25037
+ assoc: "before",
25038
+ generatedContentKind: generatedTarget.generatedContentKind,
25039
+ generatedContentBoundary: generatedTarget.generatedContentBoundary?.policy,
25040
+ semanticEntryId: generatedTarget.targetId.startsWith("hit:") ? generatedTarget.targetId.slice("hit:".length) : generatedTarget.targetId
25041
+ };
25042
+ }
24971
25043
  const target = nearestTarget(containing, point) ?? nearestTarget(targets, point);
24972
25044
  if (!target) return null;
24973
25045
  const anchorHit = resolveLineAnchorHit(index, target, point);
@@ -25344,6 +25416,7 @@ function projectGeometryIndexFromFrame(frame, options) {
25344
25416
  identities,
25345
25417
  storyKey: storyKey2,
25346
25418
  entries: semanticEntries,
25419
+ hitTargets,
25347
25420
  projectedBlocksByStory,
25348
25421
  projectedCommandTargetsByKey,
25349
25422
  precision,
@@ -25614,6 +25687,7 @@ function appendBlockSemanticEntries(input) {
25614
25687
  identities,
25615
25688
  storyKey: storyKey2,
25616
25689
  entries,
25690
+ hitTargets,
25617
25691
  projectedBlocksByStory,
25618
25692
  projectedCommandTargetsByKey,
25619
25693
  precision,
@@ -25643,6 +25717,7 @@ function appendBlockSemanticEntries(input) {
25643
25717
  block,
25644
25718
  sourceIdentity: sliceIdentity,
25645
25719
  entries,
25720
+ hitTargets,
25646
25721
  projectedCommandTargetsByKey,
25647
25722
  precision,
25648
25723
  frameCompleteness,
@@ -25824,6 +25899,7 @@ function appendFragmentLayoutObjectSemanticEntries(input) {
25824
25899
  block,
25825
25900
  sourceIdentity,
25826
25901
  entries,
25902
+ hitTargets,
25827
25903
  projectedCommandTargetsByKey,
25828
25904
  precision,
25829
25905
  frameCompleteness,
@@ -25908,18 +25984,57 @@ function appendFragmentLayoutObjectSemanticEntries(input) {
25908
25984
  }
25909
25985
  return;
25910
25986
  }
25911
- if (layoutObject.kind === "numbered-paragraph") {
25912
- const markerProjection = resolveNumberingMarkerProjection(block);
25987
+ const numberingRows = layoutObject.numberingRows && layoutObject.numberingRows.length > 0 ? layoutObject.numberingRows : layoutObject.kind === "numbered-paragraph" && layoutObject.numbering ? [layoutObject.numbering] : [];
25988
+ for (let index = 0; index < numberingRows.length; index += 1) {
25989
+ const numbering = numberingRows[index];
25990
+ const markerProjection = resolveNumberingMarkerProjection(block, numbering);
25991
+ const entryId = layoutObject.kind === "numbered-paragraph" && index === 0 ? `semantic:numbering-marker:${base.sliceId}` : `semantic:numbering-marker:${base.sliceId}:${stableGeometryId(
25992
+ numbering.numberingLayoutId ?? numbering.numberingKey ?? String(index)
25993
+ )}`;
25994
+ const source = numberingSourceIdentity(numbering, sourceIdentity);
25913
25995
  entries.push({
25914
25996
  ...base,
25915
- entryId: `semantic:numbering-marker:${base.sliceId}`,
25997
+ entryId,
25916
25998
  kind: "numbering-marker",
25917
25999
  layoutObjectId: layoutObject.objectId,
26000
+ numberingLayoutId: numbering.numberingLayoutId,
26001
+ numberingKey: numbering.numberingKey,
26002
+ numberingTargetKey: numbering.targetKey,
26003
+ numberingTargetKind: numbering.targetKind,
26004
+ numberingCanonicalAddressKey: numbering.canonicalAddressKey,
26005
+ numberingListAddressKey: numbering.listAddressKey,
26006
+ numberingMarkerText: numbering.markerText,
26007
+ numberingMarkerSuffix: numbering.markerSuffix,
26008
+ numberingFormat: numbering.format,
26009
+ numberingFormatPosture: numbering.formatPosture,
26010
+ numberingUnavailableReasons: numbering.unavailableReasons,
26011
+ markerGlyphRect: markerProjection.rect,
26012
+ markerLaneRect: markerProjection.markerLaneRect,
26013
+ textColumnRect: markerProjection.textColumnRect,
26014
+ markerBoundary: markerProjection.markerBoundary,
25918
26015
  rect: markerProjection.rect,
25919
26016
  status: markerProjection.status,
25920
26017
  precision: markerProjection.precision,
25921
26018
  frameCompleteness,
25922
- ...sourceIdentity ? { sourceIdentity } : {}
26019
+ ...source ? { sourceIdentity: source } : {}
26020
+ });
26021
+ hitTargets.push({
26022
+ targetId: `hit:${entryId}`,
26023
+ pageId: base.pageId,
26024
+ pageIndex: base.pageIndex,
26025
+ regionId: base.regionId,
26026
+ regionKind: base.regionKind,
26027
+ blockId: base.blockId,
26028
+ fragmentId: base.fragmentId,
26029
+ lineIndex: firstLineIndex(block),
26030
+ rect: markerProjection.rect,
26031
+ precision: markerProjection.precision,
26032
+ generatedContentKind: "numbering-marker",
26033
+ generatedContentBoundary: {
26034
+ policy: "snap-to-authored-text",
26035
+ authoredTextStartsAtPx: markerProjection.markerBoundary.authoredTextStartsAtPx,
26036
+ selectionPolicy: "exclude-generated-marker"
26037
+ }
25923
26038
  });
25924
26039
  recordPrecision(precision, markerProjection.precision);
25925
26040
  }
@@ -26010,8 +26125,8 @@ function bookmarkRangeSourceIdentity(fact, fallback) {
26010
26125
  joinKind: "block-scoped"
26011
26126
  };
26012
26127
  }
26013
- function resolveNumberingMarkerProjection(block) {
26014
- const metadata = resolveNumberingMarkerProjectionMetadata(block);
26128
+ function resolveNumberingMarkerProjection(block, numbering) {
26129
+ const metadata = resolveNumberingMarkerProjectionMetadata(block, numbering);
26015
26130
  const blockFrame = block.frame;
26016
26131
  if (metadata.markerLane && metadata.measuredWidthTwips !== void 0) {
26017
26132
  const markerLane = metadata.markerLane;
@@ -26022,14 +26137,25 @@ function resolveNumberingMarkerProjection(block) {
26022
26137
  const rawRightPx = rawLeftPx + markerLane.widthTwips * pxPerTwip;
26023
26138
  const leftPx = clamp3(rawLeftPx, blockLeftPx, blockRightPx);
26024
26139
  const rightPx = clamp3(rawRightPx, leftPx, blockRightPx);
26025
- return {
26026
- rect: {
26027
- leftPx,
26028
- topPx: blockFrame.topPx,
26029
- widthPx: rightPx - leftPx,
26030
- heightPx: blockFrame.heightPx,
26031
- space: "frame",
26032
- precision: metadata.precision
26140
+ const markerLaneRect = {
26141
+ leftPx,
26142
+ topPx: blockFrame.topPx,
26143
+ widthPx: rightPx - leftPx,
26144
+ heightPx: blockFrame.heightPx,
26145
+ space: "frame",
26146
+ precision: metadata.precision
26147
+ };
26148
+ const textColumnRect = metadata.textColumn ? projectTextColumnRect(blockFrame, metadata.measuredWidthTwips, metadata.textColumn) : void 0;
26149
+ return {
26150
+ rect: markerLaneRect,
26151
+ markerLaneRect,
26152
+ ...textColumnRect ? { textColumnRect } : {},
26153
+ markerBoundary: {
26154
+ generatedContent: "numbering-marker",
26155
+ caretPolicy: "snap-to-authored-text",
26156
+ selectionPolicy: "exclude-marker-unless-list-item-action",
26157
+ coordinateSpace: "frame-px",
26158
+ ...textColumnRect ? { authoredTextStartsAtPx: textColumnRect.leftPx } : {}
26033
26159
  },
26034
26160
  precision: metadata.precision,
26035
26161
  status: metadata.status
@@ -26048,20 +26174,28 @@ function resolveNumberingMarkerProjection(block) {
26048
26174
  space: "frame",
26049
26175
  precision: metadata.precision
26050
26176
  },
26177
+ markerBoundary: {
26178
+ generatedContent: "numbering-marker",
26179
+ caretPolicy: "snap-to-authored-text",
26180
+ selectionPolicy: "exclude-marker-unless-list-item-action",
26181
+ coordinateSpace: "frame-px"
26182
+ },
26051
26183
  precision: metadata.precision,
26052
26184
  status: metadata.status
26053
26185
  };
26054
26186
  }
26055
- function resolveNumberingMarkerProjectionMetadata(block) {
26187
+ function resolveNumberingMarkerProjectionMetadata(block, numbering) {
26056
26188
  const blockFrame = block.frame;
26057
26189
  const layoutObject = block.fragment.layoutObject;
26058
- const markerLane = layoutObject?.kind === "numbered-paragraph" ? layoutObject.numbering?.markerLane : void 0;
26190
+ const markerLane = numbering?.markerLane ?? (layoutObject?.kind === "numbered-paragraph" ? layoutObject.numbering?.markerLane : void 0);
26191
+ const textColumn = numbering?.textColumn ?? (layoutObject?.kind === "numbered-paragraph" ? layoutObject.numbering?.textColumn : void 0);
26059
26192
  const measuredWidthTwips = layoutObject?.measuredExtentTwips.widthTwips;
26060
26193
  if (markerLane && markerLane.widthTwips > 0 && measuredWidthTwips !== void 0 && measuredWidthTwips > 0 && Number.isFinite(blockFrame.widthPx)) {
26061
26194
  return {
26062
26195
  precision: "within-tolerance",
26063
26196
  status: "realized",
26064
26197
  markerLane,
26198
+ ...textColumn ? { textColumn } : {},
26065
26199
  measuredWidthTwips
26066
26200
  };
26067
26201
  }
@@ -26070,6 +26204,42 @@ function resolveNumberingMarkerProjectionMetadata(block) {
26070
26204
  status: "requires-rehydration"
26071
26205
  };
26072
26206
  }
26207
+ function projectTextColumnRect(blockFrame, measuredWidthTwips, textColumn) {
26208
+ if (measuredWidthTwips <= 0 || !Number.isFinite(blockFrame.widthPx)) {
26209
+ return void 0;
26210
+ }
26211
+ const pxPerTwip = blockFrame.widthPx / measuredWidthTwips;
26212
+ const leftPx = blockFrame.leftPx + textColumn.startTwips * pxPerTwip;
26213
+ const rightInsetPx = (textColumn.rightTwips ?? 0) * pxPerTwip;
26214
+ const rightPx = blockFrame.leftPx + blockFrame.widthPx - rightInsetPx;
26215
+ if (rightPx < leftPx) return void 0;
26216
+ return {
26217
+ leftPx,
26218
+ topPx: blockFrame.topPx,
26219
+ widthPx: rightPx - leftPx,
26220
+ heightPx: blockFrame.heightPx,
26221
+ space: "frame",
26222
+ precision: "within-tolerance"
26223
+ };
26224
+ }
26225
+ function numberingSourceIdentity(numbering, fallback) {
26226
+ const storyKey2 = numbering.storyKey ?? fallback?.storyKey;
26227
+ if (!storyKey2) return fallback;
26228
+ return {
26229
+ storyKey: storyKey2,
26230
+ ...numbering.sourceBlockPath ?? fallback?.blockPath ? { blockPath: numbering.sourceBlockPath ?? fallback?.blockPath } : {},
26231
+ ...numbering.numberingKey ?? fallback?.scopeKey ? { scopeKey: numbering.numberingKey ?? fallback?.scopeKey } : {},
26232
+ ...numbering.numberingInstanceId ?? fallback?.scopeId ? { scopeId: numbering.numberingInstanceId ?? fallback?.scopeId } : {},
26233
+ ...numbering.numberingSourceRef ?? numbering.sourceRef ?? fallback?.sourceRef ? { sourceRef: numbering.numberingSourceRef ?? numbering.sourceRef ?? fallback?.sourceRef } : {},
26234
+ joinKind: "block-scoped"
26235
+ };
26236
+ }
26237
+ function stableGeometryId(value) {
26238
+ return value.replace(/[^A-Za-z0-9_.:-]+/gu, "_");
26239
+ }
26240
+ function firstLineIndex(block) {
26241
+ return block.lines[0]?.line.lineIndex ?? 0;
26242
+ }
26073
26243
  function countBlockSemanticEntries(block) {
26074
26244
  const counts = createPrecisionCounts();
26075
26245
  const layoutObject = block.fragment.layoutObject;
@@ -32259,6 +32429,24 @@ function refusalIdForPostureBlocker(target, blocker) {
32259
32429
  return "editable_target_opaque_content";
32260
32430
  case "synthetic-layout-cell":
32261
32431
  return "editable_target_synthetic_layout_cell";
32432
+ case "list-text-readback-missing":
32433
+ return "list_text_readback_missing";
32434
+ case "list-structure-command-missing":
32435
+ return "list_structure_command_missing";
32436
+ case "list-target-stale":
32437
+ return "list_target_stale";
32438
+ case "list-secondary-story-unsupported":
32439
+ return "list_secondary_story_unsupported";
32440
+ case "list-table-target-missing":
32441
+ return "list_table_target_missing";
32442
+ case "list-export-persistence-missing":
32443
+ return "list_export_persistence_missing";
32444
+ case "numbering-format-unsupported":
32445
+ return "numbering_format_unsupported";
32446
+ case "picture-bullet-preserve-only":
32447
+ return "picture_bullet_preserve_only";
32448
+ case "marker-geometry-unavailable":
32449
+ return "marker_geometry_unavailable";
32262
32450
  case "unmodeled-target":
32263
32451
  return target.commandFamily === "link-bookmark" ? "editable_target_linked_content_unmodeled" : "editable_target_unmodeled";
32264
32452
  }
@@ -32281,12 +32469,42 @@ function auditCategoryForPostureBlocker(target, blocker) {
32281
32469
  return target.commandFamily === "link-bookmark" ? "linked-content" : "unsupported-command";
32282
32470
  case "synthetic-layout-cell":
32283
32471
  return "synthetic-cell";
32472
+ case "list-target-stale":
32473
+ return "stale-ref";
32474
+ case "picture-bullet-preserve-only":
32475
+ case "list-export-persistence-missing":
32476
+ return "preserve-only";
32477
+ case "list-text-readback-missing":
32478
+ case "list-structure-command-missing":
32479
+ case "list-secondary-story-unsupported":
32480
+ case "list-table-target-missing":
32481
+ case "numbering-format-unsupported":
32482
+ case "marker-geometry-unavailable":
32483
+ return "unsupported-command";
32284
32484
  }
32285
32485
  }
32286
32486
  function messageForPostureBlocker(blocker) {
32287
32487
  switch (blocker) {
32288
32488
  case "synthetic-layout-cell":
32289
32489
  return "Hidden vertical-merge continuation or synthetic layout cells are not editable targets.";
32490
+ case "list-text-readback-missing":
32491
+ return "List text edits need an authoritative list-item text target before mutation.";
32492
+ case "list-structure-command-missing":
32493
+ return "List structure changes need a supported list command envelope before mutation.";
32494
+ case "list-target-stale":
32495
+ return "List target identity is stale for the current canonical document.";
32496
+ case "list-secondary-story-unsupported":
32497
+ return "List edits in this secondary story are not yet supported.";
32498
+ case "list-table-target-missing":
32499
+ return "Table-contained list item is missing a command-safe list target.";
32500
+ case "list-export-persistence-missing":
32501
+ return "List mutation is blocked until export/reopen persistence is available.";
32502
+ case "numbering-format-unsupported":
32503
+ return "Numbering format is unsupported for this list command.";
32504
+ case "picture-bullet-preserve-only":
32505
+ return "Picture bullet lists are preserve-only until picture bullet mutation is supported.";
32506
+ case "marker-geometry-unavailable":
32507
+ return "List marker geometry is unavailable for this target.";
32290
32508
  default:
32291
32509
  return void 0;
32292
32510
  }
@@ -33539,6 +33757,21 @@ function compileParagraphScope(entry, options = {}) {
33539
33757
  partial: true
33540
33758
  };
33541
33759
  }
33760
+ function storyKeyFromHandle(handle) {
33761
+ const target = handle.storyTarget;
33762
+ if (target.kind === "main") return "main";
33763
+ return null;
33764
+ }
33765
+ function textLeafEditableTargetHint(entry, semanticBlockRange) {
33766
+ const storyKey2 = storyKeyFromHandle(entry.handle);
33767
+ if (!storyKey2) return void 0;
33768
+ return {
33769
+ kind: "text-leaf",
33770
+ storyKey: storyKey2,
33771
+ blockPath: `${storyKey2}/block[${entry.blockIndex}]`,
33772
+ semanticBlockRange
33773
+ };
33774
+ }
33542
33775
  function compileParagraphReplacement(entry, proposed, options) {
33543
33776
  if (proposed.operation !== "replace" && proposed.operation !== "insert-before" && proposed.operation !== "insert-after") {
33544
33777
  return null;
@@ -33594,6 +33827,7 @@ function compileParagraphReplacement(entry, proposed, options) {
33594
33827
  {
33595
33828
  kind: stepKind,
33596
33829
  summary: stepKind === "text-replace" ? actionSummary : `suggest-mode ${actionSummary}`,
33830
+ ...textLeafEditableTargetHint(entry, blockRange) ? { editableTargetHint: textLeafEditableTargetHint(entry, blockRange) } : {},
33597
33831
  range: { from: operationRange.from, to: operationRange.to },
33598
33832
  text,
33599
33833
  ...proposed.formatting ? { formatting: proposed.formatting } : {}
@@ -33621,6 +33855,7 @@ function compileParagraphReplacement(entry, proposed, options) {
33621
33855
  {
33622
33856
  kind: "fragment-replace",
33623
33857
  summary: actionSummary,
33858
+ ...textLeafEditableTargetHint(entry, blockRange) ? { editableTargetHint: textLeafEditableTargetHint(entry, blockRange) } : {},
33624
33859
  range: { from: operationRange.from, to: operationRange.to },
33625
33860
  fragment
33626
33861
  }
@@ -35543,14 +35778,17 @@ function paragraphHasBookmarkId(paragraph, bookmarkId) {
35543
35778
  function commandActionHandleForAddress(commandFamily, address) {
35544
35779
  return address ? `scope-command:${commandFamily}:${address.addressKey}` : void 0;
35545
35780
  }
35546
- function withCommandAction(evidence, target) {
35547
- if (evidence.status !== "supported" || !target.canonicalAddress) return evidence;
35781
+ function withCommandAction(evidence, target, canonicalAddress = target.canonicalAddress) {
35782
+ if (evidence.status !== "supported" || !canonicalAddress) return evidence;
35548
35783
  return {
35549
35784
  ...evidence,
35550
- actionHandle: commandActionHandleForAddress(target.commandFamily, target.canonicalAddress),
35551
- canonicalAddress: target.canonicalAddress
35785
+ actionHandle: commandActionHandleForAddress(target.commandFamily, canonicalAddress),
35786
+ canonicalAddress
35552
35787
  };
35553
35788
  }
35789
+ function commandAddressForTarget(target, scopeKind) {
35790
+ return scopeKind === "list-item" && target.listAddress !== void 0 ? target.listAddress : target.canonicalAddress;
35791
+ }
35554
35792
  function runtimeTextCommandEvidence(target, workflowBlockers) {
35555
35793
  const shapeIssues = validateEditableTargetRef(target);
35556
35794
  if (shapeIssues.length > 0) {
@@ -35603,6 +35841,9 @@ var TABLE_TEXT_TARGET_KINDS2 = /* @__PURE__ */ new Set([
35603
35841
  var LIST_TEXT_TARGET_KINDS2 = /* @__PURE__ */ new Set([
35604
35842
  "paragraph-text",
35605
35843
  "sdt-paragraph-text",
35844
+ "table-cell-paragraph-text",
35845
+ "nested-table-cell-paragraph-text",
35846
+ "sdt-table-cell-paragraph-text",
35606
35847
  "secondary-story-paragraph-text"
35607
35848
  ]);
35608
35849
  function tableTextScopeReplacementPosture(target) {
@@ -35653,7 +35894,7 @@ function runtimeCommandEvidence(target, workflowBlockers, textCommand, scopeKind
35653
35894
  intents: commandIntentsForTarget(target, scopeKind),
35654
35895
  reason: textCommand.reason,
35655
35896
  ...textCommand.blockers ? { blockers: textCommand.blockers } : {}
35656
- }, target);
35897
+ }, target, commandAddressForTarget(target, scopeKind));
35657
35898
  }
35658
35899
  if (target.commandFamily === "comment-revision") {
35659
35900
  const isOpen = target.review?.status === "open";
@@ -43626,8 +43867,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43626
43867
  const perPageCounter = /* @__PURE__ */ new Map();
43627
43868
  const fieldRegionsByParagraphIndex = buildFieldRegionsByParagraphIndex(fieldRegions);
43628
43869
  const generatedTargets = buildGeneratedTargets(editableTargets);
43870
+ const numberingTargets = buildNumberingTargets(editableTargets);
43629
43871
  const bookmarkRanges = buildBookmarkRanges(editableTargets);
43630
- const numberingByParagraphIndex = buildNumberingByParagraphIndex(numberingInputs);
43872
+ const numberingIndex = buildNumberingInputIndex(numberingInputs);
43631
43873
  const pushFragment = (pageIndex, fragment) => {
43632
43874
  const existing = byPage.get(pageIndex);
43633
43875
  if (existing) {
@@ -43663,8 +43905,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43663
43905
  },
43664
43906
  fieldRegionsByParagraphIndex,
43665
43907
  generatedTargets,
43908
+ numberingTargets,
43666
43909
  bookmarkRanges,
43667
- numberingByParagraphIndex,
43910
+ numberingIndex,
43668
43911
  blockPath
43669
43912
  );
43670
43913
  continue;
@@ -43685,8 +43928,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43685
43928
  },
43686
43929
  fieldRegionsByParagraphIndex,
43687
43930
  generatedTargets,
43931
+ numberingTargets,
43688
43932
  bookmarkRanges,
43689
- numberingByParagraphIndex,
43933
+ numberingIndex,
43690
43934
  blockPath
43691
43935
  );
43692
43936
  continue;
@@ -43718,8 +43962,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43718
43962
  paginationRole: "whole",
43719
43963
  fieldRegionsByParagraphIndex,
43720
43964
  generatedTargets,
43965
+ numberingTargets,
43721
43966
  bookmarkRanges,
43722
- numberingByParagraphIndex,
43967
+ numberingIndex,
43723
43968
  blockPath
43724
43969
  }),
43725
43970
  ...columnIndex !== void 0 ? { columnIndex } : {}
@@ -43866,7 +44111,7 @@ function buildRunAnchorsForLine(input) {
43866
44111
  }
43867
44112
  return anchors;
43868
44113
  }
43869
- function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], bookmarkRanges = [], numberingByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
44114
+ function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], numberingTargets = [], bookmarkRanges = [], numberingIndex = EMPTY_NUMBERING_INPUT_INDEX, blockPath) {
43870
44115
  for (let i = 0; i < slices.length; i += 1) {
43871
44116
  const slice = slices[i];
43872
44117
  const heightTwips = slice.heightTwips ?? estimateSliceHeightFromLines(slice.lineRange);
@@ -43891,8 +44136,9 @@ function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex =
43891
44136
  paginationRole: slice.lineRange.from > 0 ? "continuation" : "slice",
43892
44137
  fieldRegionsByParagraphIndex,
43893
44138
  generatedTargets,
44139
+ numberingTargets,
43894
44140
  bookmarkRanges,
43895
- numberingByParagraphIndex,
44141
+ numberingIndex,
43896
44142
  blockPath
43897
44143
  })
43898
44144
  };
@@ -43913,7 +44159,7 @@ function estimateSliceHeightFromLines(lineRange) {
43913
44159
  const lines = Math.max(0, lineRange.to - lineRange.from);
43914
44160
  return lines * 240;
43915
44161
  }
43916
- function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], bookmarkRanges = [], numberingByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
44162
+ function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], numberingTargets = [], bookmarkRanges = [], numberingIndex = EMPTY_NUMBERING_INPUT_INDEX, blockPath) {
43917
44163
  for (let i = 0; i < slices.length; i += 1) {
43918
44164
  const slice = slices[i];
43919
44165
  const heightTwips = slice.heightTwips ?? estimateSliceHeightFromRows(slice.rowRange);
@@ -43937,8 +44183,9 @@ function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /*
43937
44183
  paginationRole: slice.rowRange.from > 0 ? "continuation" : "slice",
43938
44184
  fieldRegionsByParagraphIndex,
43939
44185
  generatedTargets,
44186
+ numberingTargets,
43940
44187
  bookmarkRanges,
43941
- numberingByParagraphIndex,
44188
+ numberingIndex,
43942
44189
  blockPath
43943
44190
  }),
43944
44191
  ...slice.columnIndex !== void 0 ? { columnIndex: slice.columnIndex } : {}
@@ -44012,7 +44259,8 @@ function buildFragmentLayoutObject(input) {
44012
44259
  const numberingRows = collectNumberingLayoutFactsForBlock(
44013
44260
  input.block,
44014
44261
  input.blockPath,
44015
- input.numberingByParagraphIndex
44262
+ input.numberingIndex,
44263
+ input.numberingTargets
44016
44264
  );
44017
44265
  const numbering = input.block.kind === "paragraph" ? numberingRows[0] : void 0;
44018
44266
  const fieldRegions = collectFieldRegionLayoutFacts(
@@ -44183,6 +44431,11 @@ function buildGeneratedTargets(targets) {
44183
44431
  (target) => target.kind === "field-result-text" || target.kind === "hyperlink-text" || target.kind === "hyperlink-destination" || target.kind === "bookmark-anchor" || target.kind === "bookmark-content-range"
44184
44432
  );
44185
44433
  }
44434
+ function buildNumberingTargets(targets) {
44435
+ return targets.filter(
44436
+ (target) => target.listAddress !== void 0 || target.canonicalAddress?.addressKind === "list-item-text"
44437
+ );
44438
+ }
44186
44439
  function buildBookmarkRanges(targets) {
44187
44440
  const anchors = /* @__PURE__ */ new Map();
44188
44441
  const contentRanges = /* @__PURE__ */ new Map();
@@ -44230,14 +44483,27 @@ function buildBookmarkRanges(targets) {
44230
44483
  }
44231
44484
  return ranges;
44232
44485
  }
44233
- function buildNumberingByParagraphIndex(numberingInputs) {
44486
+ var EMPTY_NUMBERING_INPUT_INDEX = {
44487
+ byNumberingKey: /* @__PURE__ */ new Map(),
44488
+ byBlockPath: /* @__PURE__ */ new Map(),
44489
+ byParagraphIndex: /* @__PURE__ */ new Map()
44490
+ };
44491
+ function buildNumberingInputIndex(numberingInputs) {
44492
+ const byNumberingKey = /* @__PURE__ */ new Map();
44493
+ const byBlockPath = /* @__PURE__ */ new Map();
44234
44494
  const byParagraph = /* @__PURE__ */ new Map();
44235
44495
  for (const input of numberingInputs) {
44496
+ if (!byNumberingKey.has(input.numberingKey)) {
44497
+ byNumberingKey.set(input.numberingKey, input);
44498
+ }
44499
+ if (!byBlockPath.has(input.blockPath)) {
44500
+ byBlockPath.set(input.blockPath, input);
44501
+ }
44236
44502
  if (!byParagraph.has(input.paragraphIndex)) {
44237
44503
  byParagraph.set(input.paragraphIndex, input);
44238
44504
  }
44239
44505
  }
44240
- return byParagraph;
44506
+ return { byNumberingKey, byBlockPath, byParagraphIndex: byParagraph };
44241
44507
  }
44242
44508
  function collectBookmarkRangeLayoutFacts(fragmentId, blockPath, bookmarkRanges) {
44243
44509
  if (!blockPath || !bookmarkRanges || bookmarkRanges.length === 0) return [];
@@ -44318,6 +44584,7 @@ function collectNumberingLayoutFacts(block) {
44318
44584
  ...block.numbering?.numberingInstanceId !== void 0 ? { numberingInstanceId: block.numbering.numberingInstanceId } : {},
44319
44585
  ...block.numbering?.level !== void 0 ? { level: block.numbering.level } : {},
44320
44586
  ...block.resolvedNumbering?.format !== void 0 ? { format: block.resolvedNumbering.format } : {},
44587
+ ...block.resolvedNumbering?.formatPosture !== void 0 ? { formatPosture: { ...block.resolvedNumbering.formatPosture } } : {},
44321
44588
  ...block.numberingPrefix !== void 0 ? { markerText: block.numberingPrefix } : {},
44322
44589
  ...block.numberingSuffix !== void 0 ? { markerSuffix: block.numberingSuffix } : {},
44323
44590
  ...block.resolvedNumbering?.geometry.markerJustification !== void 0 ? { markerJustification: block.resolvedNumbering.geometry.markerJustification } : {},
@@ -44345,15 +44612,21 @@ function collectNumberingLayoutFacts(block) {
44345
44612
  } : {}
44346
44613
  };
44347
44614
  }
44348
- function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagraphIndex) {
44615
+ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingIndex, numberingTargets = []) {
44349
44616
  const rows = [];
44350
44617
  const seen = /* @__PURE__ */ new Set();
44351
44618
  visitParagraphBlocks(block, (paragraph, context) => {
44352
44619
  const numbering = collectNumberingLayoutFacts(paragraph);
44353
44620
  if (!numbering) return;
44354
44621
  const paragraphIndex = parseParagraphBlockIndex(paragraph.blockId);
44355
- const canonical = paragraphIndex !== void 0 ? numberingByParagraphIndex?.get(paragraphIndex) : void 0;
44356
44622
  const numberingKey = context.path !== void 0 ? `main:${context.path}:numbering` : void 0;
44623
+ const canonical = lookupNumberingInput(
44624
+ numberingIndex,
44625
+ numberingKey,
44626
+ context.path,
44627
+ paragraphIndex
44628
+ );
44629
+ const target = findNumberingTarget(numberingTargets, context.path);
44357
44630
  const numberingLayoutId = numberingKey ?? [
44358
44631
  "numbering",
44359
44632
  paragraph.blockId,
@@ -44362,6 +44635,7 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagr
44362
44635
  ].join(":");
44363
44636
  if (seen.has(numberingLayoutId)) return;
44364
44637
  seen.add(numberingLayoutId);
44638
+ const unavailableReasons = collectNumberingUnavailableReasons(numbering, canonical);
44365
44639
  rows.push({
44366
44640
  numberingLayoutId,
44367
44641
  ...numberingKey !== void 0 ? { numberingKey } : {},
@@ -44369,6 +44643,10 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagr
44369
44643
  ...canonical?.blockPath !== void 0 ? { sourceBlockPath: canonical.blockPath } : context.path !== void 0 ? { sourceBlockPath: context.path } : {},
44370
44644
  sourceBlockId: paragraph.blockId,
44371
44645
  ...paragraphIndex !== void 0 ? { paragraphIndex } : {},
44646
+ ...target?.targetKey !== void 0 ? { targetKey: target.targetKey } : {},
44647
+ ...target?.kind !== void 0 ? { targetKind: target.kind } : {},
44648
+ ...target?.canonicalAddress?.addressKey !== void 0 ? { canonicalAddressKey: target.canonicalAddress.addressKey } : {},
44649
+ ...target?.listAddress?.addressKey !== void 0 ? { listAddressKey: target.listAddress.addressKey } : {},
44372
44650
  ...canonical?.sourceRef !== void 0 ? { sourceRef: { ...canonical.sourceRef } } : {},
44373
44651
  ...canonical?.numberingSourceRef !== void 0 ? { numberingSourceRef: { ...canonical.numberingSourceRef } } : {},
44374
44652
  ...canonical?.numberingOrigin !== void 0 ? { numberingOrigin: canonical.numberingOrigin } : {},
@@ -44376,11 +44654,41 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagr
44376
44654
  ...canonical?.numberingInstanceSourceRef !== void 0 ? { numberingInstanceSourceRef: { ...canonical.numberingInstanceSourceRef } } : {},
44377
44655
  ...canonical?.abstractNumberingId !== void 0 ? { abstractNumberingId: canonical.abstractNumberingId } : {},
44378
44656
  ...canonical?.abstractNumberingSourceRef !== void 0 ? { abstractNumberingSourceRef: { ...canonical.abstractNumberingSourceRef } } : {},
44379
- ...numbering
44657
+ ...numbering,
44658
+ ...unavailableReasons.length > 0 ? { unavailableReasons } : {}
44380
44659
  });
44381
44660
  }, blockPath);
44382
44661
  return rows;
44383
44662
  }
44663
+ function findNumberingTarget(numberingTargets, blockPath) {
44664
+ if (blockPath === void 0) return void 0;
44665
+ return numberingTargets.find((target) => target.blockPath === blockPath);
44666
+ }
44667
+ function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraphIndex) {
44668
+ if (!numberingIndex) return void 0;
44669
+ if (numberingKey !== void 0) {
44670
+ const byKey = numberingIndex.byNumberingKey.get(numberingKey);
44671
+ if (byKey !== void 0) return byKey;
44672
+ }
44673
+ if (blockPath !== void 0) {
44674
+ const byPath = numberingIndex.byBlockPath.get(blockPath);
44675
+ if (byPath !== void 0) return byPath;
44676
+ }
44677
+ return paragraphIndex !== void 0 ? numberingIndex.byParagraphIndex.get(paragraphIndex) : void 0;
44678
+ }
44679
+ function collectNumberingUnavailableReasons(numbering, canonical) {
44680
+ const reasons = [];
44681
+ if (canonical === void 0) {
44682
+ reasons.push("canonical-numbering-input-missing");
44683
+ }
44684
+ if (numbering.markerLane === void 0) {
44685
+ reasons.push("numbering-marker-lane-unavailable");
44686
+ }
44687
+ if (numbering.textColumn === void 0) {
44688
+ reasons.push("numbering-text-column-unavailable");
44689
+ }
44690
+ return reasons;
44691
+ }
44384
44692
  function findPageIndexForOffset(pages, offset) {
44385
44693
  for (let i = 0; i < pages.length; i += 1) {
44386
44694
  const page = pages[i];
@@ -48354,6 +48662,16 @@ function createLayoutFacet(input) {
48354
48662
  function currentGraph() {
48355
48663
  return engine.getPageGraph(getQueryInput());
48356
48664
  }
48665
+ function fullGraphForViewportIndependentReads() {
48666
+ const query = getQueryInput();
48667
+ if (!query.viewportPageWindow) {
48668
+ return engine.getPageGraph(query);
48669
+ }
48670
+ return engine.getPageGraph({
48671
+ document: query.document,
48672
+ ...query.viewState ? { viewState: query.viewState } : {}
48673
+ });
48674
+ }
48357
48675
  function currentMapper() {
48358
48676
  return engine.getFragmentMapper(getQueryInput());
48359
48677
  }
@@ -48491,7 +48809,7 @@ function createLayoutFacet(input) {
48491
48809
  return graph.sections.map((section) => toPublicSectionNode(graph, section.index)).filter((node) => node !== null);
48492
48810
  },
48493
48811
  getPageForOffset(offset, story) {
48494
- const graph = currentGraph();
48812
+ const graph = fullGraphForViewportIndependentReads();
48495
48813
  const page = findPageForOffsetAndStory(graph, offset, story);
48496
48814
  return page ? toPublicPageNode(page, graph) : null;
48497
48815
  },
@@ -48803,7 +49121,7 @@ function createLayoutFacet(input) {
48803
49121
  return null;
48804
49122
  },
48805
49123
  getBlockHeightsTwips() {
48806
- const graph = currentGraph();
49124
+ const graph = fullGraphForViewportIndependentReads();
48807
49125
  if (blockHeightsCache.revision === graph.revision && blockHeightsCache.map) {
48808
49126
  return blockHeightsCache.map;
48809
49127
  }
@@ -52297,19 +52615,19 @@ function locateTargetRange(document2, surface, target) {
52297
52615
  if (!sdt || sdt.kind !== "sdt_block") return null;
52298
52616
  const paragraph = sdt.children[sdtPath.childIndex];
52299
52617
  if (!paragraph || paragraph.kind !== "paragraph") return null;
52300
- return { from: paragraph.from, to: paragraph.to };
52618
+ return textLeafTargetRange(target, paragraph.from, paragraph.to);
52301
52619
  }
52302
52620
  const paragraphPath = parseTopLevelParagraphPath(target.blockPath);
52303
52621
  if (paragraphPath) {
52304
52622
  const paragraph = surface[paragraphPath.blockIndex];
52305
52623
  if (!paragraph || paragraph.kind !== "paragraph") return null;
52306
- return { from: paragraph.from, to: paragraph.to };
52624
+ return textLeafTargetRange(target, paragraph.from, paragraph.to);
52307
52625
  }
52308
52626
  const secondaryParagraphPath = parseSecondaryStoryParagraphPath(target.blockPath);
52309
52627
  if (secondaryParagraphPath) {
52310
52628
  const paragraph = surface[secondaryParagraphPath.blockIndex];
52311
52629
  if (!paragraph || paragraph.kind !== "paragraph") return null;
52312
- return { from: paragraph.from, to: paragraph.to };
52630
+ return textLeafTargetRange(target, paragraph.from, paragraph.to);
52313
52631
  }
52314
52632
  if (target.kind === "textbox-paragraph-text") {
52315
52633
  return {
@@ -52325,6 +52643,18 @@ function locateTargetRange(document2, surface, target) {
52325
52643
  }
52326
52644
  return null;
52327
52645
  }
52646
+ function textLeafTargetRange(target, from, to) {
52647
+ return {
52648
+ from,
52649
+ to,
52650
+ textTarget: {
52651
+ kind: "text-leaf",
52652
+ blockPath: target.blockPath,
52653
+ paragraphStart: from,
52654
+ paragraphEnd: to
52655
+ }
52656
+ };
52657
+ }
52328
52658
  function locateHyperlinkDisplayRange(document2, surface, target) {
52329
52659
  const canonical = resolveHyperlinkDisplayPath(document2, target.blockPath);
52330
52660
  if (!canonical) return null;
@@ -52705,6 +53035,8 @@ function sortJson(value) {
52705
53035
 
52706
53036
  // src/runtime/document-runtime.ts
52707
53037
  var CANONICAL_BLOCK_REFS_SYMBOL2 = /* @__PURE__ */ Symbol.for("wre.canonical-block-refs");
53038
+ var LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES = 5e3;
53039
+ var LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK = 256;
52708
53040
  function getLocalTextPatchMetadata(mapping) {
52709
53041
  const metadata = mapping.metadata?.localTextPatch;
52710
53042
  if (!metadata || typeof metadata !== "object") {
@@ -52877,8 +53209,10 @@ function createDocumentRuntime(options) {
52877
53209
  void upgradeMeasurementProvider(layoutEngine, fontLoader);
52878
53210
  let renderKernelRef = null;
52879
53211
  let runtimeRef = null;
53212
+ const normalizedInitialSurfaceViewportRanges = options.initialSurfaceViewportBlockRanges && options.initialSurfaceViewportBlockRanges.length > 0 ? normalizeViewportRanges(options.initialSurfaceViewportBlockRanges) : null;
53213
+ let initialSurfaceViewportBlockRanges = normalizedInitialSurfaceViewportRanges && normalizedInitialSurfaceViewportRanges.length > 0 ? normalizedInitialSurfaceViewportRanges : null;
52880
53214
  let viewportBlockRanges = null;
52881
- let viewportRangesKey = serializeViewportRanges(null);
53215
+ let viewportRangesKey = serializeViewportRanges(viewportBlockRanges);
52882
53216
  let viewportBlocksPerPageEstimate = null;
52883
53217
  const EDITING_CORRIDOR_BLOCK_RADIUS = 8;
52884
53218
  const getRuntimeForLayoutFacet = () => {
@@ -53118,10 +53452,11 @@ function createDocumentRuntime(options) {
53118
53452
  const cachedContextAnalyticsSnapshots = /* @__PURE__ */ new Map();
53119
53453
  let lastEmittedContextAnalyticsSnapshots;
53120
53454
  function getCachedFullSurface(document2, nextActiveStory) {
53121
- const activeStoryKey = storyTargetKey(nextActiveStory);
53122
- 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) {
53123
- return cachedFullSurface.snapshot;
53455
+ const cached = getReusableCachedFullSurface(document2, nextActiveStory);
53456
+ if (cached) {
53457
+ return cached;
53124
53458
  }
53459
+ const activeStoryKey = storyTargetKey(nextActiveStory);
53125
53460
  const snapshot = createEditorSurfaceSnapshot(document2, state.selection, nextActiveStory, {
53126
53461
  viewportBlockRanges: null,
53127
53462
  editableTargetsByBlockPath: getEditableTargetsByBlockPath(document2),
@@ -53143,6 +53478,13 @@ function createDocumentRuntime(options) {
53143
53478
  };
53144
53479
  return snapshot;
53145
53480
  }
53481
+ function getReusableCachedFullSurface(document2, nextActiveStory) {
53482
+ const activeStoryKey = storyTargetKey(nextActiveStory);
53483
+ 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) {
53484
+ return cachedFullSurface.snapshot;
53485
+ }
53486
+ return void 0;
53487
+ }
53146
53488
  function getCachedSurface(document2, nextActiveStory, options2 = {}) {
53147
53489
  const activeStoryKey = storyTargetKey(nextActiveStory);
53148
53490
  const surfaceViewportRanges = "viewportBlockRangesOverride" in options2 ? options2.viewportBlockRangesOverride ?? null : viewportBlockRanges;
@@ -53153,12 +53495,20 @@ function createDocumentRuntime(options) {
53153
53495
  }
53154
53496
  const snapshot = createEditorSurfaceSnapshot(document2, state.selection, nextActiveStory, {
53155
53497
  viewportBlockRanges: surfaceViewportRanges,
53156
- editableTargetsByBlockPath: options2.editableTargetsByBlockPathOverride ?? getEditableTargetsByBlockPath(document2),
53498
+ editableTargetsByBlockPath: options2.editableTargetsByBlockPathOverride ?? getEditableTargetsByBlockPathForRanges(
53499
+ document2,
53500
+ activeStoryKey,
53501
+ surfaceViewportRanges
53502
+ ),
53157
53503
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
53158
53504
  });
53159
53505
  recordPerfSample("snapshot.surface");
53160
53506
  incrementInvalidationCounter("runtime.snapshot.surfaceMisses");
53161
- const enrichedSnapshot = options2.enrichCulledPlaceholders === false ? snapshot : enrichCulledPlaceholdersWithHeights(snapshot);
53507
+ const enrichedSnapshot = options2.enrichCulledPlaceholders === false ? snapshot : enrichCulledPlaceholdersWithHeights(
53508
+ snapshot,
53509
+ document2,
53510
+ nextActiveStory
53511
+ );
53162
53512
  if (surfaceViewportRanges === null) {
53163
53513
  cachedFullSurface = {
53164
53514
  content: document2.content,
@@ -53216,7 +53566,7 @@ function createDocumentRuntime(options) {
53216
53566
  }
53217
53567
  return -1;
53218
53568
  }
53219
- function cachePatchedLocalTextSurface(surface) {
53569
+ function cachePatchedLocalTextSurface(surface, fullSurfaceForCache) {
53220
53570
  const activeStoryKey = storyTargetKey(activeStory);
53221
53571
  const rangesKey = serializeViewportRanges(surface.viewportBlockRanges);
53222
53572
  cachedSurface = {
@@ -53232,7 +53582,8 @@ function createDocumentRuntime(options) {
53232
53582
  viewportRangesKey: rangesKey,
53233
53583
  snapshot: surface
53234
53584
  };
53235
- if (surface.viewportBlockRanges === null) {
53585
+ const fullSurface = fullSurfaceForCache ?? (surface.viewportBlockRanges === null ? surface : void 0);
53586
+ if (fullSurface) {
53236
53587
  cachedFullSurface = {
53237
53588
  content: state.document.content,
53238
53589
  subParts: state.document.subParts,
@@ -53243,11 +53594,15 @@ function createDocumentRuntime(options) {
53243
53594
  review: state.document.review,
53244
53595
  effectiveMarkupModeProvider,
53245
53596
  activeStoryKey,
53246
- snapshot: surface
53597
+ snapshot: fullSurface
53247
53598
  };
53248
53599
  }
53249
53600
  cachedSurfaceFingerprint = `${activeStoryKey}|${rangesKey}|${String(state.selection.anchor)}:${String(state.selection.head)}`;
53250
53601
  }
53602
+ function createLocalTextCorridorSurfaceFromFullSurface(fullSurface) {
53603
+ const ranges = getSelectionCorridorViewportRanges(fullSurface);
53604
+ return ranges ? createViewportCulledSurfaceFromFullSurface(fullSurface, ranges) : fullSurface;
53605
+ }
53251
53606
  function tryPatchLocalTextSurface(previousSurface, mapping) {
53252
53607
  const tTotal0 = performance.now();
53253
53608
  try {
@@ -53283,6 +53638,13 @@ function createDocumentRuntime(options) {
53283
53638
  perfCounters.increment("surface.localText.patchMiss");
53284
53639
  return null;
53285
53640
  }
53641
+ const shiftBudget = estimateLocalTextPatchShiftBudget(previousSurface.blocks, blockIndex + 1);
53642
+ perfCounters.increment("surface.localText.shiftedBlocks", shiftBudget.shiftedBlocks);
53643
+ perfCounters.increment("surface.localText.shiftedNodes", shiftBudget.shiftedNodes);
53644
+ if (!shiftBudget.withinBudget) {
53645
+ perfCounters.increment("surface.localText.patchBudgetFallback");
53646
+ return null;
53647
+ }
53286
53648
  const segmentIndex = block.segments.findIndex(
53287
53649
  (segment2) => segment2.kind === "text" && editFrom >= segment2.from && editTo <= segment2.to
53288
53650
  );
@@ -53390,7 +53752,83 @@ function createDocumentRuntime(options) {
53390
53752
  };
53391
53753
  }
53392
53754
  }
53393
- function enrichCulledPlaceholdersWithHeights(snapshot) {
53755
+ function estimateLocalTextPatchShiftBudget(blocks, startIndex) {
53756
+ const shiftedBlocks = Math.max(0, blocks.length - startIndex);
53757
+ let shiftedNodes = 0;
53758
+ for (let index = startIndex; index < blocks.length; index += 1) {
53759
+ const shiftedBlockNodes = countSurfaceShiftNodesUpTo(
53760
+ blocks[index],
53761
+ Math.min(
53762
+ LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK,
53763
+ LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES - shiftedNodes
53764
+ ) + 1
53765
+ );
53766
+ shiftedNodes += shiftedBlockNodes;
53767
+ if (shiftedBlockNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK) {
53768
+ return {
53769
+ shiftedBlocks,
53770
+ shiftedNodes,
53771
+ withinBudget: false
53772
+ };
53773
+ }
53774
+ if (shiftedNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES) {
53775
+ return {
53776
+ shiftedBlocks,
53777
+ shiftedNodes,
53778
+ withinBudget: false
53779
+ };
53780
+ }
53781
+ }
53782
+ return {
53783
+ shiftedBlocks,
53784
+ shiftedNodes,
53785
+ withinBudget: true
53786
+ };
53787
+ }
53788
+ function countSurfaceShiftNodesUpTo(block, limit) {
53789
+ if (limit <= 0) {
53790
+ return 1;
53791
+ }
53792
+ switch (block.kind) {
53793
+ case "paragraph":
53794
+ return 1 + block.segments.length;
53795
+ case "opaque_block":
53796
+ return 1;
53797
+ case "sdt_block": {
53798
+ let total = 1;
53799
+ for (const child of block.children) {
53800
+ total += countSurfaceShiftNodesUpTo(child, limit - total);
53801
+ if (total > limit) {
53802
+ return total;
53803
+ }
53804
+ }
53805
+ return total;
53806
+ }
53807
+ case "table": {
53808
+ let total = 1;
53809
+ for (const row2 of block.rows) {
53810
+ total += 1;
53811
+ if (total > limit) {
53812
+ return total;
53813
+ }
53814
+ for (const cell of row2.cells) {
53815
+ total += 1;
53816
+ if (total > limit) {
53817
+ return total;
53818
+ }
53819
+ for (const child of cell.content) {
53820
+ total += countSurfaceShiftNodesUpTo(child, limit - total);
53821
+ if (total > limit) {
53822
+ return total;
53823
+ }
53824
+ }
53825
+ }
53826
+ }
53827
+ return total;
53828
+ }
53829
+ }
53830
+ }
53831
+ function enrichCulledPlaceholdersWithHeights(snapshot, document2, nextActiveStory, fullSurfaceForPlaceholders) {
53394
53832
  let heights;
53395
53833
  try {
53396
53834
  heights = layoutFacet.getBlockHeightsTwips();
@@ -53398,17 +53836,19 @@ function createDocumentRuntime(options) {
53398
53836
  return snapshot;
53399
53837
  }
53400
53838
  if (heights.size === 0) return snapshot;
53839
+ const fullSurface = fullSurfaceForPlaceholders ?? getReusableCachedFullSurface(document2, nextActiveStory);
53840
+ if (!fullSurface) return snapshot;
53401
53841
  let changed = false;
53402
53842
  const enrichedBlocks = snapshot.blocks.map((block) => {
53403
53843
  if (block.kind !== "opaque_block" || block.state !== "placeholder-culled") {
53404
53844
  return block;
53405
53845
  }
53406
- const realBlockIdFromOffset = resolveBlockIdFromRuntimeOffset(
53407
- layoutFacet,
53408
- block.from
53846
+ const realBlock = resolveFullSurfaceBlockForPlaceholder(
53847
+ fullSurface,
53848
+ block
53409
53849
  );
53410
- if (!realBlockIdFromOffset) return block;
53411
- const heightTwips = heights.get(realBlockIdFromOffset);
53850
+ if (!realBlock) return block;
53851
+ const heightTwips = heights.get(realBlock.blockId);
53412
53852
  if (typeof heightTwips !== "number" || heightTwips <= 0) return block;
53413
53853
  changed = true;
53414
53854
  return { ...block, placeholderHeightTwips: heightTwips };
@@ -53416,13 +53856,20 @@ function createDocumentRuntime(options) {
53416
53856
  if (!changed) return snapshot;
53417
53857
  return { ...snapshot, blocks: enrichedBlocks };
53418
53858
  }
53419
- function resolveBlockIdFromRuntimeOffset(facet, runtimeOffset) {
53420
- try {
53421
- const frag = facet.getFragmentForOffset?.(runtimeOffset);
53422
- return frag?.blockId ?? null;
53423
- } catch {
53424
- return null;
53859
+ function resolveFullSurfaceBlockForPlaceholder(fullSurface, placeholder) {
53860
+ const index = parsePlaceholderCulledIndex(placeholder.blockId);
53861
+ if (index !== null) {
53862
+ return fullSurface.blocks[index] ?? null;
53425
53863
  }
53864
+ return fullSurface.blocks.find(
53865
+ (block) => block.from === placeholder.from && block.to === placeholder.to
53866
+ ) ?? null;
53867
+ }
53868
+ function parsePlaceholderCulledIndex(blockId) {
53869
+ const match = /^placeholder-culled-(\d+)$/.exec(blockId);
53870
+ if (!match) return null;
53871
+ const index = Number(match[1]);
53872
+ return Number.isSafeInteger(index) ? index : null;
53426
53873
  }
53427
53874
  function getCachedFieldSnapshot(document2) {
53428
53875
  const blockCount = document2.content.children.length;
@@ -53987,7 +54434,14 @@ function createDocumentRuntime(options) {
53987
54434
  revisionToken: state.revisionToken
53988
54435
  });
53989
54436
  perfCounters.increment("refresh.all");
53990
- const surface = timeFacet("surface", () => getCachedSurface(state.document, activeStory));
54437
+ const firstSurfaceViewportBlockRanges = initialSurfaceViewportBlockRanges;
54438
+ initialSurfaceViewportBlockRanges = null;
54439
+ const surface = timeFacet(
54440
+ "surface",
54441
+ () => firstSurfaceViewportBlockRanges ? getCachedSurface(state.document, activeStory, {
54442
+ viewportBlockRangesOverride: firstSurfaceViewportBlockRanges
54443
+ }) : getCachedSurface(state.document, activeStory)
54444
+ );
53991
54445
  const snapshot = {
53992
54446
  documentId: state.documentId,
53993
54447
  sessionId: state.sessionId,
@@ -54085,8 +54539,10 @@ function createDocumentRuntime(options) {
54085
54539
  if (options2.forceProjection) {
54086
54540
  cachedFullSurface = void 0;
54087
54541
  }
54088
- const newSurface = viewportBlockRanges !== null && options2.forceProjection !== true ? createViewportCulledSurfaceFromFullSurface(
54089
- getCachedFullSurface(state.document, activeStory),
54542
+ const reusableFullSurface = viewportBlockRanges !== null && options2.forceProjection !== true ? getReusableCachedFullSurface(state.document, activeStory) : void 0;
54543
+ const derivedFromFull = viewportBlockRanges !== null && reusableFullSurface !== void 0;
54544
+ const projectedSurface = derivedFromFull ? createViewportCulledSurfaceFromFullSurface(
54545
+ reusableFullSurface,
54090
54546
  viewportBlockRanges
54091
54547
  ) : createEditorSurfaceSnapshot(
54092
54548
  state.document,
@@ -54094,11 +54550,21 @@ function createDocumentRuntime(options) {
54094
54550
  activeStory,
54095
54551
  {
54096
54552
  viewportBlockRanges,
54097
- editableTargetsByBlockPath: getEditableTargetsByBlockPath(state.document),
54553
+ editableTargetsByBlockPath: getEditableTargetsByBlockPathForRanges(
54554
+ state.document,
54555
+ activeStoryKey,
54556
+ viewportBlockRanges
54557
+ ),
54098
54558
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
54099
54559
  }
54100
54560
  );
54101
- if (viewportBlockRanges !== null && options2.forceProjection !== true) {
54561
+ const newSurface = viewportBlockRanges !== null ? enrichCulledPlaceholdersWithHeights(
54562
+ projectedSurface,
54563
+ state.document,
54564
+ activeStory,
54565
+ reusableFullSurface
54566
+ ) : projectedSurface;
54567
+ if (derivedFromFull) {
54102
54568
  perfCounters.increment("runtime.viewport.derivedSurfaceRefreshes");
54103
54569
  } else {
54104
54570
  recordPerfSample("snapshot.surface");
@@ -55169,12 +55635,86 @@ function createDocumentRuntime(options) {
55169
55635
  }
55170
55636
  },
55171
55637
  applyScopeReplacement(plan) {
55638
+ const resolveEditableTargetHint = (hint) => {
55639
+ if (!hint) return void 0;
55640
+ const activeStoryKey = storyTargetKey(activeStory);
55641
+ if (hint.storyKey !== activeStoryKey) return null;
55642
+ const currentTargets = collectEditableTargetRefs(
55643
+ state.document,
55644
+ editableTargetBlockCache
55645
+ );
55646
+ const target = currentTargets.find(
55647
+ (target2) => target2.storyKey === hint.storyKey && target2.blockPath === hint.blockPath && target2.commandFamily === "text-leaf"
55648
+ );
55649
+ if (!target) return null;
55650
+ const fallbackTextTarget = {
55651
+ kind: "text-leaf",
55652
+ blockPath: target.blockPath,
55653
+ paragraphStart: hint.semanticBlockRange.from,
55654
+ paragraphEnd: hint.semanticBlockRange.to
55655
+ };
55656
+ const resolved = resolveEditableTextTarget({
55657
+ document: state.document,
55658
+ surface: cachedRenderSnapshot.surface?.blocks ?? [],
55659
+ target,
55660
+ activeStoryKey,
55661
+ editableTargetCache: editableTargetBlockCache
55662
+ });
55663
+ if (resolved.kind === "rejected") {
55664
+ return {
55665
+ textTarget: fallbackTextTarget,
55666
+ range: hint.semanticBlockRange
55667
+ };
55668
+ }
55669
+ return {
55670
+ target,
55671
+ textTarget: resolved.textTarget ?? fallbackTextTarget,
55672
+ range: resolved.range
55673
+ };
55674
+ };
55675
+ const mapSemanticStepRangeToEditableTarget = (stepRange, hint, editableRange) => {
55676
+ if (!hint || !editableRange) return stepRange;
55677
+ const semanticFrom = hint.semanticBlockRange.from;
55678
+ const semanticTo = hint.semanticBlockRange.to;
55679
+ const localFrom = Math.max(0, stepRange.from - semanticFrom);
55680
+ const localTo = Math.max(localFrom, stepRange.to - semanticFrom);
55681
+ const semanticLength = Math.max(0, semanticTo - semanticFrom);
55682
+ const editableLength = Math.max(0, editableRange.to - editableRange.from);
55683
+ if (semanticLength === editableLength) {
55684
+ return {
55685
+ from: editableRange.from + localFrom,
55686
+ to: editableRange.from + localTo
55687
+ };
55688
+ }
55689
+ if (stepRange.from === semanticFrom && stepRange.to === semanticTo) {
55690
+ return editableRange;
55691
+ }
55692
+ return stepRange;
55693
+ };
55172
55694
  for (const step of plan.steps) {
55173
55695
  if (step.kind === "text-replace" && step.range && typeof step.text === "string") {
55696
+ const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
55697
+ if (editableTarget === null) {
55698
+ emit({
55699
+ type: "command_blocked",
55700
+ documentId: state.documentId,
55701
+ command: "applyScopeReplacement",
55702
+ reasons: [{
55703
+ code: "unsupported_surface",
55704
+ message: "Scope replacement editable target no longer resolves."
55705
+ }]
55706
+ });
55707
+ continue;
55708
+ }
55709
+ const dispatchRange = mapSemanticStepRangeToEditableTarget(
55710
+ step.range,
55711
+ step.editableTargetHint,
55712
+ editableTarget?.range
55713
+ );
55174
55714
  const anchor = {
55175
55715
  kind: "range",
55176
- from: step.range.from,
55177
- to: step.range.to,
55716
+ from: dispatchRange.from,
55717
+ to: dispatchRange.to,
55178
55718
  assoc: { start: -1, end: 1 }
55179
55719
  };
55180
55720
  const timestamp = clock();
@@ -55183,6 +55723,8 @@ function createDocumentRuntime(options) {
55183
55723
  {
55184
55724
  type: "text.insert",
55185
55725
  text: step.text,
55726
+ ...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
55727
+ ...editableTarget?.textTarget ? { textTarget: editableTarget.textTarget } : {},
55186
55728
  ...step.formatting ? { formatting: step.formatting } : {},
55187
55729
  origin: createOrigin("api", timestamp)
55188
55730
  },
@@ -55220,10 +55762,28 @@ function createDocumentRuntime(options) {
55220
55762
  emitError(toRuntimeError(error));
55221
55763
  }
55222
55764
  } else if (step.kind === "text-insert-tracked" && step.range && typeof step.text === "string") {
55765
+ const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
55766
+ if (editableTarget === null) {
55767
+ emit({
55768
+ type: "command_blocked",
55769
+ documentId: state.documentId,
55770
+ command: "applyScopeReplacement",
55771
+ reasons: [{
55772
+ code: "unsupported_surface",
55773
+ message: "Scope replacement editable target no longer resolves."
55774
+ }]
55775
+ });
55776
+ continue;
55777
+ }
55778
+ const dispatchRange = mapSemanticStepRangeToEditableTarget(
55779
+ step.range,
55780
+ step.editableTargetHint,
55781
+ editableTarget?.range
55782
+ );
55223
55783
  const anchor = {
55224
55784
  kind: "range",
55225
- from: step.range.from,
55226
- to: step.range.to,
55785
+ from: dispatchRange.from,
55786
+ to: dispatchRange.to,
55227
55787
  assoc: { start: -1, end: 1 }
55228
55788
  };
55229
55789
  const timestamp = clock();
@@ -55232,6 +55792,8 @@ function createDocumentRuntime(options) {
55232
55792
  {
55233
55793
  type: "text.insert",
55234
55794
  text: step.text,
55795
+ ...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
55796
+ ...editableTarget?.textTarget ? { textTarget: editableTarget.textTarget } : {},
55235
55797
  ...step.formatting ? { formatting: step.formatting } : {},
55236
55798
  origin: createOrigin("api", timestamp)
55237
55799
  },
@@ -55246,10 +55808,28 @@ function createDocumentRuntime(options) {
55246
55808
  emitError(toRuntimeError(error));
55247
55809
  }
55248
55810
  } else if (step.kind === "text-delete-tracked" && step.range && step.range.to > step.range.from) {
55811
+ const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
55812
+ if (editableTarget === null) {
55813
+ emit({
55814
+ type: "command_blocked",
55815
+ documentId: state.documentId,
55816
+ command: "applyScopeReplacement",
55817
+ reasons: [{
55818
+ code: "unsupported_surface",
55819
+ message: "Scope replacement editable target no longer resolves."
55820
+ }]
55821
+ });
55822
+ continue;
55823
+ }
55824
+ const dispatchRange = mapSemanticStepRangeToEditableTarget(
55825
+ step.range,
55826
+ step.editableTargetHint,
55827
+ editableTarget?.range
55828
+ );
55249
55829
  const anchor = {
55250
55830
  kind: "range",
55251
- from: step.range.from,
55252
- to: step.range.to,
55831
+ from: dispatchRange.from,
55832
+ to: dispatchRange.to,
55253
55833
  assoc: { start: -1, end: 1 }
55254
55834
  };
55255
55835
  const timestamp = clock();
@@ -55257,6 +55837,8 @@ function createDocumentRuntime(options) {
55257
55837
  applyTextCommandInActiveStory(
55258
55838
  {
55259
55839
  type: "text.delete-forward",
55840
+ ...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
55841
+ ...editableTarget?.textTarget ? { textTarget: editableTarget.textTarget } : {},
55260
55842
  origin: createOrigin("api", timestamp)
55261
55843
  },
55262
55844
  {
@@ -56777,9 +57359,13 @@ function createDocumentRuntime(options) {
56777
57359
  applyViewportRanges(getSelectionCorridorViewportRanges(cachedRenderSnapshot.surface));
56778
57360
  }
56779
57361
  const tValidation0 = performance.now();
56780
- const patchedLocalTextSurface = useLocalTextCommitSnapshot ? tryPatchLocalTextSurface(cachedRenderSnapshot.surface, transaction.mapping) : null;
57362
+ const patchedFullLocalTextSurface = useLocalTextCommitSnapshot ? tryPatchLocalTextSurface(cachedRenderSnapshot.surface, transaction.mapping) : null;
57363
+ const patchedLocalTextSurface = patchedFullLocalTextSurface ? createLocalTextCorridorSurfaceFromFullSurface(patchedFullLocalTextSurface) : null;
56781
57364
  if (patchedLocalTextSurface) {
56782
- cachePatchedLocalTextSurface(patchedLocalTextSurface);
57365
+ cachePatchedLocalTextSurface(
57366
+ patchedLocalTextSurface,
57367
+ patchedFullLocalTextSurface ?? void 0
57368
+ );
56783
57369
  perfCounters.increment("commit.localTextValidation.storySizeOnly");
56784
57370
  }
56785
57371
  const localTextViewportRanges = useLocalTextCommitSnapshot && !patchedLocalTextSurface ? getSelectionCorridorViewportRanges(cachedRenderSnapshot.surface) : void 0;
@@ -56819,7 +57405,8 @@ function createDocumentRuntime(options) {
56819
57405
  cachedRenderSnapshot = useLocalTextCommitSnapshot ? refreshLocalTextCommitSnapshot(surfaceForValidation, transaction.mapping) : refreshRenderSnapshot();
56820
57406
  perfCounters.increment("commit.refresh.us", Math.round((performance.now() - tRefresh0) * 1e3));
56821
57407
  const tNotify0 = performance.now();
56822
- deferNextContextAnalyticsEmit = useLocalTextCommitSnapshot;
57408
+ const shouldDeferContextAnalyticsEmit = transaction.markDirty && transaction.mapping.steps.length > 0;
57409
+ deferNextContextAnalyticsEmit = shouldDeferContextAnalyticsEmit;
56823
57410
  try {
56824
57411
  notify(previous, state, {
56825
57412
  ...transaction,