@beyondwork/docx-react-component 1.0.124 → 1.0.126

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 +796 -102
  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-A74Y5NE4.js → chunk-4YJVRIUB.js} +52 -21
  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-ZMRO6P3A.js → chunk-6IGWPAR4.js} +505 -44
  18. package/dist/{chunk-KOHQFZMM.js → chunk-BYSRJ4FE.js} +1 -1
  19. package/dist/{chunk-H6IL5ABU.js → chunk-CXSYRB37.js} +64 -20
  20. package/dist/{chunk-32ZAOQ54.js → chunk-D5HYZQTG.js} +1 -1
  21. package/dist/{chunk-TY4DIJO3.js → chunk-ESJ2MES5.js} +1 -1
  22. package/dist/{chunk-Q76XPPTA.js → chunk-FPRWV54X.js} +101 -14
  23. package/dist/{chunk-MPH4ZQS4.js → chunk-GL7XRYBY.js} +624 -87
  24. package/dist/{chunk-IR7QV2BX.js → chunk-KV435YXO.js} +2 -2
  25. package/dist/{chunk-N4VIXI2Z.js → chunk-MWSBGJQO.js} +137 -18
  26. package/dist/{chunk-7PC6XUNO.js → chunk-TQDQU2E3.js} +2 -2
  27. package/dist/{chunk-4B74ETJI.js → chunk-V6XVZFFH.js} +2 -2
  28. package/dist/{chunk-NAMAWCXN.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 +1677 -240
  57. package/dist/index.d.cts +5 -5
  58. package/dist/index.d.ts +5 -5
  59. package/dist/index.js +62 -25
  60. package/dist/io/docx-session.cjs +51 -20
  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 +36 -12
  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-CS9-9KFa.d.ts} +3 -3
  69. package/dist/{loader-D9KCtj4m.d.cts → loader-OoWJ1_17.d.cts} +3 -3
  70. package/dist/{public-types-CNnMHZM9.d.ts → public-types-BP3vqJR5.d.cts} +157 -11
  71. package/dist/{public-types-DajNGKV4.d.cts → public-types-DdcHqcow.d.ts} +157 -11
  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 +945 -134
  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-Cq-fzx3B.d.cts} +3 -3
  83. package/dist/{session-DEmaOEjA.d.ts → session-DyFQt8Ph.d.ts} +3 -3
  84. package/dist/session.cjs +51 -20
  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-CxE1aZiv.d.cts → types-Bg7D-GD3.d.cts} +2 -2
  93. package/dist/{types-DjJNaE9c.d.ts → types-bJAgMq1M.d.ts} +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 +1 -1
@@ -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[");
@@ -18870,22 +18918,43 @@ function rangesOverlap2(leftFrom, leftTo, rightFrom, rightTo) {
18870
18918
  }
18871
18919
 
18872
18920
  // src/core/commands/list-commands.ts
18873
- function toggleNumberedList(document2, paragraphIndexes, context) {
18874
- return toggleListKind(document2, paragraphIndexes, "numbered", context);
18921
+ function toggleNumberedList(document2, paragraphIndexes, context, options = {}) {
18922
+ return toggleListKind(document2, paragraphIndexes, "numbered", context, options);
18875
18923
  }
18876
- function toggleBulletedList(document2, paragraphIndexes, context) {
18877
- return toggleListKind(document2, paragraphIndexes, "bulleted", context);
18924
+ function toggleBulletedList(document2, paragraphIndexes, context, options = {}) {
18925
+ return toggleListKind(document2, paragraphIndexes, "bulleted", context, options);
18878
18926
  }
18879
- function indentListItems(document2, paragraphIndexes, context) {
18880
- return adjustListLevels(document2, paragraphIndexes, 1, context);
18927
+ function indentListItems(document2, paragraphIndexes, context, options = {}) {
18928
+ return adjustListLevels(document2, paragraphIndexes, 1, context, options);
18881
18929
  }
18882
- function outdentListItems(document2, paragraphIndexes, context) {
18883
- return adjustListLevels(document2, paragraphIndexes, -1, context);
18930
+ function outdentListItems(document2, paragraphIndexes, context, options = {}) {
18931
+ return adjustListLevels(document2, paragraphIndexes, -1, context, options);
18884
18932
  }
18885
- function restartNumbering(document2, paragraphIndex, context, startAt = 1) {
18933
+ function restartNumbering(document2, paragraphIndex, context, startAt = 1, options = {}) {
18886
18934
  const working = cloneEnvelope(document2, context.timestamp);
18887
18935
  const paragraphs = captureEditableParagraphs(working);
18888
- const target = paragraphs[paragraphIndex];
18936
+ const resolved = resolveListCommandParagraphIndexes(
18937
+ working,
18938
+ paragraphs,
18939
+ [paragraphIndex],
18940
+ context,
18941
+ normalizeListCommandTargets(options)
18942
+ );
18943
+ if (resolved.blockedReason) {
18944
+ return {
18945
+ document: working,
18946
+ affectedParagraphIndexes: [],
18947
+ blockedReason: resolved.blockedReason
18948
+ };
18949
+ }
18950
+ const resolvedParagraphIndex = resolved.paragraphIndexes[0];
18951
+ if (resolvedParagraphIndex === void 0) {
18952
+ return {
18953
+ document: working,
18954
+ affectedParagraphIndexes: []
18955
+ };
18956
+ }
18957
+ const target = paragraphs[resolvedParagraphIndex];
18889
18958
  if (!target?.numbering) {
18890
18959
  return {
18891
18960
  document: working,
@@ -18910,7 +18979,7 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1) {
18910
18979
  })
18911
18980
  };
18912
18981
  const affectedParagraphIndexes = [];
18913
- for (let index = paragraphIndex; index < paragraphs.length; index += 1) {
18982
+ for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
18914
18983
  const paragraph = paragraphs[index];
18915
18984
  if (!paragraph?.numbering) {
18916
18985
  break;
@@ -18931,10 +19000,31 @@ function restartNumbering(document2, paragraphIndex, context, startAt = 1) {
18931
19000
  createdNumberingInstanceId: numberingInstanceId
18932
19001
  };
18933
19002
  }
18934
- function continueNumbering(document2, paragraphIndex, context) {
19003
+ function continueNumbering(document2, paragraphIndex, context, options = {}) {
18935
19004
  const working = cloneEnvelope(document2, context.timestamp);
18936
19005
  const paragraphs = captureEditableParagraphs(working);
18937
- const target = paragraphs[paragraphIndex];
19006
+ const resolved = resolveListCommandParagraphIndexes(
19007
+ working,
19008
+ paragraphs,
19009
+ [paragraphIndex],
19010
+ context,
19011
+ normalizeListCommandTargets(options)
19012
+ );
19013
+ if (resolved.blockedReason) {
19014
+ return {
19015
+ document: working,
19016
+ affectedParagraphIndexes: [],
19017
+ blockedReason: resolved.blockedReason
19018
+ };
19019
+ }
19020
+ const resolvedParagraphIndex = resolved.paragraphIndexes[0];
19021
+ if (resolvedParagraphIndex === void 0) {
19022
+ return {
19023
+ document: working,
19024
+ affectedParagraphIndexes: []
19025
+ };
19026
+ }
19027
+ const target = paragraphs[resolvedParagraphIndex];
18938
19028
  if (!target?.numbering) {
18939
19029
  return {
18940
19030
  document: working,
@@ -18953,7 +19043,7 @@ function continueNumbering(document2, paragraphIndex, context) {
18953
19043
  const compatibleInstanceId = findPreviousCompatibleInstance(
18954
19044
  paragraphs,
18955
19045
  catalog,
18956
- paragraphIndex,
19046
+ resolvedParagraphIndex,
18957
19047
  currentKind
18958
19048
  );
18959
19049
  if (!compatibleInstanceId || compatibleInstanceId === currentInstanceId) {
@@ -18963,7 +19053,7 @@ function continueNumbering(document2, paragraphIndex, context) {
18963
19053
  };
18964
19054
  }
18965
19055
  const affectedParagraphIndexes = [];
18966
- for (let index = paragraphIndex; index < paragraphs.length; index += 1) {
19056
+ for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
18967
19057
  const paragraph = paragraphs[index];
18968
19058
  if (!paragraph?.numbering) {
18969
19059
  break;
@@ -18984,10 +19074,24 @@ function continueNumbering(document2, paragraphIndex, context) {
18984
19074
  createdNumberingInstanceId: compatibleInstanceId
18985
19075
  };
18986
19076
  }
18987
- function toggleListKind(document2, paragraphIndexes, kind, context) {
19077
+ function toggleListKind(document2, paragraphIndexes, kind, context, options) {
18988
19078
  const working = cloneEnvelope(document2, context.timestamp);
18989
19079
  const paragraphs = captureEditableParagraphs(working);
18990
- const normalizedIndexes = normalizeParagraphIndexes(paragraphs, paragraphIndexes);
19080
+ const resolved = resolveListCommandParagraphIndexes(
19081
+ working,
19082
+ paragraphs,
19083
+ paragraphIndexes,
19084
+ context,
19085
+ normalizeListCommandTargets(options)
19086
+ );
19087
+ if (resolved.blockedReason) {
19088
+ return {
19089
+ document: working,
19090
+ affectedParagraphIndexes: [],
19091
+ blockedReason: resolved.blockedReason
19092
+ };
19093
+ }
19094
+ const normalizedIndexes = resolved.paragraphIndexes;
18991
19095
  if (normalizedIndexes.length === 0) {
18992
19096
  return {
18993
19097
  document: working,
@@ -19024,10 +19128,24 @@ function toggleListKind(document2, paragraphIndexes, kind, context) {
19024
19128
  createdNumberingInstanceId: numberingInstanceId
19025
19129
  };
19026
19130
  }
19027
- function adjustListLevels(document2, paragraphIndexes, delta, context) {
19131
+ function adjustListLevels(document2, paragraphIndexes, delta, context, options) {
19028
19132
  const working = cloneEnvelope(document2, context.timestamp);
19029
19133
  const paragraphs = captureEditableParagraphs(working);
19030
- const affectedParagraphIndexes = normalizeParagraphIndexes(paragraphs, paragraphIndexes).filter(
19134
+ const resolved = resolveListCommandParagraphIndexes(
19135
+ working,
19136
+ paragraphs,
19137
+ paragraphIndexes,
19138
+ context,
19139
+ normalizeListCommandTargets(options)
19140
+ );
19141
+ if (resolved.blockedReason) {
19142
+ return {
19143
+ document: working,
19144
+ affectedParagraphIndexes: [],
19145
+ blockedReason: resolved.blockedReason
19146
+ };
19147
+ }
19148
+ const affectedParagraphIndexes = resolved.paragraphIndexes.filter(
19031
19149
  (index) => Boolean(paragraphs[index]?.numbering)
19032
19150
  );
19033
19151
  for (const index of affectedParagraphIndexes) {
@@ -19045,6 +19163,121 @@ function adjustListLevels(document2, paragraphIndexes, delta, context) {
19045
19163
  affectedParagraphIndexes
19046
19164
  };
19047
19165
  }
19166
+ function normalizeListCommandTargets(options) {
19167
+ if (options.editableTargets !== void 0) return options.editableTargets;
19168
+ return options.editableTarget ? [options.editableTarget] : [];
19169
+ }
19170
+ function resolveListCommandParagraphIndexes(document2, paragraphs, paragraphIndexes, context, editableTargets) {
19171
+ if (editableTargets.length === 0) {
19172
+ return { paragraphIndexes: normalizeParagraphIndexes(paragraphs, paragraphIndexes) };
19173
+ }
19174
+ const currentTargets = collectEditableTargetRefs(document2, context.editableTargetCache);
19175
+ const paragraphIndexByTargetKey = /* @__PURE__ */ new Map();
19176
+ let paragraphIndex = 0;
19177
+ for (const target of currentTargets) {
19178
+ if (!isParagraphTextTarget(target)) continue;
19179
+ if (!paragraphIndexByTargetKey.has(target.targetKey)) {
19180
+ paragraphIndexByTargetKey.set(target.targetKey, paragraphIndex);
19181
+ paragraphIndex += 1;
19182
+ }
19183
+ }
19184
+ const resolvedIndexes = [];
19185
+ for (const target of editableTargets) {
19186
+ const blockedReason = validateListCommandTarget(target, currentTargets, context);
19187
+ if (blockedReason) return { paragraphIndexes: [], blockedReason };
19188
+ const current = findCurrentListCommandTarget(target, currentTargets);
19189
+ if (!current) {
19190
+ return {
19191
+ paragraphIndexes: [],
19192
+ blockedReason: {
19193
+ code: "list_target_not_found",
19194
+ message: "List editable target no longer resolves in the current canonical document."
19195
+ }
19196
+ };
19197
+ }
19198
+ if (!sameResolvedListCommandTarget(target, current)) {
19199
+ return {
19200
+ paragraphIndexes: [],
19201
+ blockedReason: {
19202
+ code: "list_target_stale",
19203
+ message: "List editable target is stale for the current canonical document."
19204
+ }
19205
+ };
19206
+ }
19207
+ const currentIndex = paragraphIndexByTargetKey.get(current.targetKey);
19208
+ if (currentIndex === void 0) {
19209
+ return {
19210
+ paragraphIndexes: [],
19211
+ blockedReason: {
19212
+ code: "list_target_position_unavailable",
19213
+ message: "List editable target resolved but could not be mapped to a current paragraph."
19214
+ }
19215
+ };
19216
+ }
19217
+ resolvedIndexes.push(currentIndex);
19218
+ }
19219
+ return { paragraphIndexes: normalizeParagraphIndexes(paragraphs, resolvedIndexes) };
19220
+ }
19221
+ function validateListCommandTarget(target, currentTargets, context) {
19222
+ const shapeIssues = validateEditableTargetRef(target);
19223
+ if (shapeIssues.length > 0) {
19224
+ return {
19225
+ code: "list_target_malformed",
19226
+ message: `List editable target is malformed: ${shapeIssues[0]?.path ?? "$"}.`
19227
+ };
19228
+ }
19229
+ if (context.activeStoryKey !== void 0 && target.storyKey !== context.activeStoryKey) {
19230
+ return {
19231
+ code: "list_target_wrong_story",
19232
+ message: "List editable target does not belong to the active story."
19233
+ };
19234
+ }
19235
+ if (target.commandFamily !== "text-leaf" || target.listAddress === void 0) {
19236
+ return {
19237
+ code: "list_target_required",
19238
+ message: "List commands require a validated list item editable target."
19239
+ };
19240
+ }
19241
+ if (target.editability !== "editable" || target.posture.blockers.length > 0) {
19242
+ return {
19243
+ code: "list_target_non_editable",
19244
+ message: target.posture.blockers.length > 0 ? `List editable target is not editable: ${target.posture.blockers.join(", ")}.` : "List editable target is not editable."
19245
+ };
19246
+ }
19247
+ if (!findCurrentListCommandTarget(target, currentTargets)) {
19248
+ return {
19249
+ code: "list_target_not_found",
19250
+ message: "List editable target no longer resolves in the current canonical document."
19251
+ };
19252
+ }
19253
+ return void 0;
19254
+ }
19255
+ function findCurrentListCommandTarget(target, currentTargets) {
19256
+ return currentTargets.find(
19257
+ (candidate) => isParagraphTextTarget(candidate) && candidate.listAddress !== void 0 && (candidate.targetKey === target.targetKey || candidate.listAddress.addressKey === target.listAddress?.addressKey)
19258
+ );
19259
+ }
19260
+ function sameResolvedListCommandTarget(left, right) {
19261
+ return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength && left.staleCheck.inlineCount === right.staleCheck.inlineCount && left.staleCheck.blockType === right.staleCheck.blockType && left.listAddress?.addressKey === right.listAddress?.addressKey && left.listAddress?.resolver?.staleHash === right.listAddress?.resolver?.staleHash && jsonStable(left.sourceRef) === jsonStable(right.sourceRef);
19262
+ }
19263
+ function isParagraphTextTarget(target) {
19264
+ return target.commandFamily === "text-leaf" && target.staleCheck.blockType === "paragraph" && target.leafPath.endsWith("/inline");
19265
+ }
19266
+ function jsonStable(value) {
19267
+ return JSON.stringify(sortJson(value));
19268
+ }
19269
+ function sortJson(value) {
19270
+ if (Array.isArray(value)) return value.map(sortJson);
19271
+ if (value && typeof value === "object") {
19272
+ const record = value;
19273
+ const sorted = {};
19274
+ for (const key of Object.keys(record).sort()) {
19275
+ sorted[key] = sortJson(record[key]);
19276
+ }
19277
+ return sorted;
19278
+ }
19279
+ return value;
19280
+ }
19048
19281
  function ensureDefaultInstance(catalog, kind) {
19049
19282
  const existing = Object.values(catalog.instances).find(
19050
19283
  (instance) => getListKind(catalog, instance.numberingInstanceId) === kind
@@ -19817,7 +20050,7 @@ function validateResult(result, context) {
19817
20050
  return { ...result, selection: validated };
19818
20051
  }
19819
20052
  function getPostMutationMaxOffset(result, context) {
19820
- if (typeof context.activeStorySize !== "number" || context.textTarget?.kind === "text-leaf") {
20053
+ if (typeof context.activeStorySize !== "number" || isTargetLocalTextLeaf(context.textTarget)) {
19821
20054
  return result.storyText.length;
19822
20055
  }
19823
20056
  let storySize = context.activeStorySize;
@@ -19826,6 +20059,9 @@ function getPostMutationMaxOffset(result, context) {
19826
20059
  }
19827
20060
  return Math.max(result.storyText.length, storySize);
19828
20061
  }
20062
+ function isTargetLocalTextLeaf(textTarget) {
20063
+ return textTarget?.kind === "text-leaf" && textTarget.blockPath.includes("/txbx/");
20064
+ }
19829
20065
  var editLayer = {
19830
20066
  applyTextInsert(doc, selection, text, context, formatting) {
19831
20067
  return validateResult(insertText(doc, selection, text, context, formatting), context);
@@ -20088,6 +20324,13 @@ function withCommandTextTarget(context, command) {
20088
20324
  textTarget: command.textTarget
20089
20325
  };
20090
20326
  }
20327
+ function listCommandContext(context) {
20328
+ return {
20329
+ timestamp: context.timestamp,
20330
+ ...context.activeStoryKey !== void 0 ? { activeStoryKey: context.activeStoryKey } : {},
20331
+ ...context.editableTargetCache !== void 0 ? { editableTargetCache: context.editableTargetCache } : {}
20332
+ };
20333
+ }
20091
20334
  function executeEditorCommand(state, command, context) {
20092
20335
  switch (command.type) {
20093
20336
  case "selection.set":
@@ -20729,7 +20972,17 @@ function executeEditorCommand(state, command, context) {
20729
20972
  });
20730
20973
  }
20731
20974
  case "list.toggle": {
20732
- const result = command.kind === "bulleted" ? toggleBulletedList(state.document, command.paragraphIndexes, { timestamp: context.timestamp }) : toggleNumberedList(state.document, command.paragraphIndexes, { timestamp: context.timestamp });
20975
+ const result = command.kind === "bulleted" ? toggleBulletedList(
20976
+ state.document,
20977
+ command.paragraphIndexes ?? [],
20978
+ listCommandContext(context),
20979
+ { editableTargets: command.editableTargets }
20980
+ ) : toggleNumberedList(
20981
+ state.document,
20982
+ command.paragraphIndexes ?? [],
20983
+ listCommandContext(context),
20984
+ { editableTargets: command.editableTargets }
20985
+ );
20733
20986
  return buildDocumentReplaceTransaction(state, context, {
20734
20987
  changed: result.affectedParagraphIndexes.length > 0,
20735
20988
  document: result.document,
@@ -20737,7 +20990,12 @@ function executeEditorCommand(state, command, context) {
20737
20990
  });
20738
20991
  }
20739
20992
  case "list.indent": {
20740
- const result = indentListItems(state.document, command.paragraphIndexes, { timestamp: context.timestamp });
20993
+ const result = indentListItems(
20994
+ state.document,
20995
+ command.paragraphIndexes ?? [],
20996
+ listCommandContext(context),
20997
+ { editableTargets: command.editableTargets }
20998
+ );
20741
20999
  return buildDocumentReplaceTransaction(state, context, {
20742
21000
  changed: result.affectedParagraphIndexes.length > 0,
20743
21001
  document: result.document,
@@ -20745,7 +21003,12 @@ function executeEditorCommand(state, command, context) {
20745
21003
  });
20746
21004
  }
20747
21005
  case "list.outdent": {
20748
- const result = outdentListItems(state.document, command.paragraphIndexes, { timestamp: context.timestamp });
21006
+ const result = outdentListItems(
21007
+ state.document,
21008
+ command.paragraphIndexes ?? [],
21009
+ listCommandContext(context),
21010
+ { editableTargets: command.editableTargets }
21011
+ );
20749
21012
  return buildDocumentReplaceTransaction(state, context, {
20750
21013
  changed: result.affectedParagraphIndexes.length > 0,
20751
21014
  document: result.document,
@@ -20755,9 +21018,10 @@ function executeEditorCommand(state, command, context) {
20755
21018
  case "list.restart-numbering": {
20756
21019
  const result = restartNumbering(
20757
21020
  state.document,
20758
- command.paragraphIndex,
20759
- { timestamp: context.timestamp },
20760
- command.startAt
21021
+ command.paragraphIndex ?? -1,
21022
+ listCommandContext(context),
21023
+ command.startAt,
21024
+ { editableTarget: command.editableTarget }
20761
21025
  );
20762
21026
  return buildDocumentReplaceTransaction(state, context, {
20763
21027
  changed: result.affectedParagraphIndexes.length > 0,
@@ -20768,8 +21032,9 @@ function executeEditorCommand(state, command, context) {
20768
21032
  case "list.continue-numbering": {
20769
21033
  const result = continueNumbering(
20770
21034
  state.document,
20771
- command.paragraphIndex,
20772
- { timestamp: context.timestamp }
21035
+ command.paragraphIndex ?? -1,
21036
+ listCommandContext(context),
21037
+ { editableTarget: command.editableTarget }
20773
21038
  );
20774
21039
  return buildDocumentReplaceTransaction(state, context, {
20775
21040
  changed: result.affectedParagraphIndexes.length > 0,
@@ -24742,7 +25007,7 @@ function buildFormattingDebugEntry(inputs) {
24742
25007
  }
24743
25008
 
24744
25009
  // src/runtime/layout/layout-engine-version.ts
24745
- var LAYOUT_ENGINE_VERSION = 87;
25010
+ var LAYOUT_ENGINE_VERSION = 88;
24746
25011
 
24747
25012
  // src/runtime/layout/compat-input-ledger.ts
24748
25013
  var DEFAULT_COMPATIBILITY_MODE = 15;
@@ -24968,6 +25233,27 @@ function hitTestRegion(index, region, point) {
24968
25233
  (target2) => target2.regionId === region.regionId
24969
25234
  );
24970
25235
  const containing = targets.filter((target2) => containsPoint(target2.rect, point));
25236
+ const generatedTarget = containing.find(
25237
+ (target2) => target2.generatedContentKind === "numbering-marker"
25238
+ );
25239
+ if (generatedTarget) {
25240
+ const anchorHit2 = firstLineAnchor(index, generatedTarget)?.runtimeOffset !== void 0 ? {
25241
+ runtimeOffset: firstLineAnchor(index, generatedTarget).runtimeOffset,
25242
+ assoc: "before"
25243
+ } : resolveLineAnchorHit(index, generatedTarget, point);
25244
+ return {
25245
+ pageIndex: generatedTarget.pageIndex,
25246
+ regionKind: generatedTarget.regionKind,
25247
+ blockId: generatedTarget.blockId,
25248
+ fragmentId: generatedTarget.fragmentId,
25249
+ lineIndex: generatedTarget.lineIndex,
25250
+ runtimeOffset: anchorHit2?.runtimeOffset ?? 0,
25251
+ assoc: "before",
25252
+ generatedContentKind: generatedTarget.generatedContentKind,
25253
+ generatedContentBoundary: generatedTarget.generatedContentBoundary?.policy,
25254
+ semanticEntryId: generatedTarget.targetId.startsWith("hit:") ? generatedTarget.targetId.slice("hit:".length) : generatedTarget.targetId
25255
+ };
25256
+ }
24971
25257
  const target = nearestTarget(containing, point) ?? nearestTarget(targets, point);
24972
25258
  if (!target) return null;
24973
25259
  const anchorHit = resolveLineAnchorHit(index, target, point);
@@ -25344,6 +25630,7 @@ function projectGeometryIndexFromFrame(frame, options) {
25344
25630
  identities,
25345
25631
  storyKey: storyKey2,
25346
25632
  entries: semanticEntries,
25633
+ hitTargets,
25347
25634
  projectedBlocksByStory,
25348
25635
  projectedCommandTargetsByKey,
25349
25636
  precision,
@@ -25614,6 +25901,7 @@ function appendBlockSemanticEntries(input) {
25614
25901
  identities,
25615
25902
  storyKey: storyKey2,
25616
25903
  entries,
25904
+ hitTargets,
25617
25905
  projectedBlocksByStory,
25618
25906
  projectedCommandTargetsByKey,
25619
25907
  precision,
@@ -25643,6 +25931,7 @@ function appendBlockSemanticEntries(input) {
25643
25931
  block,
25644
25932
  sourceIdentity: sliceIdentity,
25645
25933
  entries,
25934
+ hitTargets,
25646
25935
  projectedCommandTargetsByKey,
25647
25936
  precision,
25648
25937
  frameCompleteness,
@@ -25824,6 +26113,7 @@ function appendFragmentLayoutObjectSemanticEntries(input) {
25824
26113
  block,
25825
26114
  sourceIdentity,
25826
26115
  entries,
26116
+ hitTargets,
25827
26117
  projectedCommandTargetsByKey,
25828
26118
  precision,
25829
26119
  frameCompleteness,
@@ -25908,18 +26198,57 @@ function appendFragmentLayoutObjectSemanticEntries(input) {
25908
26198
  }
25909
26199
  return;
25910
26200
  }
25911
- if (layoutObject.kind === "numbered-paragraph") {
25912
- const markerProjection = resolveNumberingMarkerProjection(block);
26201
+ const numberingRows = layoutObject.numberingRows && layoutObject.numberingRows.length > 0 ? layoutObject.numberingRows : layoutObject.kind === "numbered-paragraph" && layoutObject.numbering ? [layoutObject.numbering] : [];
26202
+ for (let index = 0; index < numberingRows.length; index += 1) {
26203
+ const numbering = numberingRows[index];
26204
+ const markerProjection = resolveNumberingMarkerProjection(block, numbering);
26205
+ const entryId = layoutObject.kind === "numbered-paragraph" && index === 0 ? `semantic:numbering-marker:${base.sliceId}` : `semantic:numbering-marker:${base.sliceId}:${stableGeometryId(
26206
+ numbering.numberingLayoutId ?? numbering.numberingKey ?? String(index)
26207
+ )}`;
26208
+ const source = numberingSourceIdentity(numbering, sourceIdentity);
25913
26209
  entries.push({
25914
26210
  ...base,
25915
- entryId: `semantic:numbering-marker:${base.sliceId}`,
26211
+ entryId,
25916
26212
  kind: "numbering-marker",
25917
26213
  layoutObjectId: layoutObject.objectId,
26214
+ numberingLayoutId: numbering.numberingLayoutId,
26215
+ numberingKey: numbering.numberingKey,
26216
+ numberingTargetKey: numbering.targetKey,
26217
+ numberingTargetKind: numbering.targetKind,
26218
+ numberingCanonicalAddressKey: numbering.canonicalAddressKey,
26219
+ numberingListAddressKey: numbering.listAddressKey,
26220
+ numberingMarkerText: numbering.markerText,
26221
+ numberingMarkerSuffix: numbering.markerSuffix,
26222
+ numberingFormat: numbering.format,
26223
+ numberingFormatPosture: numbering.formatPosture,
26224
+ numberingUnavailableReasons: numbering.unavailableReasons,
26225
+ markerGlyphRect: markerProjection.rect,
26226
+ markerLaneRect: markerProjection.markerLaneRect,
26227
+ textColumnRect: markerProjection.textColumnRect,
26228
+ markerBoundary: markerProjection.markerBoundary,
25918
26229
  rect: markerProjection.rect,
25919
26230
  status: markerProjection.status,
25920
26231
  precision: markerProjection.precision,
25921
26232
  frameCompleteness,
25922
- ...sourceIdentity ? { sourceIdentity } : {}
26233
+ ...source ? { sourceIdentity: source } : {}
26234
+ });
26235
+ hitTargets.push({
26236
+ targetId: `hit:${entryId}`,
26237
+ pageId: base.pageId,
26238
+ pageIndex: base.pageIndex,
26239
+ regionId: base.regionId,
26240
+ regionKind: base.regionKind,
26241
+ blockId: base.blockId,
26242
+ fragmentId: base.fragmentId,
26243
+ lineIndex: firstLineIndex(block),
26244
+ rect: markerProjection.rect,
26245
+ precision: markerProjection.precision,
26246
+ generatedContentKind: "numbering-marker",
26247
+ generatedContentBoundary: {
26248
+ policy: "snap-to-authored-text",
26249
+ authoredTextStartsAtPx: markerProjection.markerBoundary.authoredTextStartsAtPx,
26250
+ selectionPolicy: "exclude-generated-marker"
26251
+ }
25923
26252
  });
25924
26253
  recordPrecision(precision, markerProjection.precision);
25925
26254
  }
@@ -26010,8 +26339,8 @@ function bookmarkRangeSourceIdentity(fact, fallback) {
26010
26339
  joinKind: "block-scoped"
26011
26340
  };
26012
26341
  }
26013
- function resolveNumberingMarkerProjection(block) {
26014
- const metadata = resolveNumberingMarkerProjectionMetadata(block);
26342
+ function resolveNumberingMarkerProjection(block, numbering) {
26343
+ const metadata = resolveNumberingMarkerProjectionMetadata(block, numbering);
26015
26344
  const blockFrame = block.frame;
26016
26345
  if (metadata.markerLane && metadata.measuredWidthTwips !== void 0) {
26017
26346
  const markerLane = metadata.markerLane;
@@ -26022,14 +26351,25 @@ function resolveNumberingMarkerProjection(block) {
26022
26351
  const rawRightPx = rawLeftPx + markerLane.widthTwips * pxPerTwip;
26023
26352
  const leftPx = clamp3(rawLeftPx, blockLeftPx, blockRightPx);
26024
26353
  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
26354
+ const markerLaneRect = {
26355
+ leftPx,
26356
+ topPx: blockFrame.topPx,
26357
+ widthPx: rightPx - leftPx,
26358
+ heightPx: blockFrame.heightPx,
26359
+ space: "frame",
26360
+ precision: metadata.precision
26361
+ };
26362
+ const textColumnRect = metadata.textColumn ? projectTextColumnRect(blockFrame, metadata.measuredWidthTwips, metadata.textColumn) : void 0;
26363
+ return {
26364
+ rect: markerLaneRect,
26365
+ markerLaneRect,
26366
+ ...textColumnRect ? { textColumnRect } : {},
26367
+ markerBoundary: {
26368
+ generatedContent: "numbering-marker",
26369
+ caretPolicy: "snap-to-authored-text",
26370
+ selectionPolicy: "exclude-marker-unless-list-item-action",
26371
+ coordinateSpace: "frame-px",
26372
+ ...textColumnRect ? { authoredTextStartsAtPx: textColumnRect.leftPx } : {}
26033
26373
  },
26034
26374
  precision: metadata.precision,
26035
26375
  status: metadata.status
@@ -26048,20 +26388,28 @@ function resolveNumberingMarkerProjection(block) {
26048
26388
  space: "frame",
26049
26389
  precision: metadata.precision
26050
26390
  },
26391
+ markerBoundary: {
26392
+ generatedContent: "numbering-marker",
26393
+ caretPolicy: "snap-to-authored-text",
26394
+ selectionPolicy: "exclude-marker-unless-list-item-action",
26395
+ coordinateSpace: "frame-px"
26396
+ },
26051
26397
  precision: metadata.precision,
26052
26398
  status: metadata.status
26053
26399
  };
26054
26400
  }
26055
- function resolveNumberingMarkerProjectionMetadata(block) {
26401
+ function resolveNumberingMarkerProjectionMetadata(block, numbering) {
26056
26402
  const blockFrame = block.frame;
26057
26403
  const layoutObject = block.fragment.layoutObject;
26058
- const markerLane = layoutObject?.kind === "numbered-paragraph" ? layoutObject.numbering?.markerLane : void 0;
26404
+ const markerLane = numbering?.markerLane ?? (layoutObject?.kind === "numbered-paragraph" ? layoutObject.numbering?.markerLane : void 0);
26405
+ const textColumn = numbering?.textColumn ?? (layoutObject?.kind === "numbered-paragraph" ? layoutObject.numbering?.textColumn : void 0);
26059
26406
  const measuredWidthTwips = layoutObject?.measuredExtentTwips.widthTwips;
26060
26407
  if (markerLane && markerLane.widthTwips > 0 && measuredWidthTwips !== void 0 && measuredWidthTwips > 0 && Number.isFinite(blockFrame.widthPx)) {
26061
26408
  return {
26062
26409
  precision: "within-tolerance",
26063
26410
  status: "realized",
26064
26411
  markerLane,
26412
+ ...textColumn ? { textColumn } : {},
26065
26413
  measuredWidthTwips
26066
26414
  };
26067
26415
  }
@@ -26070,6 +26418,42 @@ function resolveNumberingMarkerProjectionMetadata(block) {
26070
26418
  status: "requires-rehydration"
26071
26419
  };
26072
26420
  }
26421
+ function projectTextColumnRect(blockFrame, measuredWidthTwips, textColumn) {
26422
+ if (measuredWidthTwips <= 0 || !Number.isFinite(blockFrame.widthPx)) {
26423
+ return void 0;
26424
+ }
26425
+ const pxPerTwip = blockFrame.widthPx / measuredWidthTwips;
26426
+ const leftPx = blockFrame.leftPx + textColumn.startTwips * pxPerTwip;
26427
+ const rightInsetPx = (textColumn.rightTwips ?? 0) * pxPerTwip;
26428
+ const rightPx = blockFrame.leftPx + blockFrame.widthPx - rightInsetPx;
26429
+ if (rightPx < leftPx) return void 0;
26430
+ return {
26431
+ leftPx,
26432
+ topPx: blockFrame.topPx,
26433
+ widthPx: rightPx - leftPx,
26434
+ heightPx: blockFrame.heightPx,
26435
+ space: "frame",
26436
+ precision: "within-tolerance"
26437
+ };
26438
+ }
26439
+ function numberingSourceIdentity(numbering, fallback) {
26440
+ const storyKey2 = numbering.storyKey ?? fallback?.storyKey;
26441
+ if (!storyKey2) return fallback;
26442
+ return {
26443
+ storyKey: storyKey2,
26444
+ ...numbering.sourceBlockPath ?? fallback?.blockPath ? { blockPath: numbering.sourceBlockPath ?? fallback?.blockPath } : {},
26445
+ ...numbering.numberingKey ?? fallback?.scopeKey ? { scopeKey: numbering.numberingKey ?? fallback?.scopeKey } : {},
26446
+ ...numbering.numberingInstanceId ?? fallback?.scopeId ? { scopeId: numbering.numberingInstanceId ?? fallback?.scopeId } : {},
26447
+ ...numbering.numberingSourceRef ?? numbering.sourceRef ?? fallback?.sourceRef ? { sourceRef: numbering.numberingSourceRef ?? numbering.sourceRef ?? fallback?.sourceRef } : {},
26448
+ joinKind: "block-scoped"
26449
+ };
26450
+ }
26451
+ function stableGeometryId(value) {
26452
+ return value.replace(/[^A-Za-z0-9_.:-]+/gu, "_");
26453
+ }
26454
+ function firstLineIndex(block) {
26455
+ return block.lines[0]?.line.lineIndex ?? 0;
26456
+ }
26073
26457
  function countBlockSemanticEntries(block) {
26074
26458
  const counts = createPrecisionCounts();
26075
26459
  const layoutObject = block.fragment.layoutObject;
@@ -32259,6 +32643,24 @@ function refusalIdForPostureBlocker(target, blocker) {
32259
32643
  return "editable_target_opaque_content";
32260
32644
  case "synthetic-layout-cell":
32261
32645
  return "editable_target_synthetic_layout_cell";
32646
+ case "list-text-readback-missing":
32647
+ return "list_text_readback_missing";
32648
+ case "list-structure-command-missing":
32649
+ return "list_structure_command_missing";
32650
+ case "list-target-stale":
32651
+ return "list_target_stale";
32652
+ case "list-secondary-story-unsupported":
32653
+ return "list_secondary_story_unsupported";
32654
+ case "list-table-target-missing":
32655
+ return "list_table_target_missing";
32656
+ case "list-export-persistence-missing":
32657
+ return "list_export_persistence_missing";
32658
+ case "numbering-format-unsupported":
32659
+ return "numbering_format_unsupported";
32660
+ case "picture-bullet-preserve-only":
32661
+ return "picture_bullet_preserve_only";
32662
+ case "marker-geometry-unavailable":
32663
+ return "marker_geometry_unavailable";
32262
32664
  case "unmodeled-target":
32263
32665
  return target.commandFamily === "link-bookmark" ? "editable_target_linked_content_unmodeled" : "editable_target_unmodeled";
32264
32666
  }
@@ -32281,12 +32683,42 @@ function auditCategoryForPostureBlocker(target, blocker) {
32281
32683
  return target.commandFamily === "link-bookmark" ? "linked-content" : "unsupported-command";
32282
32684
  case "synthetic-layout-cell":
32283
32685
  return "synthetic-cell";
32686
+ case "list-target-stale":
32687
+ return "stale-ref";
32688
+ case "picture-bullet-preserve-only":
32689
+ case "list-export-persistence-missing":
32690
+ return "preserve-only";
32691
+ case "list-text-readback-missing":
32692
+ case "list-structure-command-missing":
32693
+ case "list-secondary-story-unsupported":
32694
+ case "list-table-target-missing":
32695
+ case "numbering-format-unsupported":
32696
+ case "marker-geometry-unavailable":
32697
+ return "unsupported-command";
32284
32698
  }
32285
32699
  }
32286
32700
  function messageForPostureBlocker(blocker) {
32287
32701
  switch (blocker) {
32288
32702
  case "synthetic-layout-cell":
32289
32703
  return "Hidden vertical-merge continuation or synthetic layout cells are not editable targets.";
32704
+ case "list-text-readback-missing":
32705
+ return "List text edits need an authoritative list-item text target before mutation.";
32706
+ case "list-structure-command-missing":
32707
+ return "List structure changes need a supported list command envelope before mutation.";
32708
+ case "list-target-stale":
32709
+ return "List target identity is stale for the current canonical document.";
32710
+ case "list-secondary-story-unsupported":
32711
+ return "List edits in this secondary story are not yet supported.";
32712
+ case "list-table-target-missing":
32713
+ return "Table-contained list item is missing a command-safe list target.";
32714
+ case "list-export-persistence-missing":
32715
+ return "List mutation is blocked until export/reopen persistence is available.";
32716
+ case "numbering-format-unsupported":
32717
+ return "Numbering format is unsupported for this list command.";
32718
+ case "picture-bullet-preserve-only":
32719
+ return "Picture bullet lists are preserve-only until picture bullet mutation is supported.";
32720
+ case "marker-geometry-unavailable":
32721
+ return "List marker geometry is unavailable for this target.";
32290
32722
  default:
32291
32723
  return void 0;
32292
32724
  }
@@ -33539,6 +33971,21 @@ function compileParagraphScope(entry, options = {}) {
33539
33971
  partial: true
33540
33972
  };
33541
33973
  }
33974
+ function storyKeyFromHandle(handle) {
33975
+ const target = handle.storyTarget;
33976
+ if (target.kind === "main") return "main";
33977
+ return null;
33978
+ }
33979
+ function textLeafEditableTargetHint(entry, semanticBlockRange) {
33980
+ const storyKey2 = storyKeyFromHandle(entry.handle);
33981
+ if (!storyKey2) return void 0;
33982
+ return {
33983
+ kind: "text-leaf",
33984
+ storyKey: storyKey2,
33985
+ blockPath: `${storyKey2}/block[${entry.blockIndex}]`,
33986
+ semanticBlockRange
33987
+ };
33988
+ }
33542
33989
  function compileParagraphReplacement(entry, proposed, options) {
33543
33990
  if (proposed.operation !== "replace" && proposed.operation !== "insert-before" && proposed.operation !== "insert-after") {
33544
33991
  return null;
@@ -33594,6 +34041,7 @@ function compileParagraphReplacement(entry, proposed, options) {
33594
34041
  {
33595
34042
  kind: stepKind,
33596
34043
  summary: stepKind === "text-replace" ? actionSummary : `suggest-mode ${actionSummary}`,
34044
+ ...textLeafEditableTargetHint(entry, blockRange) ? { editableTargetHint: textLeafEditableTargetHint(entry, blockRange) } : {},
33597
34045
  range: { from: operationRange.from, to: operationRange.to },
33598
34046
  text,
33599
34047
  ...proposed.formatting ? { formatting: proposed.formatting } : {}
@@ -33621,6 +34069,7 @@ function compileParagraphReplacement(entry, proposed, options) {
33621
34069
  {
33622
34070
  kind: "fragment-replace",
33623
34071
  summary: actionSummary,
34072
+ ...textLeafEditableTargetHint(entry, blockRange) ? { editableTargetHint: textLeafEditableTargetHint(entry, blockRange) } : {},
33624
34073
  range: { from: operationRange.from, to: operationRange.to },
33625
34074
  fragment
33626
34075
  }
@@ -35543,14 +35992,17 @@ function paragraphHasBookmarkId(paragraph, bookmarkId) {
35543
35992
  function commandActionHandleForAddress(commandFamily, address) {
35544
35993
  return address ? `scope-command:${commandFamily}:${address.addressKey}` : void 0;
35545
35994
  }
35546
- function withCommandAction(evidence, target) {
35547
- if (evidence.status !== "supported" || !target.canonicalAddress) return evidence;
35995
+ function withCommandAction(evidence, target, canonicalAddress = target.canonicalAddress) {
35996
+ if (evidence.status !== "supported" || !canonicalAddress) return evidence;
35548
35997
  return {
35549
35998
  ...evidence,
35550
- actionHandle: commandActionHandleForAddress(target.commandFamily, target.canonicalAddress),
35551
- canonicalAddress: target.canonicalAddress
35999
+ actionHandle: commandActionHandleForAddress(target.commandFamily, canonicalAddress),
36000
+ canonicalAddress
35552
36001
  };
35553
36002
  }
36003
+ function commandAddressForTarget(target, scopeKind) {
36004
+ return scopeKind === "list-item" && target.listAddress !== void 0 ? target.listAddress : target.canonicalAddress;
36005
+ }
35554
36006
  function runtimeTextCommandEvidence(target, workflowBlockers) {
35555
36007
  const shapeIssues = validateEditableTargetRef(target);
35556
36008
  if (shapeIssues.length > 0) {
@@ -35603,6 +36055,9 @@ var TABLE_TEXT_TARGET_KINDS2 = /* @__PURE__ */ new Set([
35603
36055
  var LIST_TEXT_TARGET_KINDS2 = /* @__PURE__ */ new Set([
35604
36056
  "paragraph-text",
35605
36057
  "sdt-paragraph-text",
36058
+ "table-cell-paragraph-text",
36059
+ "nested-table-cell-paragraph-text",
36060
+ "sdt-table-cell-paragraph-text",
35606
36061
  "secondary-story-paragraph-text"
35607
36062
  ]);
35608
36063
  function tableTextScopeReplacementPosture(target) {
@@ -35653,7 +36108,7 @@ function runtimeCommandEvidence(target, workflowBlockers, textCommand, scopeKind
35653
36108
  intents: commandIntentsForTarget(target, scopeKind),
35654
36109
  reason: textCommand.reason,
35655
36110
  ...textCommand.blockers ? { blockers: textCommand.blockers } : {}
35656
- }, target);
36111
+ }, target, commandAddressForTarget(target, scopeKind));
35657
36112
  }
35658
36113
  if (target.commandFamily === "comment-revision") {
35659
36114
  const isOpen = target.review?.status === "open";
@@ -43626,8 +44081,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43626
44081
  const perPageCounter = /* @__PURE__ */ new Map();
43627
44082
  const fieldRegionsByParagraphIndex = buildFieldRegionsByParagraphIndex(fieldRegions);
43628
44083
  const generatedTargets = buildGeneratedTargets(editableTargets);
44084
+ const numberingTargets = buildNumberingTargets(editableTargets);
43629
44085
  const bookmarkRanges = buildBookmarkRanges(editableTargets);
43630
- const numberingByParagraphIndex = buildNumberingByParagraphIndex(numberingInputs);
44086
+ const numberingIndex = buildNumberingInputIndex(numberingInputs);
43631
44087
  const pushFragment = (pageIndex, fragment) => {
43632
44088
  const existing = byPage.get(pageIndex);
43633
44089
  if (existing) {
@@ -43663,8 +44119,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43663
44119
  },
43664
44120
  fieldRegionsByParagraphIndex,
43665
44121
  generatedTargets,
44122
+ numberingTargets,
43666
44123
  bookmarkRanges,
43667
- numberingByParagraphIndex,
44124
+ numberingIndex,
43668
44125
  blockPath
43669
44126
  );
43670
44127
  continue;
@@ -43685,8 +44142,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43685
44142
  },
43686
44143
  fieldRegionsByParagraphIndex,
43687
44144
  generatedTargets,
44145
+ numberingTargets,
43688
44146
  bookmarkRanges,
43689
- numberingByParagraphIndex,
44147
+ numberingIndex,
43690
44148
  blockPath
43691
44149
  );
43692
44150
  continue;
@@ -43718,8 +44176,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
43718
44176
  paginationRole: "whole",
43719
44177
  fieldRegionsByParagraphIndex,
43720
44178
  generatedTargets,
44179
+ numberingTargets,
43721
44180
  bookmarkRanges,
43722
- numberingByParagraphIndex,
44181
+ numberingIndex,
43723
44182
  blockPath
43724
44183
  }),
43725
44184
  ...columnIndex !== void 0 ? { columnIndex } : {}
@@ -43866,7 +44325,7 @@ function buildRunAnchorsForLine(input) {
43866
44325
  }
43867
44326
  return anchors;
43868
44327
  }
43869
- function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], bookmarkRanges = [], numberingByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
44328
+ function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], numberingTargets = [], bookmarkRanges = [], numberingIndex = EMPTY_NUMBERING_INPUT_INDEX, blockPath) {
43870
44329
  for (let i = 0; i < slices.length; i += 1) {
43871
44330
  const slice = slices[i];
43872
44331
  const heightTwips = slice.heightTwips ?? estimateSliceHeightFromLines(slice.lineRange);
@@ -43891,8 +44350,9 @@ function emitSlicedParagraph(block, slices, emit, fieldRegionsByParagraphIndex =
43891
44350
  paginationRole: slice.lineRange.from > 0 ? "continuation" : "slice",
43892
44351
  fieldRegionsByParagraphIndex,
43893
44352
  generatedTargets,
44353
+ numberingTargets,
43894
44354
  bookmarkRanges,
43895
- numberingByParagraphIndex,
44355
+ numberingIndex,
43896
44356
  blockPath
43897
44357
  })
43898
44358
  };
@@ -43913,7 +44373,7 @@ function estimateSliceHeightFromLines(lineRange) {
43913
44373
  const lines = Math.max(0, lineRange.to - lineRange.from);
43914
44374
  return lines * 240;
43915
44375
  }
43916
- function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], bookmarkRanges = [], numberingByParagraphIndex = /* @__PURE__ */ new Map(), blockPath) {
44376
+ function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /* @__PURE__ */ new Map(), generatedTargets = [], numberingTargets = [], bookmarkRanges = [], numberingIndex = EMPTY_NUMBERING_INPUT_INDEX, blockPath) {
43917
44377
  for (let i = 0; i < slices.length; i += 1) {
43918
44378
  const slice = slices[i];
43919
44379
  const heightTwips = slice.heightTwips ?? estimateSliceHeightFromRows(slice.rowRange);
@@ -43937,8 +44397,9 @@ function emitSlicedTable(block, slices, emit, fieldRegionsByParagraphIndex = /*
43937
44397
  paginationRole: slice.rowRange.from > 0 ? "continuation" : "slice",
43938
44398
  fieldRegionsByParagraphIndex,
43939
44399
  generatedTargets,
44400
+ numberingTargets,
43940
44401
  bookmarkRanges,
43941
- numberingByParagraphIndex,
44402
+ numberingIndex,
43942
44403
  blockPath
43943
44404
  }),
43944
44405
  ...slice.columnIndex !== void 0 ? { columnIndex: slice.columnIndex } : {}
@@ -44012,7 +44473,8 @@ function buildFragmentLayoutObject(input) {
44012
44473
  const numberingRows = collectNumberingLayoutFactsForBlock(
44013
44474
  input.block,
44014
44475
  input.blockPath,
44015
- input.numberingByParagraphIndex
44476
+ input.numberingIndex,
44477
+ input.numberingTargets
44016
44478
  );
44017
44479
  const numbering = input.block.kind === "paragraph" ? numberingRows[0] : void 0;
44018
44480
  const fieldRegions = collectFieldRegionLayoutFacts(
@@ -44183,6 +44645,11 @@ function buildGeneratedTargets(targets) {
44183
44645
  (target) => target.kind === "field-result-text" || target.kind === "hyperlink-text" || target.kind === "hyperlink-destination" || target.kind === "bookmark-anchor" || target.kind === "bookmark-content-range"
44184
44646
  );
44185
44647
  }
44648
+ function buildNumberingTargets(targets) {
44649
+ return targets.filter(
44650
+ (target) => target.listAddress !== void 0 || target.canonicalAddress?.addressKind === "list-item-text"
44651
+ );
44652
+ }
44186
44653
  function buildBookmarkRanges(targets) {
44187
44654
  const anchors = /* @__PURE__ */ new Map();
44188
44655
  const contentRanges = /* @__PURE__ */ new Map();
@@ -44230,14 +44697,27 @@ function buildBookmarkRanges(targets) {
44230
44697
  }
44231
44698
  return ranges;
44232
44699
  }
44233
- function buildNumberingByParagraphIndex(numberingInputs) {
44700
+ var EMPTY_NUMBERING_INPUT_INDEX = {
44701
+ byNumberingKey: /* @__PURE__ */ new Map(),
44702
+ byBlockPath: /* @__PURE__ */ new Map(),
44703
+ byParagraphIndex: /* @__PURE__ */ new Map()
44704
+ };
44705
+ function buildNumberingInputIndex(numberingInputs) {
44706
+ const byNumberingKey = /* @__PURE__ */ new Map();
44707
+ const byBlockPath = /* @__PURE__ */ new Map();
44234
44708
  const byParagraph = /* @__PURE__ */ new Map();
44235
44709
  for (const input of numberingInputs) {
44710
+ if (!byNumberingKey.has(input.numberingKey)) {
44711
+ byNumberingKey.set(input.numberingKey, input);
44712
+ }
44713
+ if (!byBlockPath.has(input.blockPath)) {
44714
+ byBlockPath.set(input.blockPath, input);
44715
+ }
44236
44716
  if (!byParagraph.has(input.paragraphIndex)) {
44237
44717
  byParagraph.set(input.paragraphIndex, input);
44238
44718
  }
44239
44719
  }
44240
- return byParagraph;
44720
+ return { byNumberingKey, byBlockPath, byParagraphIndex: byParagraph };
44241
44721
  }
44242
44722
  function collectBookmarkRangeLayoutFacts(fragmentId, blockPath, bookmarkRanges) {
44243
44723
  if (!blockPath || !bookmarkRanges || bookmarkRanges.length === 0) return [];
@@ -44318,6 +44798,7 @@ function collectNumberingLayoutFacts(block) {
44318
44798
  ...block.numbering?.numberingInstanceId !== void 0 ? { numberingInstanceId: block.numbering.numberingInstanceId } : {},
44319
44799
  ...block.numbering?.level !== void 0 ? { level: block.numbering.level } : {},
44320
44800
  ...block.resolvedNumbering?.format !== void 0 ? { format: block.resolvedNumbering.format } : {},
44801
+ ...block.resolvedNumbering?.formatPosture !== void 0 ? { formatPosture: { ...block.resolvedNumbering.formatPosture } } : {},
44321
44802
  ...block.numberingPrefix !== void 0 ? { markerText: block.numberingPrefix } : {},
44322
44803
  ...block.numberingSuffix !== void 0 ? { markerSuffix: block.numberingSuffix } : {},
44323
44804
  ...block.resolvedNumbering?.geometry.markerJustification !== void 0 ? { markerJustification: block.resolvedNumbering.geometry.markerJustification } : {},
@@ -44345,15 +44826,21 @@ function collectNumberingLayoutFacts(block) {
44345
44826
  } : {}
44346
44827
  };
44347
44828
  }
44348
- function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagraphIndex) {
44829
+ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingIndex, numberingTargets = []) {
44349
44830
  const rows = [];
44350
44831
  const seen = /* @__PURE__ */ new Set();
44351
44832
  visitParagraphBlocks(block, (paragraph, context) => {
44352
44833
  const numbering = collectNumberingLayoutFacts(paragraph);
44353
44834
  if (!numbering) return;
44354
44835
  const paragraphIndex = parseParagraphBlockIndex(paragraph.blockId);
44355
- const canonical = paragraphIndex !== void 0 ? numberingByParagraphIndex?.get(paragraphIndex) : void 0;
44356
44836
  const numberingKey = context.path !== void 0 ? `main:${context.path}:numbering` : void 0;
44837
+ const canonical = lookupNumberingInput(
44838
+ numberingIndex,
44839
+ numberingKey,
44840
+ context.path,
44841
+ paragraphIndex
44842
+ );
44843
+ const target = findNumberingTarget(numberingTargets, context.path);
44357
44844
  const numberingLayoutId = numberingKey ?? [
44358
44845
  "numbering",
44359
44846
  paragraph.blockId,
@@ -44362,6 +44849,7 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagr
44362
44849
  ].join(":");
44363
44850
  if (seen.has(numberingLayoutId)) return;
44364
44851
  seen.add(numberingLayoutId);
44852
+ const unavailableReasons = collectNumberingUnavailableReasons(numbering, canonical);
44365
44853
  rows.push({
44366
44854
  numberingLayoutId,
44367
44855
  ...numberingKey !== void 0 ? { numberingKey } : {},
@@ -44369,6 +44857,10 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagr
44369
44857
  ...canonical?.blockPath !== void 0 ? { sourceBlockPath: canonical.blockPath } : context.path !== void 0 ? { sourceBlockPath: context.path } : {},
44370
44858
  sourceBlockId: paragraph.blockId,
44371
44859
  ...paragraphIndex !== void 0 ? { paragraphIndex } : {},
44860
+ ...target?.targetKey !== void 0 ? { targetKey: target.targetKey } : {},
44861
+ ...target?.kind !== void 0 ? { targetKind: target.kind } : {},
44862
+ ...target?.canonicalAddress?.addressKey !== void 0 ? { canonicalAddressKey: target.canonicalAddress.addressKey } : {},
44863
+ ...target?.listAddress?.addressKey !== void 0 ? { listAddressKey: target.listAddress.addressKey } : {},
44372
44864
  ...canonical?.sourceRef !== void 0 ? { sourceRef: { ...canonical.sourceRef } } : {},
44373
44865
  ...canonical?.numberingSourceRef !== void 0 ? { numberingSourceRef: { ...canonical.numberingSourceRef } } : {},
44374
44866
  ...canonical?.numberingOrigin !== void 0 ? { numberingOrigin: canonical.numberingOrigin } : {},
@@ -44376,11 +44868,41 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingByParagr
44376
44868
  ...canonical?.numberingInstanceSourceRef !== void 0 ? { numberingInstanceSourceRef: { ...canonical.numberingInstanceSourceRef } } : {},
44377
44869
  ...canonical?.abstractNumberingId !== void 0 ? { abstractNumberingId: canonical.abstractNumberingId } : {},
44378
44870
  ...canonical?.abstractNumberingSourceRef !== void 0 ? { abstractNumberingSourceRef: { ...canonical.abstractNumberingSourceRef } } : {},
44379
- ...numbering
44871
+ ...numbering,
44872
+ ...unavailableReasons.length > 0 ? { unavailableReasons } : {}
44380
44873
  });
44381
44874
  }, blockPath);
44382
44875
  return rows;
44383
44876
  }
44877
+ function findNumberingTarget(numberingTargets, blockPath) {
44878
+ if (blockPath === void 0) return void 0;
44879
+ return numberingTargets.find((target) => target.blockPath === blockPath);
44880
+ }
44881
+ function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraphIndex) {
44882
+ if (!numberingIndex) return void 0;
44883
+ if (numberingKey !== void 0) {
44884
+ const byKey = numberingIndex.byNumberingKey.get(numberingKey);
44885
+ if (byKey !== void 0) return byKey;
44886
+ }
44887
+ if (blockPath !== void 0) {
44888
+ const byPath = numberingIndex.byBlockPath.get(blockPath);
44889
+ if (byPath !== void 0) return byPath;
44890
+ }
44891
+ return paragraphIndex !== void 0 ? numberingIndex.byParagraphIndex.get(paragraphIndex) : void 0;
44892
+ }
44893
+ function collectNumberingUnavailableReasons(numbering, canonical) {
44894
+ const reasons = [];
44895
+ if (canonical === void 0) {
44896
+ reasons.push("canonical-numbering-input-missing");
44897
+ }
44898
+ if (numbering.markerLane === void 0) {
44899
+ reasons.push("numbering-marker-lane-unavailable");
44900
+ }
44901
+ if (numbering.textColumn === void 0) {
44902
+ reasons.push("numbering-text-column-unavailable");
44903
+ }
44904
+ return reasons;
44905
+ }
44384
44906
  function findPageIndexForOffset(pages, offset) {
44385
44907
  for (let i = 0; i < pages.length; i += 1) {
44386
44908
  const page = pages[i];
@@ -48354,6 +48876,16 @@ function createLayoutFacet(input) {
48354
48876
  function currentGraph() {
48355
48877
  return engine.getPageGraph(getQueryInput());
48356
48878
  }
48879
+ function fullGraphForViewportIndependentReads() {
48880
+ const query = getQueryInput();
48881
+ if (!query.viewportPageWindow) {
48882
+ return engine.getPageGraph(query);
48883
+ }
48884
+ return engine.getPageGraph({
48885
+ document: query.document,
48886
+ ...query.viewState ? { viewState: query.viewState } : {}
48887
+ });
48888
+ }
48357
48889
  function currentMapper() {
48358
48890
  return engine.getFragmentMapper(getQueryInput());
48359
48891
  }
@@ -48491,7 +49023,7 @@ function createLayoutFacet(input) {
48491
49023
  return graph.sections.map((section) => toPublicSectionNode(graph, section.index)).filter((node) => node !== null);
48492
49024
  },
48493
49025
  getPageForOffset(offset, story) {
48494
- const graph = currentGraph();
49026
+ const graph = fullGraphForViewportIndependentReads();
48495
49027
  const page = findPageForOffsetAndStory(graph, offset, story);
48496
49028
  return page ? toPublicPageNode(page, graph) : null;
48497
49029
  },
@@ -48803,7 +49335,7 @@ function createLayoutFacet(input) {
48803
49335
  return null;
48804
49336
  },
48805
49337
  getBlockHeightsTwips() {
48806
- const graph = currentGraph();
49338
+ const graph = fullGraphForViewportIndependentReads();
48807
49339
  if (blockHeightsCache.revision === graph.revision && blockHeightsCache.map) {
48808
49340
  return blockHeightsCache.map;
48809
49341
  }
@@ -52259,7 +52791,8 @@ function rejectCommand(code, message) {
52259
52791
  };
52260
52792
  }
52261
52793
  function sameResolvedTarget2(left, right) {
52262
- return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && sameTextTargetStaleCheck(left, right) && left.staleCheck.inlineCount === right.staleCheck.inlineCount && left.staleCheck.targetHash === right.staleCheck.targetHash && left.staleCheck.targetTextLength === right.staleCheck.targetTextLength && left.staleCheck.childCount === right.staleCheck.childCount && left.staleCheck.blockType === right.staleCheck.blockType && left.staleCheck.wordParaId === right.staleCheck.wordParaId && left.staleCheck.wordTextId === right.staleCheck.wordTextId && jsonStable(left.staleCheck.sourceRef) === jsonStable(right.staleCheck.sourceRef) && jsonStable(left.sourceRef) === jsonStable(right.sourceRef) && jsonStable(left.table) === jsonStable(right.table) && jsonStable(left.editableOwner) === jsonStable(right.editableOwner);
52794
+ const textTargetLengthDrift = hasTextTargetLengthDrift(left, right);
52795
+ return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && sameTextTargetStaleCheck(left, right) && left.staleCheck.inlineCount === right.staleCheck.inlineCount && left.staleCheck.targetHash === right.staleCheck.targetHash && left.staleCheck.targetTextLength === right.staleCheck.targetTextLength && left.staleCheck.childCount === right.staleCheck.childCount && left.staleCheck.blockType === right.staleCheck.blockType && left.staleCheck.wordParaId === right.staleCheck.wordParaId && left.staleCheck.wordTextId === right.staleCheck.wordTextId && (textTargetLengthDrift || jsonStable2(left.staleCheck.sourceRef) === jsonStable2(right.staleCheck.sourceRef)) && (textTargetLengthDrift || jsonStable2(left.sourceRef) === jsonStable2(right.sourceRef)) && jsonStable2(left.table) === jsonStable2(right.table) && jsonStable2(left.editableOwner) === jsonStable2(right.editableOwner);
52263
52796
  }
52264
52797
  function sameTextTargetStaleCheck(left, right) {
52265
52798
  if (left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength) {
@@ -52267,6 +52800,9 @@ function sameTextTargetStaleCheck(left, right) {
52267
52800
  }
52268
52801
  return left.commandFamily === "text-leaf" && left.staleCheck.paragraphTextLength !== void 0 && right.staleCheck.paragraphTextLength !== void 0 && left.staleCheck.paragraphTextLength !== right.staleCheck.paragraphTextLength;
52269
52802
  }
52803
+ function hasTextTargetLengthDrift(left, right) {
52804
+ return left.commandFamily === "text-leaf" && left.staleCheck.paragraphTextLength !== void 0 && right.staleCheck.paragraphTextLength !== void 0 && left.staleCheck.paragraphTextLength !== right.staleCheck.paragraphTextLength;
52805
+ }
52270
52806
  function locateTargetRange(document2, surface, target) {
52271
52807
  if (target.kind === "hyperlink-text") {
52272
52808
  return locateHyperlinkDisplayRange(document2, surface, target);
@@ -52297,19 +52833,19 @@ function locateTargetRange(document2, surface, target) {
52297
52833
  if (!sdt || sdt.kind !== "sdt_block") return null;
52298
52834
  const paragraph = sdt.children[sdtPath.childIndex];
52299
52835
  if (!paragraph || paragraph.kind !== "paragraph") return null;
52300
- return { from: paragraph.from, to: paragraph.to };
52836
+ return textLeafTargetRange(target, paragraph.from, paragraph.to);
52301
52837
  }
52302
52838
  const paragraphPath = parseTopLevelParagraphPath(target.blockPath);
52303
52839
  if (paragraphPath) {
52304
52840
  const paragraph = surface[paragraphPath.blockIndex];
52305
52841
  if (!paragraph || paragraph.kind !== "paragraph") return null;
52306
- return { from: paragraph.from, to: paragraph.to };
52842
+ return textLeafTargetRange(target, paragraph.from, paragraph.to);
52307
52843
  }
52308
52844
  const secondaryParagraphPath = parseSecondaryStoryParagraphPath(target.blockPath);
52309
52845
  if (secondaryParagraphPath) {
52310
52846
  const paragraph = surface[secondaryParagraphPath.blockIndex];
52311
52847
  if (!paragraph || paragraph.kind !== "paragraph") return null;
52312
- return { from: paragraph.from, to: paragraph.to };
52848
+ return textLeafTargetRange(target, paragraph.from, paragraph.to);
52313
52849
  }
52314
52850
  if (target.kind === "textbox-paragraph-text") {
52315
52851
  return {
@@ -52325,6 +52861,18 @@ function locateTargetRange(document2, surface, target) {
52325
52861
  }
52326
52862
  return null;
52327
52863
  }
52864
+ function textLeafTargetRange(target, from, to) {
52865
+ return {
52866
+ from,
52867
+ to,
52868
+ textTarget: {
52869
+ kind: "text-leaf",
52870
+ blockPath: target.blockPath,
52871
+ paragraphStart: from,
52872
+ paragraphEnd: to
52873
+ }
52874
+ };
52875
+ }
52328
52876
  function locateHyperlinkDisplayRange(document2, surface, target) {
52329
52877
  const canonical = resolveHyperlinkDisplayPath(document2, target.blockPath);
52330
52878
  if (!canonical) return null;
@@ -52546,7 +53094,7 @@ function resolveBlockPathInSurfaceBlocks2(blocks, tokens, tokenIndex, hasVertica
52546
53094
  hasVerticalMergeContinuation || cell.verticalMerge === "continue"
52547
53095
  );
52548
53096
  }
52549
- function jsonStable(value) {
53097
+ function jsonStable2(value) {
52550
53098
  return value === void 0 ? "" : JSON.stringify(value);
52551
53099
  }
52552
53100
 
@@ -52683,20 +53231,20 @@ function tableAnchorCell(table) {
52683
53231
  };
52684
53232
  }
52685
53233
  function sameResolvedTableStructureTarget(left, right) {
52686
- return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && left.staleCheck.targetHash === right.staleCheck.targetHash && left.staleCheck.childCount === right.staleCheck.childCount && left.staleCheck.blockType === right.staleCheck.blockType && jsonStable2(left.staleCheck.sourceRef) === jsonStable2(right.staleCheck.sourceRef) && jsonStable2(left.sourceRef) === jsonStable2(right.sourceRef) && jsonStable2(left.table) === jsonStable2(right.table);
53234
+ return left.kind === right.kind && left.storyKey === right.storyKey && left.blockPath === right.blockPath && left.leafPath === right.leafPath && left.commandFamily === right.commandFamily && left.editability === right.editability && left.staleCheck.targetHash === right.staleCheck.targetHash && left.staleCheck.childCount === right.staleCheck.childCount && left.staleCheck.blockType === right.staleCheck.blockType && jsonStable3(left.staleCheck.sourceRef) === jsonStable3(right.staleCheck.sourceRef) && jsonStable3(left.sourceRef) === jsonStable3(right.sourceRef) && jsonStable3(left.table) === jsonStable3(right.table);
52687
53235
  }
52688
- function jsonStable2(value) {
52689
- return JSON.stringify(sortJson(value));
53236
+ function jsonStable3(value) {
53237
+ return JSON.stringify(sortJson2(value));
52690
53238
  }
52691
- function sortJson(value) {
53239
+ function sortJson2(value) {
52692
53240
  if (Array.isArray(value)) {
52693
- return value.map(sortJson);
53241
+ return value.map(sortJson2);
52694
53242
  }
52695
53243
  if (value && typeof value === "object") {
52696
53244
  const record = value;
52697
53245
  const sorted = {};
52698
53246
  for (const key of Object.keys(record).sort()) {
52699
- sorted[key] = sortJson(record[key]);
53247
+ sorted[key] = sortJson2(record[key]);
52700
53248
  }
52701
53249
  return sorted;
52702
53250
  }
@@ -52705,6 +53253,8 @@ function sortJson(value) {
52705
53253
 
52706
53254
  // src/runtime/document-runtime.ts
52707
53255
  var CANONICAL_BLOCK_REFS_SYMBOL2 = /* @__PURE__ */ Symbol.for("wre.canonical-block-refs");
53256
+ var LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES = 5e3;
53257
+ var LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK = 256;
52708
53258
  function getLocalTextPatchMetadata(mapping) {
52709
53259
  const metadata = mapping.metadata?.localTextPatch;
52710
53260
  if (!metadata || typeof metadata !== "object") {
@@ -52877,8 +53427,10 @@ function createDocumentRuntime(options) {
52877
53427
  void upgradeMeasurementProvider(layoutEngine, fontLoader);
52878
53428
  let renderKernelRef = null;
52879
53429
  let runtimeRef = null;
53430
+ const normalizedInitialSurfaceViewportRanges = options.initialSurfaceViewportBlockRanges && options.initialSurfaceViewportBlockRanges.length > 0 ? normalizeViewportRanges(options.initialSurfaceViewportBlockRanges) : null;
53431
+ let initialSurfaceViewportBlockRanges = normalizedInitialSurfaceViewportRanges && normalizedInitialSurfaceViewportRanges.length > 0 ? normalizedInitialSurfaceViewportRanges : null;
52880
53432
  let viewportBlockRanges = null;
52881
- let viewportRangesKey = serializeViewportRanges(null);
53433
+ let viewportRangesKey = serializeViewportRanges(viewportBlockRanges);
52882
53434
  let viewportBlocksPerPageEstimate = null;
52883
53435
  const EDITING_CORRIDOR_BLOCK_RADIUS = 8;
52884
53436
  const getRuntimeForLayoutFacet = () => {
@@ -53118,10 +53670,11 @@ function createDocumentRuntime(options) {
53118
53670
  const cachedContextAnalyticsSnapshots = /* @__PURE__ */ new Map();
53119
53671
  let lastEmittedContextAnalyticsSnapshots;
53120
53672
  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;
53673
+ const cached = getReusableCachedFullSurface(document2, nextActiveStory);
53674
+ if (cached) {
53675
+ return cached;
53124
53676
  }
53677
+ const activeStoryKey = storyTargetKey(nextActiveStory);
53125
53678
  const snapshot = createEditorSurfaceSnapshot(document2, state.selection, nextActiveStory, {
53126
53679
  viewportBlockRanges: null,
53127
53680
  editableTargetsByBlockPath: getEditableTargetsByBlockPath(document2),
@@ -53143,6 +53696,13 @@ function createDocumentRuntime(options) {
53143
53696
  };
53144
53697
  return snapshot;
53145
53698
  }
53699
+ function getReusableCachedFullSurface(document2, nextActiveStory) {
53700
+ const activeStoryKey = storyTargetKey(nextActiveStory);
53701
+ 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) {
53702
+ return cachedFullSurface.snapshot;
53703
+ }
53704
+ return void 0;
53705
+ }
53146
53706
  function getCachedSurface(document2, nextActiveStory, options2 = {}) {
53147
53707
  const activeStoryKey = storyTargetKey(nextActiveStory);
53148
53708
  const surfaceViewportRanges = "viewportBlockRangesOverride" in options2 ? options2.viewportBlockRangesOverride ?? null : viewportBlockRanges;
@@ -53153,12 +53713,20 @@ function createDocumentRuntime(options) {
53153
53713
  }
53154
53714
  const snapshot = createEditorSurfaceSnapshot(document2, state.selection, nextActiveStory, {
53155
53715
  viewportBlockRanges: surfaceViewportRanges,
53156
- editableTargetsByBlockPath: options2.editableTargetsByBlockPathOverride ?? getEditableTargetsByBlockPath(document2),
53716
+ editableTargetsByBlockPath: options2.editableTargetsByBlockPathOverride ?? getEditableTargetsByBlockPathForRanges(
53717
+ document2,
53718
+ activeStoryKey,
53719
+ surfaceViewportRanges
53720
+ ),
53157
53721
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
53158
53722
  });
53159
53723
  recordPerfSample("snapshot.surface");
53160
53724
  incrementInvalidationCounter("runtime.snapshot.surfaceMisses");
53161
- const enrichedSnapshot = options2.enrichCulledPlaceholders === false ? snapshot : enrichCulledPlaceholdersWithHeights(snapshot);
53725
+ const enrichedSnapshot = options2.enrichCulledPlaceholders === false ? snapshot : enrichCulledPlaceholdersWithHeights(
53726
+ snapshot,
53727
+ document2,
53728
+ nextActiveStory
53729
+ );
53162
53730
  if (surfaceViewportRanges === null) {
53163
53731
  cachedFullSurface = {
53164
53732
  content: document2.content,
@@ -53216,7 +53784,7 @@ function createDocumentRuntime(options) {
53216
53784
  }
53217
53785
  return -1;
53218
53786
  }
53219
- function cachePatchedLocalTextSurface(surface) {
53787
+ function cachePatchedLocalTextSurface(surface, fullSurfaceForCache) {
53220
53788
  const activeStoryKey = storyTargetKey(activeStory);
53221
53789
  const rangesKey = serializeViewportRanges(surface.viewportBlockRanges);
53222
53790
  cachedSurface = {
@@ -53232,7 +53800,8 @@ function createDocumentRuntime(options) {
53232
53800
  viewportRangesKey: rangesKey,
53233
53801
  snapshot: surface
53234
53802
  };
53235
- if (surface.viewportBlockRanges === null) {
53803
+ const fullSurface = fullSurfaceForCache ?? (surface.viewportBlockRanges === null ? surface : void 0);
53804
+ if (fullSurface) {
53236
53805
  cachedFullSurface = {
53237
53806
  content: state.document.content,
53238
53807
  subParts: state.document.subParts,
@@ -53243,11 +53812,15 @@ function createDocumentRuntime(options) {
53243
53812
  review: state.document.review,
53244
53813
  effectiveMarkupModeProvider,
53245
53814
  activeStoryKey,
53246
- snapshot: surface
53815
+ snapshot: fullSurface
53247
53816
  };
53248
53817
  }
53249
53818
  cachedSurfaceFingerprint = `${activeStoryKey}|${rangesKey}|${String(state.selection.anchor)}:${String(state.selection.head)}`;
53250
53819
  }
53820
+ function createLocalTextCorridorSurfaceFromFullSurface(fullSurface) {
53821
+ const ranges = getSelectionCorridorViewportRanges(fullSurface);
53822
+ return ranges ? createViewportCulledSurfaceFromFullSurface(fullSurface, ranges) : fullSurface;
53823
+ }
53251
53824
  function tryPatchLocalTextSurface(previousSurface, mapping) {
53252
53825
  const tTotal0 = performance.now();
53253
53826
  try {
@@ -53283,6 +53856,13 @@ function createDocumentRuntime(options) {
53283
53856
  perfCounters.increment("surface.localText.patchMiss");
53284
53857
  return null;
53285
53858
  }
53859
+ const shiftBudget = estimateLocalTextPatchShiftBudget(previousSurface.blocks, blockIndex + 1);
53860
+ perfCounters.increment("surface.localText.shiftedBlocks", shiftBudget.shiftedBlocks);
53861
+ perfCounters.increment("surface.localText.shiftedNodes", shiftBudget.shiftedNodes);
53862
+ if (!shiftBudget.withinBudget) {
53863
+ perfCounters.increment("surface.localText.patchBudgetFallback");
53864
+ return null;
53865
+ }
53286
53866
  const segmentIndex = block.segments.findIndex(
53287
53867
  (segment2) => segment2.kind === "text" && editFrom >= segment2.from && editTo <= segment2.to
53288
53868
  );
@@ -53390,7 +53970,83 @@ function createDocumentRuntime(options) {
53390
53970
  };
53391
53971
  }
53392
53972
  }
53393
- function enrichCulledPlaceholdersWithHeights(snapshot) {
53973
+ function estimateLocalTextPatchShiftBudget(blocks, startIndex) {
53974
+ const shiftedBlocks = Math.max(0, blocks.length - startIndex);
53975
+ let shiftedNodes = 0;
53976
+ for (let index = startIndex; index < blocks.length; index += 1) {
53977
+ const shiftedBlockNodes = countSurfaceShiftNodesUpTo(
53978
+ blocks[index],
53979
+ Math.min(
53980
+ LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK,
53981
+ LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES - shiftedNodes
53982
+ ) + 1
53983
+ );
53984
+ shiftedNodes += shiftedBlockNodes;
53985
+ if (shiftedBlockNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK) {
53986
+ return {
53987
+ shiftedBlocks,
53988
+ shiftedNodes,
53989
+ withinBudget: false
53990
+ };
53991
+ }
53992
+ if (shiftedNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES) {
53993
+ return {
53994
+ shiftedBlocks,
53995
+ shiftedNodes,
53996
+ withinBudget: false
53997
+ };
53998
+ }
53999
+ }
54000
+ return {
54001
+ shiftedBlocks,
54002
+ shiftedNodes,
54003
+ withinBudget: true
54004
+ };
54005
+ }
54006
+ function countSurfaceShiftNodesUpTo(block, limit) {
54007
+ if (limit <= 0) {
54008
+ return 1;
54009
+ }
54010
+ switch (block.kind) {
54011
+ case "paragraph":
54012
+ return 1 + block.segments.length;
54013
+ case "opaque_block":
54014
+ return 1;
54015
+ case "sdt_block": {
54016
+ let total = 1;
54017
+ for (const child of block.children) {
54018
+ total += countSurfaceShiftNodesUpTo(child, limit - total);
54019
+ if (total > limit) {
54020
+ return total;
54021
+ }
54022
+ }
54023
+ return total;
54024
+ }
54025
+ case "table": {
54026
+ let total = 1;
54027
+ for (const row2 of block.rows) {
54028
+ total += 1;
54029
+ if (total > limit) {
54030
+ return total;
54031
+ }
54032
+ for (const cell of row2.cells) {
54033
+ total += 1;
54034
+ if (total > limit) {
54035
+ return total;
54036
+ }
54037
+ for (const child of cell.content) {
54038
+ total += countSurfaceShiftNodesUpTo(child, limit - total);
54039
+ if (total > limit) {
54040
+ return total;
54041
+ }
54042
+ }
54043
+ }
54044
+ }
54045
+ return total;
54046
+ }
54047
+ }
54048
+ }
54049
+ function enrichCulledPlaceholdersWithHeights(snapshot, document2, nextActiveStory, fullSurfaceForPlaceholders) {
53394
54050
  let heights;
53395
54051
  try {
53396
54052
  heights = layoutFacet.getBlockHeightsTwips();
@@ -53398,17 +54054,19 @@ function createDocumentRuntime(options) {
53398
54054
  return snapshot;
53399
54055
  }
53400
54056
  if (heights.size === 0) return snapshot;
54057
+ const fullSurface = fullSurfaceForPlaceholders ?? getReusableCachedFullSurface(document2, nextActiveStory);
54058
+ if (!fullSurface) return snapshot;
53401
54059
  let changed = false;
53402
54060
  const enrichedBlocks = snapshot.blocks.map((block) => {
53403
54061
  if (block.kind !== "opaque_block" || block.state !== "placeholder-culled") {
53404
54062
  return block;
53405
54063
  }
53406
- const realBlockIdFromOffset = resolveBlockIdFromRuntimeOffset(
53407
- layoutFacet,
53408
- block.from
54064
+ const realBlock = resolveFullSurfaceBlockForPlaceholder(
54065
+ fullSurface,
54066
+ block
53409
54067
  );
53410
- if (!realBlockIdFromOffset) return block;
53411
- const heightTwips = heights.get(realBlockIdFromOffset);
54068
+ if (!realBlock) return block;
54069
+ const heightTwips = heights.get(realBlock.blockId);
53412
54070
  if (typeof heightTwips !== "number" || heightTwips <= 0) return block;
53413
54071
  changed = true;
53414
54072
  return { ...block, placeholderHeightTwips: heightTwips };
@@ -53416,13 +54074,20 @@ function createDocumentRuntime(options) {
53416
54074
  if (!changed) return snapshot;
53417
54075
  return { ...snapshot, blocks: enrichedBlocks };
53418
54076
  }
53419
- function resolveBlockIdFromRuntimeOffset(facet, runtimeOffset) {
53420
- try {
53421
- const frag = facet.getFragmentForOffset?.(runtimeOffset);
53422
- return frag?.blockId ?? null;
53423
- } catch {
53424
- return null;
54077
+ function resolveFullSurfaceBlockForPlaceholder(fullSurface, placeholder) {
54078
+ const index = parsePlaceholderCulledIndex(placeholder.blockId);
54079
+ if (index !== null) {
54080
+ return fullSurface.blocks[index] ?? null;
53425
54081
  }
54082
+ return fullSurface.blocks.find(
54083
+ (block) => block.from === placeholder.from && block.to === placeholder.to
54084
+ ) ?? null;
54085
+ }
54086
+ function parsePlaceholderCulledIndex(blockId) {
54087
+ const match = /^placeholder-culled-(\d+)$/.exec(blockId);
54088
+ if (!match) return null;
54089
+ const index = Number(match[1]);
54090
+ return Number.isSafeInteger(index) ? index : null;
53426
54091
  }
53427
54092
  function getCachedFieldSnapshot(document2) {
53428
54093
  const blockCount = document2.content.children.length;
@@ -53987,7 +54652,14 @@ function createDocumentRuntime(options) {
53987
54652
  revisionToken: state.revisionToken
53988
54653
  });
53989
54654
  perfCounters.increment("refresh.all");
53990
- const surface = timeFacet("surface", () => getCachedSurface(state.document, activeStory));
54655
+ const firstSurfaceViewportBlockRanges = initialSurfaceViewportBlockRanges;
54656
+ initialSurfaceViewportBlockRanges = null;
54657
+ const surface = timeFacet(
54658
+ "surface",
54659
+ () => firstSurfaceViewportBlockRanges ? getCachedSurface(state.document, activeStory, {
54660
+ viewportBlockRangesOverride: firstSurfaceViewportBlockRanges
54661
+ }) : getCachedSurface(state.document, activeStory)
54662
+ );
53991
54663
  const snapshot = {
53992
54664
  documentId: state.documentId,
53993
54665
  sessionId: state.sessionId,
@@ -54085,8 +54757,10 @@ function createDocumentRuntime(options) {
54085
54757
  if (options2.forceProjection) {
54086
54758
  cachedFullSurface = void 0;
54087
54759
  }
54088
- const newSurface = viewportBlockRanges !== null && options2.forceProjection !== true ? createViewportCulledSurfaceFromFullSurface(
54089
- getCachedFullSurface(state.document, activeStory),
54760
+ const reusableFullSurface = viewportBlockRanges !== null && options2.forceProjection !== true ? getReusableCachedFullSurface(state.document, activeStory) : void 0;
54761
+ const derivedFromFull = viewportBlockRanges !== null && reusableFullSurface !== void 0;
54762
+ const projectedSurface = derivedFromFull ? createViewportCulledSurfaceFromFullSurface(
54763
+ reusableFullSurface,
54090
54764
  viewportBlockRanges
54091
54765
  ) : createEditorSurfaceSnapshot(
54092
54766
  state.document,
@@ -54094,11 +54768,21 @@ function createDocumentRuntime(options) {
54094
54768
  activeStory,
54095
54769
  {
54096
54770
  viewportBlockRanges,
54097
- editableTargetsByBlockPath: getEditableTargetsByBlockPath(state.document),
54771
+ editableTargetsByBlockPath: getEditableTargetsByBlockPathForRanges(
54772
+ state.document,
54773
+ activeStoryKey,
54774
+ viewportBlockRanges
54775
+ ),
54098
54776
  ...effectiveMarkupModeProvider ? { getEffectiveMarkupMode: effectiveMarkupModeProvider } : {}
54099
54777
  }
54100
54778
  );
54101
- if (viewportBlockRanges !== null && options2.forceProjection !== true) {
54779
+ const newSurface = viewportBlockRanges !== null ? enrichCulledPlaceholdersWithHeights(
54780
+ projectedSurface,
54781
+ state.document,
54782
+ activeStory,
54783
+ reusableFullSurface
54784
+ ) : projectedSurface;
54785
+ if (derivedFromFull) {
54102
54786
  perfCounters.increment("runtime.viewport.derivedSurfaceRefreshes");
54103
54787
  } else {
54104
54788
  recordPerfSample("snapshot.surface");
@@ -54642,6 +55326,8 @@ function createDocumentRuntime(options) {
54642
55326
  documentMode: workflowCoordinator.getEffectiveDocumentMode(commandSelection),
54643
55327
  defaultAuthorId: defaultAuthorId ?? void 0,
54644
55328
  renderSnapshot: cachedRenderSnapshot,
55329
+ activeStoryKey: canonicalEditableTargetStoryKey(activeStory),
55330
+ editableTargetCache: editableTargetBlockCache,
54645
55331
  ...resolvedFragmentTextTarget ? { textTarget: resolvedFragmentTextTarget } : {}
54646
55332
  };
54647
55333
  const preSelection = commandSelection;
@@ -55169,12 +55855,86 @@ function createDocumentRuntime(options) {
55169
55855
  }
55170
55856
  },
55171
55857
  applyScopeReplacement(plan) {
55858
+ const resolveEditableTargetHint = (hint) => {
55859
+ if (!hint) return void 0;
55860
+ const activeStoryKey = storyTargetKey(activeStory);
55861
+ if (hint.storyKey !== activeStoryKey) return null;
55862
+ const currentTargets = collectEditableTargetRefs(
55863
+ state.document,
55864
+ editableTargetBlockCache
55865
+ );
55866
+ const target = currentTargets.find(
55867
+ (target2) => target2.storyKey === hint.storyKey && target2.blockPath === hint.blockPath && target2.commandFamily === "text-leaf"
55868
+ );
55869
+ if (!target) return null;
55870
+ const fallbackTextTarget = {
55871
+ kind: "text-leaf",
55872
+ blockPath: target.blockPath,
55873
+ paragraphStart: hint.semanticBlockRange.from,
55874
+ paragraphEnd: hint.semanticBlockRange.to
55875
+ };
55876
+ const resolved = resolveEditableTextTarget({
55877
+ document: state.document,
55878
+ surface: cachedRenderSnapshot.surface?.blocks ?? [],
55879
+ target,
55880
+ activeStoryKey,
55881
+ editableTargetCache: editableTargetBlockCache
55882
+ });
55883
+ if (resolved.kind === "rejected") {
55884
+ return {
55885
+ textTarget: fallbackTextTarget,
55886
+ range: hint.semanticBlockRange
55887
+ };
55888
+ }
55889
+ return {
55890
+ target,
55891
+ textTarget: resolved.textTarget ?? fallbackTextTarget,
55892
+ range: resolved.range
55893
+ };
55894
+ };
55895
+ const mapSemanticStepRangeToEditableTarget = (stepRange, hint, editableRange) => {
55896
+ if (!hint || !editableRange) return stepRange;
55897
+ const semanticFrom = hint.semanticBlockRange.from;
55898
+ const semanticTo = hint.semanticBlockRange.to;
55899
+ const localFrom = Math.max(0, stepRange.from - semanticFrom);
55900
+ const localTo = Math.max(localFrom, stepRange.to - semanticFrom);
55901
+ const semanticLength = Math.max(0, semanticTo - semanticFrom);
55902
+ const editableLength = Math.max(0, editableRange.to - editableRange.from);
55903
+ if (semanticLength === editableLength) {
55904
+ return {
55905
+ from: editableRange.from + localFrom,
55906
+ to: editableRange.from + localTo
55907
+ };
55908
+ }
55909
+ if (stepRange.from === semanticFrom && stepRange.to === semanticTo) {
55910
+ return editableRange;
55911
+ }
55912
+ return stepRange;
55913
+ };
55172
55914
  for (const step of plan.steps) {
55173
55915
  if (step.kind === "text-replace" && step.range && typeof step.text === "string") {
55916
+ const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
55917
+ if (editableTarget === null) {
55918
+ emit({
55919
+ type: "command_blocked",
55920
+ documentId: state.documentId,
55921
+ command: "applyScopeReplacement",
55922
+ reasons: [{
55923
+ code: "unsupported_surface",
55924
+ message: "Scope replacement editable target no longer resolves."
55925
+ }]
55926
+ });
55927
+ continue;
55928
+ }
55929
+ const dispatchRange = mapSemanticStepRangeToEditableTarget(
55930
+ step.range,
55931
+ step.editableTargetHint,
55932
+ editableTarget?.range
55933
+ );
55174
55934
  const anchor = {
55175
55935
  kind: "range",
55176
- from: step.range.from,
55177
- to: step.range.to,
55936
+ from: dispatchRange.from,
55937
+ to: dispatchRange.to,
55178
55938
  assoc: { start: -1, end: 1 }
55179
55939
  };
55180
55940
  const timestamp = clock();
@@ -55183,6 +55943,8 @@ function createDocumentRuntime(options) {
55183
55943
  {
55184
55944
  type: "text.insert",
55185
55945
  text: step.text,
55946
+ ...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
55947
+ ...editableTarget?.textTarget ? { textTarget: editableTarget.textTarget } : {},
55186
55948
  ...step.formatting ? { formatting: step.formatting } : {},
55187
55949
  origin: createOrigin("api", timestamp)
55188
55950
  },
@@ -55220,10 +55982,28 @@ function createDocumentRuntime(options) {
55220
55982
  emitError(toRuntimeError(error));
55221
55983
  }
55222
55984
  } else if (step.kind === "text-insert-tracked" && step.range && typeof step.text === "string") {
55985
+ const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
55986
+ if (editableTarget === null) {
55987
+ emit({
55988
+ type: "command_blocked",
55989
+ documentId: state.documentId,
55990
+ command: "applyScopeReplacement",
55991
+ reasons: [{
55992
+ code: "unsupported_surface",
55993
+ message: "Scope replacement editable target no longer resolves."
55994
+ }]
55995
+ });
55996
+ continue;
55997
+ }
55998
+ const dispatchRange = mapSemanticStepRangeToEditableTarget(
55999
+ step.range,
56000
+ step.editableTargetHint,
56001
+ editableTarget?.range
56002
+ );
55223
56003
  const anchor = {
55224
56004
  kind: "range",
55225
- from: step.range.from,
55226
- to: step.range.to,
56005
+ from: dispatchRange.from,
56006
+ to: dispatchRange.to,
55227
56007
  assoc: { start: -1, end: 1 }
55228
56008
  };
55229
56009
  const timestamp = clock();
@@ -55232,6 +56012,8 @@ function createDocumentRuntime(options) {
55232
56012
  {
55233
56013
  type: "text.insert",
55234
56014
  text: step.text,
56015
+ ...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
56016
+ ...editableTarget?.textTarget ? { textTarget: editableTarget.textTarget } : {},
55235
56017
  ...step.formatting ? { formatting: step.formatting } : {},
55236
56018
  origin: createOrigin("api", timestamp)
55237
56019
  },
@@ -55246,10 +56028,28 @@ function createDocumentRuntime(options) {
55246
56028
  emitError(toRuntimeError(error));
55247
56029
  }
55248
56030
  } else if (step.kind === "text-delete-tracked" && step.range && step.range.to > step.range.from) {
56031
+ const editableTarget = resolveEditableTargetHint(step.editableTargetHint);
56032
+ if (editableTarget === null) {
56033
+ emit({
56034
+ type: "command_blocked",
56035
+ documentId: state.documentId,
56036
+ command: "applyScopeReplacement",
56037
+ reasons: [{
56038
+ code: "unsupported_surface",
56039
+ message: "Scope replacement editable target no longer resolves."
56040
+ }]
56041
+ });
56042
+ continue;
56043
+ }
56044
+ const dispatchRange = mapSemanticStepRangeToEditableTarget(
56045
+ step.range,
56046
+ step.editableTargetHint,
56047
+ editableTarget?.range
56048
+ );
55249
56049
  const anchor = {
55250
56050
  kind: "range",
55251
- from: step.range.from,
55252
- to: step.range.to,
56051
+ from: dispatchRange.from,
56052
+ to: dispatchRange.to,
55253
56053
  assoc: { start: -1, end: 1 }
55254
56054
  };
55255
56055
  const timestamp = clock();
@@ -55257,6 +56057,8 @@ function createDocumentRuntime(options) {
55257
56057
  applyTextCommandInActiveStory(
55258
56058
  {
55259
56059
  type: "text.delete-forward",
56060
+ ...editableTarget?.target ? { editableTarget: editableTarget.target } : {},
56061
+ ...editableTarget?.textTarget ? { textTarget: editableTarget.textTarget } : {},
55260
56062
  origin: createOrigin("api", timestamp)
55261
56063
  },
55262
56064
  {
@@ -56777,9 +57579,13 @@ function createDocumentRuntime(options) {
56777
57579
  applyViewportRanges(getSelectionCorridorViewportRanges(cachedRenderSnapshot.surface));
56778
57580
  }
56779
57581
  const tValidation0 = performance.now();
56780
- const patchedLocalTextSurface = useLocalTextCommitSnapshot ? tryPatchLocalTextSurface(cachedRenderSnapshot.surface, transaction.mapping) : null;
57582
+ const patchedFullLocalTextSurface = useLocalTextCommitSnapshot ? tryPatchLocalTextSurface(cachedRenderSnapshot.surface, transaction.mapping) : null;
57583
+ const patchedLocalTextSurface = patchedFullLocalTextSurface ? createLocalTextCorridorSurfaceFromFullSurface(patchedFullLocalTextSurface) : null;
56781
57584
  if (patchedLocalTextSurface) {
56782
- cachePatchedLocalTextSurface(patchedLocalTextSurface);
57585
+ cachePatchedLocalTextSurface(
57586
+ patchedLocalTextSurface,
57587
+ patchedFullLocalTextSurface ?? void 0
57588
+ );
56783
57589
  perfCounters.increment("commit.localTextValidation.storySizeOnly");
56784
57590
  }
56785
57591
  const localTextViewportRanges = useLocalTextCommitSnapshot && !patchedLocalTextSurface ? getSelectionCorridorViewportRanges(cachedRenderSnapshot.surface) : void 0;
@@ -56819,7 +57625,8 @@ function createDocumentRuntime(options) {
56819
57625
  cachedRenderSnapshot = useLocalTextCommitSnapshot ? refreshLocalTextCommitSnapshot(surfaceForValidation, transaction.mapping) : refreshRenderSnapshot();
56820
57626
  perfCounters.increment("commit.refresh.us", Math.round((performance.now() - tRefresh0) * 1e3));
56821
57627
  const tNotify0 = performance.now();
56822
- deferNextContextAnalyticsEmit = useLocalTextCommitSnapshot;
57628
+ const shouldDeferContextAnalyticsEmit = transaction.markDirty && transaction.mapping.steps.length > 0;
57629
+ deferNextContextAnalyticsEmit = shouldDeferContextAnalyticsEmit;
56823
57630
  try {
56824
57631
  notify(previous, state, {
56825
57632
  ...transaction,
@@ -57120,6 +57927,8 @@ function createDocumentRuntime(options) {
57120
57927
  documentMode: textOptions.documentModeOverride ?? workflowCoordinator.getEffectiveDocumentMode(selection),
57121
57928
  defaultAuthorId: defaultAuthorId ?? void 0,
57122
57929
  renderSnapshot: cachedRenderSnapshot,
57930
+ activeStoryKey: canonicalEditableTargetStoryKey(activeStory),
57931
+ editableTargetCache: editableTargetBlockCache,
57123
57932
  activeStorySize: cachedRenderSnapshot.surface?.storySize,
57124
57933
  textTarget,
57125
57934
  rejectTargetlessTableStructureInsert: true
@@ -57420,7 +58229,9 @@ function createDocumentRuntime(options) {
57420
58229
  timestamp: clock(),
57421
58230
  documentMode: workflowCoordinator.getEffectiveDocumentMode(state.selection),
57422
58231
  defaultAuthorId: defaultAuthorId ?? void 0,
57423
- renderSnapshot: cachedRenderSnapshot
58232
+ renderSnapshot: cachedRenderSnapshot,
58233
+ activeStoryKey: canonicalEditableTargetStoryKey(activeStory),
58234
+ editableTargetCache: editableTargetBlockCache
57424
58235
  };
57425
58236
  try {
57426
58237
  const transaction = executeEditorCommand(