@beyondwork/docx-react-component 1.0.127 → 1.0.129

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 (98) hide show
  1. package/dist/api/public-types.cjs +215 -61
  2. package/dist/api/public-types.d.cts +2 -2
  3. package/dist/api/public-types.d.ts +2 -2
  4. package/dist/api/public-types.js +2 -2
  5. package/dist/api/v3.cjs +1324 -71
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +8 -8
  9. package/dist/{canonical-document-CXCFCbAz.d.cts → canonical-document-BMtONpgf.d.cts} +6 -0
  10. package/dist/{canonical-document-CXCFCbAz.d.ts → canonical-document-BMtONpgf.d.ts} +6 -0
  11. package/dist/{chunk-KV435YXO.js → chunk-5DSHUYSY.js} +1 -1
  12. package/dist/{chunk-TQDQU2E3.js → chunk-63FYIGCT.js} +2 -2
  13. package/dist/{chunk-ZDOAUP3V.js → chunk-DDN2AIGE.js} +1 -1
  14. package/dist/{chunk-6F5QW44A.js → chunk-DJU2W4E4.js} +2 -2
  15. package/dist/{chunk-4EENH4FG.js → chunk-EZKJXIPH.js} +1 -1
  16. package/dist/{chunk-CXSYRB37.js → chunk-HUIHBBAQ.js} +166 -49
  17. package/dist/{chunk-ESJ2MES5.js → chunk-JJGVE5J7.js} +1 -1
  18. package/dist/{chunk-LZVBNDGU.js → chunk-LJH64PV3.js} +3 -3
  19. package/dist/{chunk-MWSBGJQO.js → chunk-OTQIW2TC.js} +2 -2
  20. package/dist/{chunk-2QL5DAKF.js → chunk-PGKUJZXV.js} +3 -3
  21. package/dist/{chunk-PUMZWE2D.js → chunk-PRAZBHNF.js} +460 -136
  22. package/dist/{chunk-4YJVRIUB.js → chunk-Q3QYGKFE.js} +51 -8
  23. package/dist/{chunk-YHZHPXDB.js → chunk-RMRTQGW3.js} +50 -13
  24. package/dist/{chunk-XRACP43Q.js → chunk-SKPTKQHF.js} +351 -13
  25. package/dist/{chunk-D5HYZQTG.js → chunk-VNLDQJ47.js} +1 -1
  26. package/dist/{chunk-BYSRJ4FE.js → chunk-W34X3KBR.js} +1 -1
  27. package/dist/{chunk-V6XVZFFH.js → chunk-XMHSGPLN.js} +2 -2
  28. package/dist/{chunk-46KNRA4C.js → chunk-XQCAMKIQ.js} +849 -6
  29. package/dist/{chunk-YD2JE54B.js → chunk-YZDZ4FGR.js} +1 -1
  30. package/dist/compare.d.cts +1 -1
  31. package/dist/compare.d.ts +1 -1
  32. package/dist/core/commands/formatting-commands.d.cts +2 -2
  33. package/dist/core/commands/formatting-commands.d.ts +2 -2
  34. package/dist/core/commands/image-commands.cjs +166 -49
  35. package/dist/core/commands/image-commands.d.cts +2 -2
  36. package/dist/core/commands/image-commands.d.ts +2 -2
  37. package/dist/core/commands/image-commands.js +4 -4
  38. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  39. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  40. package/dist/core/commands/style-commands.d.cts +2 -2
  41. package/dist/core/commands/style-commands.d.ts +2 -2
  42. package/dist/core/commands/table-structure-commands.cjs +166 -49
  43. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  44. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  45. package/dist/core/commands/table-structure-commands.js +3 -3
  46. package/dist/core/commands/text-commands.cjs +166 -49
  47. package/dist/core/commands/text-commands.d.cts +2 -2
  48. package/dist/core/commands/text-commands.d.ts +2 -2
  49. package/dist/core/commands/text-commands.js +4 -4
  50. package/dist/core/selection/mapping.d.cts +2 -2
  51. package/dist/core/selection/mapping.d.ts +2 -2
  52. package/dist/core/state/editor-state.d.cts +2 -2
  53. package/dist/core/state/editor-state.d.ts +2 -2
  54. package/dist/index.cjs +1943 -219
  55. package/dist/index.d.cts +5 -5
  56. package/dist/index.d.ts +5 -5
  57. package/dist/index.js +56 -22
  58. package/dist/io/docx-session.cjs +51 -8
  59. package/dist/io/docx-session.d.cts +4 -4
  60. package/dist/io/docx-session.d.ts +4 -4
  61. package/dist/io/docx-session.js +3 -3
  62. package/dist/legal.d.cts +1 -1
  63. package/dist/legal.d.ts +1 -1
  64. package/dist/legal.js +2 -2
  65. package/dist/{loader-CFICtb9m.d.ts → loader-4qsw4eIU.d.ts} +3 -3
  66. package/dist/{loader-DveZOVuC.d.cts → loader-B8TKhmQi.d.cts} +3 -3
  67. package/dist/{public-types-beSYFJRR.d.cts → public-types-B5CRoR6f.d.cts} +220 -1
  68. package/dist/{public-types-Cgl3efbO.d.ts → public-types-p9b8rfy8.d.ts} +220 -1
  69. package/dist/public-types.cjs +215 -61
  70. package/dist/public-types.d.cts +2 -2
  71. package/dist/public-types.d.ts +2 -2
  72. package/dist/public-types.js +2 -2
  73. package/dist/runtime/collab.d.cts +3 -3
  74. package/dist/runtime/collab.d.ts +3 -3
  75. package/dist/runtime/document-runtime.cjs +999 -193
  76. package/dist/runtime/document-runtime.d.cts +2 -2
  77. package/dist/runtime/document-runtime.d.ts +2 -2
  78. package/dist/runtime/document-runtime.js +13 -13
  79. package/dist/{session-B7u82EJF.d.cts → session-BnGIjaex.d.cts} +3 -3
  80. package/dist/{session-BWMJ9jm4.d.ts → session-vEYKf-w3.d.ts} +3 -3
  81. package/dist/session.cjs +51 -8
  82. package/dist/session.d.cts +5 -5
  83. package/dist/session.d.ts +5 -5
  84. package/dist/session.js +4 -4
  85. package/dist/tailwind.cjs +215 -61
  86. package/dist/tailwind.d.cts +2 -2
  87. package/dist/tailwind.d.ts +2 -2
  88. package/dist/tailwind.js +5 -5
  89. package/dist/{types-BQjdVZsh.d.cts → types-BLuvZ6cQ.d.cts} +2 -2
  90. package/dist/{types-DvvmS5A7.d.ts → types-Dutlyj0T.d.ts} +2 -2
  91. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  92. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  93. package/dist/ui-tailwind/editor-surface/search-plugin.js +3 -3
  94. package/dist/ui-tailwind.cjs +215 -61
  95. package/dist/ui-tailwind.d.cts +3 -3
  96. package/dist/ui-tailwind.d.ts +3 -3
  97. package/dist/ui-tailwind.js +5 -5
  98. package/package.json +1 -1
package/dist/api/v3.cjs CHANGED
@@ -18852,7 +18852,7 @@ function parseNumberingXml(xml, context) {
18852
18852
  abstractDefinitions[abstractNumberingId] = {
18853
18853
  abstractNumberingId,
18854
18854
  ...context?.partPath !== void 0 ? { sourceRef: createNumberingSourceRef(context.partPath, "abstractNum", rawId, childXmlPath) } : {},
18855
- levels: readLevels(child),
18855
+ levels: readLevels(child, context, childXmlPath, rawId),
18856
18856
  ...nsid ? { nsid } : {},
18857
18857
  ...multiLevelType ? { multiLevelType } : {},
18858
18858
  ...tplc ? { tplc } : {},
@@ -18873,7 +18873,7 @@ function parseNumberingXml(xml, context) {
18873
18873
  numberingInstanceId,
18874
18874
  ...context?.partPath !== void 0 ? { sourceRef: createNumberingSourceRef(context.partPath, "num", rawId, childXmlPath) } : {},
18875
18875
  abstractNumberingId: toCanonicalAbstractNumberingId(rawAbstractId),
18876
- overrides: readOverrides(child)
18876
+ overrides: readOverrides(child, context, childXmlPath, rawId)
18877
18877
  };
18878
18878
  break;
18879
18879
  }
@@ -18894,6 +18894,16 @@ function createNumberingSourceRef(partPath, element, rawId, xmlPath) {
18894
18894
  ...xmlPath !== void 0 ? { xmlPath } : {}
18895
18895
  };
18896
18896
  }
18897
+ function createNumberingChildSourceRef(partPath, element, sourceIdSuffix, xmlPath) {
18898
+ if (partPath === void 0) return void 0;
18899
+ return {
18900
+ sourceId: `part:${partPath}#${sourceIdSuffix}`,
18901
+ partPath,
18902
+ storyKind: "numbering",
18903
+ element,
18904
+ ...xmlPath !== void 0 ? { xmlPath } : {}
18905
+ };
18906
+ }
18897
18907
  function readNumPicBullet(node, numPicBulletId, context, xmlPath) {
18898
18908
  let widthEmu;
18899
18909
  let heightEmu;
@@ -18970,18 +18980,29 @@ function toCanonicalAbstractNumberingId(value) {
18970
18980
  function toCanonicalNumberingInstanceId(value) {
18971
18981
  return value.startsWith("num:") ? value : `num:${value}`;
18972
18982
  }
18973
- function readLevels(abstractNode) {
18983
+ function readLevels(abstractNode, context, abstractXmlPath, rawAbstractId) {
18974
18984
  const levels = [];
18985
+ let levelOrdinal = 0;
18975
18986
  for (const child of abstractNode.children) {
18976
18987
  if (child.type !== "element" || localName(child.name) !== "lvl") {
18977
18988
  continue;
18978
18989
  }
18990
+ levelOrdinal += 1;
18979
18991
  const rawLevel = readStringAttr(child, "w:ilvl");
18980
18992
  const level = rawLevel === void 0 ? void 0 : parseInteger(rawLevel);
18981
18993
  if (level === void 0) {
18982
18994
  continue;
18983
18995
  }
18984
- const definition = readLevelDefinition(child, level);
18996
+ const definition = readLevelDefinition(
18997
+ child,
18998
+ level,
18999
+ createNumberingChildSourceRef(
19000
+ context?.partPath,
19001
+ "lvl",
19002
+ `abstractNum:${rawAbstractId}:lvl:${level}`,
19003
+ `${abstractXmlPath}/lvl[${levelOrdinal}]`
19004
+ )
19005
+ );
18985
19006
  if (!definition) {
18986
19007
  continue;
18987
19008
  }
@@ -18989,12 +19010,14 @@ function readLevels(abstractNode) {
18989
19010
  }
18990
19011
  return levels.sort((left, right) => left.level - right.level);
18991
19012
  }
18992
- function readOverrides(numNode) {
19013
+ function readOverrides(numNode, context, numXmlPath, rawNumId) {
18993
19014
  const overrides = [];
19015
+ let overrideOrdinal = 0;
18994
19016
  for (const child of numNode.children) {
18995
19017
  if (child.type !== "element" || localName(child.name) !== "lvlOverride") {
18996
19018
  continue;
18997
19019
  }
19020
+ overrideOrdinal += 1;
18998
19021
  const rawLevel = readStringAttr(child, "w:ilvl");
18999
19022
  const level = rawLevel === void 0 ? void 0 : parseInteger(rawLevel);
19000
19023
  if (level === void 0) {
@@ -19004,8 +19027,26 @@ function readOverrides(numNode) {
19004
19027
  const rawStart = startOverrideNode ? readStringAttr(startOverrideNode, "w:val") : void 0;
19005
19028
  const startAt = rawStart === void 0 ? void 0 : parseInteger(rawStart);
19006
19029
  const levelDefinitionNode = findChildElementOptional2(child, "lvl");
19007
- const levelDefinition = levelDefinitionNode ? readLevelOverrideDefinition(levelDefinitionNode, level) : void 0;
19030
+ const overrideXmlPath = `${numXmlPath}/lvlOverride[${overrideOrdinal}]`;
19031
+ const levelDefinition = levelDefinitionNode ? readLevelOverrideDefinition(
19032
+ levelDefinitionNode,
19033
+ level,
19034
+ createNumberingChildSourceRef(
19035
+ context?.partPath,
19036
+ "lvl",
19037
+ `num:${rawNumId}:lvlOverride:${level}:lvl`,
19038
+ `${overrideXmlPath}/lvl[1]`
19039
+ )
19040
+ ) : void 0;
19008
19041
  overrides.push({
19042
+ ...context?.partPath !== void 0 ? {
19043
+ sourceRef: createNumberingChildSourceRef(
19044
+ context.partPath,
19045
+ "lvlOverride",
19046
+ `num:${rawNumId}:lvlOverride:${level}`,
19047
+ overrideXmlPath
19048
+ )
19049
+ } : {},
19009
19050
  level,
19010
19051
  ...startAt !== void 0 ? { startAt } : {},
19011
19052
  ...levelDefinition ? { levelDefinition } : {}
@@ -19013,7 +19054,7 @@ function readOverrides(numNode) {
19013
19054
  }
19014
19055
  return overrides.sort((left, right) => left.level - right.level);
19015
19056
  }
19016
- function readLevelDefinition(levelNode, fallbackLevel) {
19057
+ function readLevelDefinition(levelNode, fallbackLevel, sourceRef) {
19017
19058
  const rawLevel = readStringAttr(levelNode, "w:ilvl");
19018
19059
  const level = rawLevel === void 0 ? fallbackLevel : parseInteger(rawLevel);
19019
19060
  if (level === void 0) {
@@ -19043,6 +19084,7 @@ function readLevelDefinition(levelNode, fallbackLevel) {
19043
19084
  const lvlPicBulletNode = findChildElementOptional2(levelNode, "lvlPicBulletId");
19044
19085
  const picBulletId = lvlPicBulletNode ? readStringAttr(lvlPicBulletNode, "w:val") : void 0;
19045
19086
  return {
19087
+ ...sourceRef ? { sourceRef } : {},
19046
19088
  level,
19047
19089
  format,
19048
19090
  text,
@@ -19056,7 +19098,7 @@ function readLevelDefinition(levelNode, fallbackLevel) {
19056
19098
  ...picBulletId !== void 0 ? { picBulletId } : {}
19057
19099
  };
19058
19100
  }
19059
- function readLevelOverrideDefinition(levelNode, fallbackLevel) {
19101
+ function readLevelOverrideDefinition(levelNode, fallbackLevel, sourceRef) {
19060
19102
  const rawLevel = readStringAttr(levelNode, "w:ilvl");
19061
19103
  const level = rawLevel === void 0 ? fallbackLevel : parseInteger(rawLevel);
19062
19104
  if (level === void 0) {
@@ -19090,6 +19132,7 @@ function readLevelOverrideDefinition(levelNode, fallbackLevel) {
19090
19132
  return void 0;
19091
19133
  }
19092
19134
  return {
19135
+ ...sourceRef ? { sourceRef } : {},
19093
19136
  level,
19094
19137
  ...startAt !== void 0 ? { startAt } : {},
19095
19138
  ...format !== void 0 ? { format } : {},
@@ -32578,7 +32621,7 @@ async function computeStructuralHash(blocks) {
32578
32621
  }
32579
32622
 
32580
32623
  // src/runtime/layout/layout-engine-version.ts
32581
- var LAYOUT_ENGINE_VERSION = 88;
32624
+ var LAYOUT_ENGINE_VERSION = 89;
32582
32625
  var LAYCACHE_SCHEMA_VERSION = 12;
32583
32626
 
32584
32627
  // src/runtime/prerender/customxml-cache.ts
@@ -33232,6 +33275,15 @@ var LIST_TEXT_TARGET_KINDS = /* @__PURE__ */ new Set([
33232
33275
  "sdt-paragraph-text",
33233
33276
  "secondary-story-paragraph-text"
33234
33277
  ]);
33278
+ var OBJECT_COMMAND_INTENTS = /* @__PURE__ */ new Set([
33279
+ "image-layout",
33280
+ "image-frame",
33281
+ "chart-edit",
33282
+ "custom-xml-update",
33283
+ "embedded-content-update",
33284
+ "opaque-content-preserve",
33285
+ "object-edit"
33286
+ ]);
33235
33287
  function freezeList(values) {
33236
33288
  return Object.freeze([...values]);
33237
33289
  }
@@ -33776,6 +33828,35 @@ function listStructureCapability(scope, context) {
33776
33828
  ]
33777
33829
  );
33778
33830
  }
33831
+ function objectEditCapability(context) {
33832
+ const objectTargets = (context?.editableTargets?.entries ?? []).filter(
33833
+ (entry) => entry.kind === "object-anchor" || entry.kind === "custom-xml-content" || entry.kind === "opaque-content" || entry.commandFamily === "object" || entry.commandFamily === "preserve-only-refusal" || entry.runtimeCommand.intents.some((intent) => OBJECT_COMMAND_INTENTS.has(intent))
33834
+ );
33835
+ const supportedTargets = objectTargets.filter(
33836
+ (entry) => entry.runtimeCommand.status === "supported" && entry.runtimeCommand.intents.some((intent) => OBJECT_COMMAND_INTENTS.has(intent))
33837
+ );
33838
+ if (supportedTargets.length > 0) {
33839
+ return supportedCommand(
33840
+ "compile-supported:object-edit:editable-target",
33841
+ supportedTargets
33842
+ );
33843
+ }
33844
+ if (objectTargets.length > 0) {
33845
+ const blockers = commandTargetBlockers(objectTargets);
33846
+ return blocked(
33847
+ "compile-blocked:object-edit:target-ref-blocked",
33848
+ blockers.length > 0 ? blockers : ["compile-blocked:object-edit:target-ref-blocked"]
33849
+ );
33850
+ }
33851
+ return unsupported(
33852
+ "compile-unsupported:object-edit:no-target-family",
33853
+ [
33854
+ "compile-unsupported:object-edit:no-target-family",
33855
+ "capability:object-edit:l02-object-target-required",
33856
+ "capability:object-edit:l07-command-support-required"
33857
+ ]
33858
+ );
33859
+ }
33779
33860
  function deriveScopeCapabilities(scope, context = {}) {
33780
33861
  return {
33781
33862
  canReplaceText: replaceTextCapability(scope, context),
@@ -33792,7 +33873,8 @@ function deriveScopeCapabilities(scope, context = {}) {
33792
33873
  canEditTableStructure: tableStructureCapability(scope, context),
33793
33874
  canUseTableContinuationEvidence: tableContinuationEvidenceCapability(scope, context),
33794
33875
  canEditListText: listTextCapability(scope, context),
33795
- canEditListStructure: listStructureCapability(scope, context)
33876
+ canEditListStructure: listStructureCapability(scope, context),
33877
+ canEditObject: objectEditCapability(context)
33796
33878
  };
33797
33879
  }
33798
33880
 
@@ -34041,6 +34123,12 @@ function resolveScopeRange(entry, handle, positionMap) {
34041
34123
  if (inlineRange) return inlineRange;
34042
34124
  return positionMap.blocks.get(entry.blockIndex) ?? null;
34043
34125
  }
34126
+ case "image": {
34127
+ const key = `${entry.blockIndex}:${entry.inlineIndex}`;
34128
+ const inlineRange = positionMap.inlines.get(key);
34129
+ if (inlineRange) return inlineRange;
34130
+ return positionMap.blocks.get(entry.blockIndex) ?? null;
34131
+ }
34044
34132
  case "comment-thread":
34045
34133
  return anchorToRange(entry.thread.anchor);
34046
34134
  case "revision":
@@ -34167,6 +34255,11 @@ function tokensForScope(entry) {
34167
34255
  { kind: "row", index: entry.rowIndex },
34168
34256
  { kind: "cell", index: entry.cellIndex }
34169
34257
  ]);
34258
+ case "image":
34259
+ return Object.freeze([
34260
+ { kind: "block", index: entry.blockIndex },
34261
+ { kind: "inline", index: entry.inlineIndex }
34262
+ ]);
34170
34263
  default:
34171
34264
  return null;
34172
34265
  }
@@ -35913,6 +36006,11 @@ function deriveReplaceability(kind, provenance) {
35913
36006
  level: "preserve-only",
35914
36007
  reason: "field-result-is-computed-preserve-only"
35915
36008
  };
36009
+ case "image":
36010
+ return {
36011
+ level: "preserve-only",
36012
+ reason: "image-object-command-required"
36013
+ };
35916
36014
  case "comment-thread":
35917
36015
  return {
35918
36016
  level: "preserve-only",
@@ -37093,12 +37191,13 @@ function getLevelStartAt(level, levelDefinitions) {
37093
37191
  return levelDefinitions.get(level)?.startAt ?? DEFAULT_NUMBERING_START_AT;
37094
37192
  }
37095
37193
  function getNumberingFormatPosture(format, value) {
37096
- if (!isSupportedNumberingFormat(format)) {
37194
+ const registryEntry = getNumberingFormatRegistryEntry(format);
37195
+ if (!registryEntry || registryEntry.renderSupport === "approximated") {
37097
37196
  return {
37098
37197
  status: "approximated",
37099
37198
  requestedFormat: format,
37100
37199
  renderedFormat: "decimal",
37101
- reason: "unsupported-numbering-format-decimal-fallback"
37200
+ reason: registryEntry?.fallbackReason ?? "unsupported-numbering-format-decimal-fallback"
37102
37201
  };
37103
37202
  }
37104
37203
  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)) {
@@ -37129,56 +37228,148 @@ function renderLevelText(text, counters, levelDefinitions) {
37129
37228
  });
37130
37229
  return rendered.trim().length > 0 ? rendered : null;
37131
37230
  }
37132
- var SUPPORTED_NUMBERING_FORMATS = /* @__PURE__ */ new Set([
37133
- "decimal",
37134
- "decimalZero",
37135
- "upperLetter",
37136
- "lowerLetter",
37137
- "upperRoman",
37138
- "lowerRoman",
37139
- "hex",
37140
- "ordinal",
37141
- "cardinalText",
37142
- "ordinalText",
37143
- "chicago",
37144
- "bullet",
37145
- "none"
37146
- ]);
37147
37231
  function isSupportedNumberingFormat(format) {
37148
- return SUPPORTED_NUMBERING_FORMATS.has(format);
37232
+ return getNumberingFormatRegistryEntry(format)?.renderSupport === "supported";
37233
+ }
37234
+ function getNumberingFormatRegistryEntry(format) {
37235
+ return NUMBERING_FORMAT_REGISTRY.get(format);
37149
37236
  }
37150
37237
  function formatCounter(value, format) {
37151
- switch (format) {
37152
- case "decimal":
37153
- return String(value);
37154
- case "decimalZero":
37155
- return String(value).padStart(2, "0");
37156
- case "upperLetter":
37157
- return toAlphabetic2(value).toUpperCase();
37158
- case "lowerLetter":
37159
- return toAlphabetic2(value).toLowerCase();
37160
- case "upperRoman":
37161
- return toRoman2(value).toUpperCase();
37162
- case "lowerRoman":
37163
- return toRoman2(value).toLowerCase();
37164
- case "hex":
37165
- return value >= 0 ? value.toString(16).toUpperCase() : String(value);
37166
- case "ordinal":
37167
- return toOrdinal2(value);
37168
- case "cardinalText":
37169
- return toCardinalText2(value);
37170
- case "ordinalText":
37171
- return toOrdinalText2(value);
37172
- case "chicago":
37173
- return toChicago2(value);
37174
- case "bullet":
37175
- return "";
37176
- case "none":
37177
- return "";
37178
- default:
37179
- return String(value);
37180
- }
37238
+ return getNumberingFormatRegistryEntry(format)?.render(value) ?? String(value);
37181
37239
  }
37240
+ var exactNumberingFormatEntries = [
37241
+ {
37242
+ format: "decimal",
37243
+ renderSupport: "supported",
37244
+ renderedFormat: "decimal",
37245
+ supportsMutation: true,
37246
+ render: (value) => String(value)
37247
+ },
37248
+ {
37249
+ format: "decimalZero",
37250
+ renderSupport: "supported",
37251
+ renderedFormat: "decimalZero",
37252
+ supportsMutation: true,
37253
+ render: (value) => String(value).padStart(2, "0")
37254
+ },
37255
+ {
37256
+ format: "upperLetter",
37257
+ renderSupport: "supported",
37258
+ renderedFormat: "upperLetter",
37259
+ supportsMutation: true,
37260
+ render: (value) => toAlphabetic2(value).toUpperCase()
37261
+ },
37262
+ {
37263
+ format: "lowerLetter",
37264
+ renderSupport: "supported",
37265
+ renderedFormat: "lowerLetter",
37266
+ supportsMutation: true,
37267
+ render: (value) => toAlphabetic2(value).toLowerCase()
37268
+ },
37269
+ {
37270
+ format: "upperRoman",
37271
+ renderSupport: "supported",
37272
+ renderedFormat: "upperRoman",
37273
+ supportsMutation: true,
37274
+ render: (value) => toRoman2(value).toUpperCase()
37275
+ },
37276
+ {
37277
+ format: "lowerRoman",
37278
+ renderSupport: "supported",
37279
+ renderedFormat: "lowerRoman",
37280
+ supportsMutation: true,
37281
+ render: (value) => toRoman2(value).toLowerCase()
37282
+ },
37283
+ {
37284
+ format: "hex",
37285
+ renderSupport: "supported",
37286
+ renderedFormat: "hex",
37287
+ supportsMutation: true,
37288
+ render: (value) => value >= 0 ? value.toString(16).toUpperCase() : String(value)
37289
+ },
37290
+ {
37291
+ format: "ordinal",
37292
+ renderSupport: "supported",
37293
+ renderedFormat: "ordinal",
37294
+ supportsMutation: true,
37295
+ render: toOrdinal2
37296
+ },
37297
+ {
37298
+ format: "cardinalText",
37299
+ renderSupport: "supported",
37300
+ renderedFormat: "cardinalText",
37301
+ supportsMutation: true,
37302
+ render: toCardinalText2
37303
+ },
37304
+ {
37305
+ format: "ordinalText",
37306
+ renderSupport: "supported",
37307
+ renderedFormat: "ordinalText",
37308
+ supportsMutation: true,
37309
+ render: toOrdinalText2
37310
+ },
37311
+ {
37312
+ format: "chicago",
37313
+ renderSupport: "supported",
37314
+ renderedFormat: "chicago",
37315
+ supportsMutation: true,
37316
+ render: toChicago2
37317
+ },
37318
+ {
37319
+ format: "bullet",
37320
+ renderSupport: "supported",
37321
+ renderedFormat: "bullet",
37322
+ supportsMutation: true,
37323
+ render: () => ""
37324
+ },
37325
+ {
37326
+ format: "none",
37327
+ renderSupport: "supported",
37328
+ renderedFormat: "none",
37329
+ supportsMutation: true,
37330
+ render: () => ""
37331
+ }
37332
+ ];
37333
+ var approximatedDecimalFormats = [
37334
+ "decimalEnclosedCircle",
37335
+ "decimalEnclosedFullstop",
37336
+ "decimalEnclosedParen",
37337
+ "decimalFullWidth",
37338
+ "decimalHalfWidth",
37339
+ "aiueo",
37340
+ "iroha",
37341
+ "ganada",
37342
+ "chosung",
37343
+ "russianLower",
37344
+ "russianUpper",
37345
+ "hebrew1",
37346
+ "hebrew2",
37347
+ "arabicAlpha",
37348
+ "arabicAbjad",
37349
+ "thaiLetters",
37350
+ "thaiNumbers",
37351
+ "hindiLetters",
37352
+ "hindiNumbers",
37353
+ "ideographDigital",
37354
+ "ideographTraditional",
37355
+ "chineseCounting",
37356
+ "japaneseCounting",
37357
+ "japaneseLegal"
37358
+ ];
37359
+ var approximatedNumberingFormatEntries = approximatedDecimalFormats.map((format) => ({
37360
+ format,
37361
+ renderSupport: "approximated",
37362
+ renderedFormat: "decimal",
37363
+ supportsMutation: false,
37364
+ fallbackReason: "unsupported-numbering-format-decimal-fallback",
37365
+ render: (value) => String(value)
37366
+ }));
37367
+ var NUMBERING_FORMAT_REGISTRY = new Map(
37368
+ [...exactNumberingFormatEntries, ...approximatedNumberingFormatEntries].map((entry) => [
37369
+ entry.format,
37370
+ entry
37371
+ ])
37372
+ );
37182
37373
  function toOrdinal2(value) {
37183
37374
  if (value <= 0) return String(value);
37184
37375
  const lastTwo = value % 100;
@@ -37832,12 +38023,36 @@ var DEFAULT_HYPERLINK_COLOR_HEX = "0563C1";
37832
38023
  function resolveHyperlinkRunFormatting(input, catalog, resolver) {
37833
38024
  const augmentedInput = input.characterStyleId === void 0 ? { ...input, characterStyleId: HYPERLINK_CHARACTER_STYLE_ID } : input;
37834
38025
  const cascade = resolveEffectiveRunFormatting(augmentedInput, catalog);
37835
- const resolvedColor = resolveHyperlinkColorHex(cascade, resolver);
38026
+ const resolvedColor = resolveHyperlinkColorHex(
38027
+ stripInheritedColorHexForImplicitHyperlink(input, catalog, cascade),
38028
+ resolver
38029
+ );
37836
38030
  if (resolvedColor && resolvedColor !== cascade.colorHex) {
37837
38031
  return { ...cascade, colorHex: resolvedColor };
37838
38032
  }
37839
38033
  return cascade;
37840
38034
  }
38035
+ function hasDirectNonAutoColor(input) {
38036
+ return Boolean(input.direct?.colorHex && input.direct.colorHex !== "auto");
38037
+ }
38038
+ function characterStyleDeclaresColorHex(styleId, catalog) {
38039
+ if (!catalog) return false;
38040
+ const chain = resolveCharacterStyleChain(styleId, catalog);
38041
+ return chain.some((chainStyleId) => {
38042
+ const colorHex = catalog.characters[chainStyleId]?.runProperties?.colorHex;
38043
+ return Boolean(colorHex && colorHex !== "auto");
38044
+ });
38045
+ }
38046
+ function stripInheritedColorHexForImplicitHyperlink(originalInput, catalog, cascade) {
38047
+ if (originalInput.characterStyleId !== void 0 || hasDirectNonAutoColor(originalInput) || !cascade.colorHex || cascade.colorHex === "auto" || characterStyleDeclaresColorHex(HYPERLINK_CHARACTER_STYLE_ID, catalog)) {
38048
+ return cascade;
38049
+ }
38050
+ const inheritedCascade = resolveEffectiveRunFormatting(originalInput, catalog);
38051
+ if (inheritedCascade.colorHex !== cascade.colorHex) {
38052
+ return cascade;
38053
+ }
38054
+ return { ...cascade, colorHex: void 0 };
38055
+ }
37841
38056
  function resolveHyperlinkColorHex(cascade, resolver) {
37842
38057
  if (cascade.colorHex && cascade.colorHex !== "auto") {
37843
38058
  return cascade.colorHex;
@@ -39092,6 +39307,55 @@ function compileHeadingScope(entry, options = {}) {
39092
39307
  };
39093
39308
  }
39094
39309
 
39310
+ // src/runtime/scopes/scope-kinds/image.ts
39311
+ function imageAltText(image) {
39312
+ if (image.type === "image") return image.altText ?? "";
39313
+ return image.anchor.docPr?.descr ?? image.anchor.docPr?.name ?? "";
39314
+ }
39315
+ function imageMediaId(image) {
39316
+ if (image.type === "image") return image.mediaId;
39317
+ return image.content.type === "picture" ? image.content.mediaId : void 0;
39318
+ }
39319
+ function imageDisplay(image) {
39320
+ if (image.type === "image") return image.display;
39321
+ return image.anchor.display;
39322
+ }
39323
+ function imageSourceKind(image) {
39324
+ return image.type === "image" ? "legacy-image" : "drawing-picture";
39325
+ }
39326
+ function compileImageScope(entry) {
39327
+ const { handle, image } = entry;
39328
+ const altText = imageAltText(image);
39329
+ const mediaId = imageMediaId(image);
39330
+ const display = imageDisplay(image);
39331
+ const sourceKind = imageSourceKind(image);
39332
+ return {
39333
+ handle,
39334
+ kind: "image",
39335
+ classifications: entry.classifications,
39336
+ content: {
39337
+ text: altText,
39338
+ excerpt: buildExcerpt(altText),
39339
+ authority: "structural-summary"
39340
+ },
39341
+ formatting: {},
39342
+ layout: display ? { flowKind: display } : {},
39343
+ geometry: {},
39344
+ workflow: { scopeIds: [], effectiveMode: "edit" },
39345
+ replaceability: deriveReplaceability("image", handle.provenance),
39346
+ audit: {
39347
+ source: "runtime",
39348
+ derivedFrom: [
39349
+ "canonical",
39350
+ `image-source:${sourceKind}`,
39351
+ ...mediaId ? [`media-id:${mediaId}`] : []
39352
+ ],
39353
+ confidence: "medium"
39354
+ },
39355
+ partial: true
39356
+ };
39357
+ }
39358
+
39095
39359
  // src/runtime/scopes/scope-kinds/list-item.ts
39096
39360
  function compileListItemScope(entry, options = {}) {
39097
39361
  const { handle, paragraph } = entry;
@@ -39675,6 +39939,8 @@ function compileScope(entry, optionsOrCatalog) {
39675
39939
  });
39676
39940
  case "field":
39677
39941
  return compileFieldScope(entry);
39942
+ case "image":
39943
+ return compileImageScope(entry);
39678
39944
  case "comment-thread":
39679
39945
  return compileCommentThreadScope(entry);
39680
39946
  case "revision":
@@ -39863,6 +40129,44 @@ function enumerateFieldsInParagraph(paragraph, blockIndex, documentId, parentSco
39863
40129
  }
39864
40130
  return out;
39865
40131
  }
40132
+ function isImageInline(child) {
40133
+ return child.type === "image" || child.type === "drawing_frame" && child.content.type === "picture";
40134
+ }
40135
+ function enumerateImagesInParagraph(paragraph, blockIndex, documentId, parentScopeId) {
40136
+ const out = [];
40137
+ for (let i = 0; i < paragraph.children.length; i += 1) {
40138
+ const child = paragraph.children[i];
40139
+ if (!isImageInline(child)) continue;
40140
+ const semanticPath = [
40141
+ "body",
40142
+ "paragraph",
40143
+ String(blockIndex),
40144
+ "image",
40145
+ String(i)
40146
+ ];
40147
+ const scopeId = `image:${blockIndex}:${i}`;
40148
+ const handle = {
40149
+ scopeId,
40150
+ documentId,
40151
+ storyTarget: MAIN_STORY,
40152
+ semanticPath,
40153
+ parentScopeId,
40154
+ stableRef: { kind: "semantic-path", value: semanticPath.join("/") },
40155
+ provenance: "derived",
40156
+ rangePrecision: "canonical"
40157
+ };
40158
+ out.push({
40159
+ kind: "image",
40160
+ handle,
40161
+ image: child,
40162
+ paragraph,
40163
+ blockIndex,
40164
+ inlineIndex: i,
40165
+ classifications: Object.freeze([])
40166
+ });
40167
+ }
40168
+ return out;
40169
+ }
39866
40170
  function enumerateCommentThreads(document2, documentId) {
39867
40171
  const review = document2.review;
39868
40172
  const comments = review?.comments;
@@ -39993,6 +40297,8 @@ function enumerateScopes(document2, inputs = {}) {
39993
40297
  });
39994
40298
  const fields = enumerateFieldsInParagraph(block, index, documentId, scopeId);
39995
40299
  for (const field of fields) results.push(field);
40300
+ const images = enumerateImagesInParagraph(block, index, documentId, scopeId);
40301
+ for (const image of images) results.push(image);
39996
40302
  continue;
39997
40303
  }
39998
40304
  if (block.type === "table") {
@@ -40444,6 +40750,64 @@ function createIssue(runtime, input) {
40444
40750
  };
40445
40751
  }
40446
40752
 
40753
+ // src/runtime/scopes/object-evidence.ts
40754
+ var OBJECT_INTENTS = /* @__PURE__ */ new Set([
40755
+ "image-layout",
40756
+ "image-frame",
40757
+ "chart-edit",
40758
+ "custom-xml-update",
40759
+ "embedded-content-update",
40760
+ "opaque-content-preserve",
40761
+ "object-edit",
40762
+ "preserve-only-refusal"
40763
+ ]);
40764
+ function unique2(values) {
40765
+ return Object.freeze([...new Set(values.filter((value) => value.length > 0))]);
40766
+ }
40767
+ function isObjectTarget(entry) {
40768
+ return entry.object !== void 0 || entry.kind === "object-anchor" || entry.kind === "custom-xml-content" || entry.kind === "opaque-content" || entry.commandFamily === "object" || entry.runtimeCommand.intents.some((intent) => OBJECT_INTENTS.has(intent));
40769
+ }
40770
+ function blockersFor(entry) {
40771
+ return unique2([
40772
+ ...entry.posture.blockers,
40773
+ ...entry.runtimeCommand.blockers ?? [],
40774
+ ...entry.runtimeTextCommand.blockers ?? [],
40775
+ ...(entry.workflowBlockers ?? []).flatMap((blocker2) => [
40776
+ blocker2.blocker,
40777
+ blocker2.refusalId
40778
+ ]),
40779
+ entry.runtimeCommand.status === "blocked" ? entry.runtimeCommand.reason : ""
40780
+ ]);
40781
+ }
40782
+ function projectEntry2(entry) {
40783
+ const blockers = blockersFor(entry);
40784
+ return {
40785
+ targetKey: entry.targetKey,
40786
+ kind: entry.kind,
40787
+ ...entry.object?.objectKind ? { objectKind: entry.object.objectKind } : {},
40788
+ relation: entry.relation,
40789
+ commandFamily: entry.commandFamily,
40790
+ editability: entry.editability,
40791
+ ...entry.sourceRef ? { sourceRef: entry.sourceRef } : {},
40792
+ ...entry.object ? { object: entry.object } : {},
40793
+ runtimeCommand: entry.runtimeCommand,
40794
+ blockers,
40795
+ ...entry.posture.preserveOnly ? { preserveOnly: true } : {}
40796
+ };
40797
+ }
40798
+ function deriveScopeObjectEvidence(editableTargets) {
40799
+ const entries = Object.freeze(
40800
+ [...editableTargets?.entries ?? []].filter(isObjectTarget).map(projectEntry2).sort((left, right) => left.targetKey.localeCompare(right.targetKey))
40801
+ );
40802
+ const blockers = unique2(entries.flatMap((entry) => [...entry.blockers]));
40803
+ return {
40804
+ status: entries.length > 0 ? "present" : "none",
40805
+ count: entries.length,
40806
+ blockers,
40807
+ entries
40808
+ };
40809
+ }
40810
+
40447
40811
  // src/runtime/scopes/evidence.ts
40448
40812
  function anchorRange(anchor) {
40449
40813
  switch (anchor.kind) {
@@ -40626,6 +40990,7 @@ function composeEvidence(inputs) {
40626
40990
  ...editableTargets ? { editableTargets } : {},
40627
40991
  layout
40628
40992
  });
40993
+ const objects = deriveScopeObjectEvidence(editableTargets);
40629
40994
  return {
40630
40995
  formattingSummary: formattingSummaryOf(scope),
40631
40996
  reviewItemIds,
@@ -40636,6 +41001,7 @@ function composeEvidence(inputs) {
40636
41001
  ...adjacentGeometry ? { adjacentGeometry } : {},
40637
41002
  visualization: deriveScopeVisualization(scope),
40638
41003
  ...editableTargets ? { editableTargets } : {},
41004
+ objects,
40639
41005
  ...table ? { table } : {},
40640
41006
  contentControls,
40641
41007
  capabilities,
@@ -40832,6 +41198,10 @@ function extractNLHaystack(entry) {
40832
41198
  }
40833
41199
  return out.slice(0, 200).toLowerCase();
40834
41200
  }
41201
+ case "image": {
41202
+ const text = entry.image.type === "image" ? entry.image.altText ?? "" : entry.image.anchor.docPr?.descr ?? entry.image.anchor.docPr?.name ?? "";
41203
+ return text.slice(0, 200).toLowerCase();
41204
+ }
40835
41205
  case "table":
40836
41206
  case "table-row":
40837
41207
  case "table-cell":
@@ -50928,6 +51298,14 @@ function paginateSectionBlocksWithSplits(section, blocks, layout, footnotes, mea
50928
51298
  pushPage(block.from);
50929
51299
  continue;
50930
51300
  }
51301
+ if (isStandalonePageBreakParagraph(block)) {
51302
+ if (columnHeight > 0) {
51303
+ pushPage(nextBoundary);
51304
+ } else {
51305
+ pageStart = Math.max(pageStart, Math.min(nextBoundary, section.end));
51306
+ }
51307
+ break;
51308
+ }
50931
51309
  const effectiveNoteHeight = estimateFootnoteReservation(
50932
51310
  block,
50933
51311
  footnotes,
@@ -51102,6 +51480,21 @@ function hasPageBreak(block) {
51102
51480
  }
51103
51481
  return nestedBlocks(block).some(hasPageBreak);
51104
51482
  }
51483
+ function isStandalonePageBreakParagraph(block) {
51484
+ if (block.kind !== "paragraph") return false;
51485
+ let sawPageBreak = false;
51486
+ for (const segment of block.segments) {
51487
+ if (segment.kind === "opaque_inline" && segment.label === "Page break") {
51488
+ sawPageBreak = true;
51489
+ continue;
51490
+ }
51491
+ if (segment.kind === "text" && segment.text.trim().length === 0) {
51492
+ continue;
51493
+ }
51494
+ return false;
51495
+ }
51496
+ return sawPageBreak;
51497
+ }
51105
51498
  function nestedBlocks(block) {
51106
51499
  if (block.kind === "sdt_block") {
51107
51500
  return block.children;
@@ -52563,6 +52956,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
52563
52956
  for (let blockIndex = 0; blockIndex < surface.blocks.length; blockIndex += 1) {
52564
52957
  const block = surface.blocks[blockIndex];
52565
52958
  const blockPath = `main/block[${blockIndex}]`;
52959
+ if (isStandalonePageBreakParagraph2(block)) {
52960
+ continue;
52961
+ }
52566
52962
  if (block.kind === "table") {
52567
52963
  const tableSliceList = splits?.tablesByBlockId.get(block.blockId);
52568
52964
  if (tableSliceList && tableSliceList.length > 1) {
@@ -52648,6 +53044,23 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
52648
53044
  }
52649
53045
  return byPage;
52650
53046
  }
53047
+ function isStandalonePageBreakParagraph2(block) {
53048
+ if (block.kind !== "paragraph") {
53049
+ return false;
53050
+ }
53051
+ let sawPageBreak = false;
53052
+ for (const segment of block.segments) {
53053
+ if (segment.kind === "opaque_inline" && segment.label === "Page break") {
53054
+ sawPageBreak = true;
53055
+ continue;
53056
+ }
53057
+ if (segment.kind === "text" && segment.text.trim().length === 0) {
53058
+ continue;
53059
+ }
53060
+ return false;
53061
+ }
53062
+ return sawPageBreak;
53063
+ }
52651
53064
  function projectLineBoxesForPageFragments(pages, fragmentsByPageIndex, fragmentMeasurementsByPageIndex, surface) {
52652
53065
  const byPage = /* @__PURE__ */ new Map();
52653
53066
  const blocksById = surface ? new Map(surface.blocks.map((block) => [block.blockId, block])) : /* @__PURE__ */ new Map();
@@ -53160,13 +53573,11 @@ function buildBookmarkRanges(targets) {
53160
53573
  }
53161
53574
  var EMPTY_NUMBERING_INPUT_INDEX = {
53162
53575
  byNumberingKey: /* @__PURE__ */ new Map(),
53163
- byBlockPath: /* @__PURE__ */ new Map(),
53164
- byParagraphIndex: /* @__PURE__ */ new Map()
53576
+ byBlockPath: /* @__PURE__ */ new Map()
53165
53577
  };
53166
53578
  function buildNumberingInputIndex(numberingInputs) {
53167
53579
  const byNumberingKey = /* @__PURE__ */ new Map();
53168
53580
  const byBlockPath = /* @__PURE__ */ new Map();
53169
- const byParagraph = /* @__PURE__ */ new Map();
53170
53581
  for (const input of numberingInputs) {
53171
53582
  if (!byNumberingKey.has(input.numberingKey)) {
53172
53583
  byNumberingKey.set(input.numberingKey, input);
@@ -53174,11 +53585,8 @@ function buildNumberingInputIndex(numberingInputs) {
53174
53585
  if (!byBlockPath.has(input.blockPath)) {
53175
53586
  byBlockPath.set(input.blockPath, input);
53176
53587
  }
53177
- if (!byParagraph.has(input.paragraphIndex)) {
53178
- byParagraph.set(input.paragraphIndex, input);
53179
- }
53180
53588
  }
53181
- return { byNumberingKey, byBlockPath, byParagraphIndex: byParagraph };
53589
+ return { byNumberingKey, byBlockPath };
53182
53590
  }
53183
53591
  function collectBookmarkRangeLayoutFacts(fragmentId, blockPath, bookmarkRanges) {
53184
53592
  if (!blockPath || !bookmarkRanges || bookmarkRanges.length === 0) return [];
@@ -53298,8 +53706,7 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingIndex, n
53298
53706
  const canonical = lookupNumberingInput(
53299
53707
  numberingIndex,
53300
53708
  numberingKey,
53301
- context.path,
53302
- paragraphIndex
53709
+ context.path
53303
53710
  );
53304
53711
  const target = findNumberingTarget(numberingTargets, context.path);
53305
53712
  const numberingLayoutId = numberingKey ?? [
@@ -53339,7 +53746,7 @@ function findNumberingTarget(numberingTargets, blockPath) {
53339
53746
  if (blockPath === void 0) return void 0;
53340
53747
  return numberingTargets.find((target) => target.blockPath === blockPath);
53341
53748
  }
53342
- function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraphIndex) {
53749
+ function lookupNumberingInput(numberingIndex, numberingKey, blockPath) {
53343
53750
  if (!numberingIndex) return void 0;
53344
53751
  if (numberingKey !== void 0) {
53345
53752
  const byKey = numberingIndex.byNumberingKey.get(numberingKey);
@@ -53349,7 +53756,7 @@ function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraph
53349
53756
  const byPath = numberingIndex.byBlockPath.get(blockPath);
53350
53757
  if (byPath !== void 0) return byPath;
53351
53758
  }
53352
- return paragraphIndex !== void 0 ? numberingIndex.byParagraphIndex.get(paragraphIndex) : void 0;
53759
+ return void 0;
53353
53760
  }
53354
53761
  function collectNumberingUnavailableReasons(numbering, canonical) {
53355
53762
  const reasons = [];
@@ -55047,6 +55454,400 @@ function createViewportFamily(runtime) {
55047
55454
  };
55048
55455
  }
55049
55456
 
55457
+ // src/io/ooxml/numbering-catalog-mutation.ts
55458
+ function getListKind(catalog, numberingInstanceId) {
55459
+ const instance = catalog.instances[numberingInstanceId];
55460
+ const definition = instance ? catalog.abstractDefinitions[instance.abstractNumberingId] : void 0;
55461
+ const levelZero = definition?.levels.find((level) => level.level === 0);
55462
+ if (!levelZero) return void 0;
55463
+ return levelZero.format === "bullet" ? "bulleted" : "numbered";
55464
+ }
55465
+
55466
+ // src/api/v3/runtime/lists.ts
55467
+ var SUPPORTED_COMMANDS = [
55468
+ "toggle-numbered",
55469
+ "toggle-bulleted",
55470
+ "indent",
55471
+ "outdent",
55472
+ "restart-numbering",
55473
+ "continue-numbering"
55474
+ ];
55475
+ var UNSUPPORTED_COMMANDS = [
55476
+ "create",
55477
+ "attach",
55478
+ "detach",
55479
+ "join",
55480
+ "separate",
55481
+ "split",
55482
+ "set-value",
55483
+ "apply-template",
55484
+ "capture-template",
55485
+ "apply-preset",
55486
+ "set-level-numbering",
55487
+ "set-level-bullet",
55488
+ "set-level-picture-bullet",
55489
+ "set-level-alignment",
55490
+ "set-level-indents",
55491
+ "set-level-trailing-character",
55492
+ "set-level-marker-font",
55493
+ "set-level-text",
55494
+ "set-level-start",
55495
+ "set-level-layout",
55496
+ "convert-to-text",
55497
+ "paste-fragment",
55498
+ "drop-fragment"
55499
+ ];
55500
+ var applyCommandMetadata = {
55501
+ name: "runtime.lists.applyCommand",
55502
+ status: "live-with-adapter",
55503
+ sourceLayer: "runtime-core",
55504
+ liveEvidence: {
55505
+ runnerTest: "test/api/v3/runtime/lists.test.ts",
55506
+ commit: "refactor-07-runtime-lists-namespace"
55507
+ },
55508
+ uxIntent: {
55509
+ uiVisible: true,
55510
+ expectsUxResponse: "surface-refresh",
55511
+ expectedDelta: "list structure changes through the L07 list command surface"
55512
+ },
55513
+ agentMetadata: { readOrMutate: "mutate", boundedScope: "scope", auditCategory: "list-command" },
55514
+ stateClass: "A-canonical",
55515
+ persistsTo: "canonical",
55516
+ broadcastsVia: "crdt",
55517
+ rwdReference: "\xA7Runtime API \xA7 runtime.lists.applyCommand. Dispatches only proven L07 list commands through opaque list targets; future commands return owner-routed blockers until command/export/readback support lands."
55518
+ };
55519
+ function createListsFamily(runtime) {
55520
+ return {
55521
+ list(input = {}) {
55522
+ const document2 = runtime.getCanonicalDocument();
55523
+ const rows = currentListTargets(document2).filter((entry) => input.storyKey === void 0 || entry.target.storyKey === input.storyKey).map((entry) => toReadback(document2, entry.target, entry.paragraph));
55524
+ return input.limit === void 0 ? rows : rows.slice(0, Math.max(0, input.limit));
55525
+ },
55526
+ get(input) {
55527
+ const resolved = resolveCurrentListTarget(runtime.getCanonicalDocument(), input);
55528
+ return resolved.kind === "resolved" ? toReadback(runtime.getCanonicalDocument(), resolved.target, resolved.paragraph) : null;
55529
+ },
55530
+ previewCommand(input) {
55531
+ return previewListCommand(runtime.getCanonicalDocument(), input);
55532
+ },
55533
+ applyCommand(input) {
55534
+ const preview = previewListCommand(runtime.getCanonicalDocument(), input);
55535
+ if (!preview.supported || !preview.target) {
55536
+ return {
55537
+ applied: false,
55538
+ command: input.command,
55539
+ before: preview.target,
55540
+ blockers: preview.blockers
55541
+ };
55542
+ }
55543
+ const resolved = resolveCurrentListTarget(runtime.getCanonicalDocument(), {
55544
+ addressKey: preview.target.addressKey
55545
+ });
55546
+ if (resolved.kind !== "resolved") {
55547
+ return {
55548
+ applied: false,
55549
+ command: input.command,
55550
+ before: preview.target,
55551
+ blockers: [resolved.blocker]
55552
+ };
55553
+ }
55554
+ const command = editorCommandForListCommand(
55555
+ input.command,
55556
+ resolved.target,
55557
+ runtime.now(),
55558
+ input.startAt
55559
+ );
55560
+ if (!command) {
55561
+ return {
55562
+ applied: false,
55563
+ command: input.command,
55564
+ before: preview.target,
55565
+ blockers: [
55566
+ unsupportedCommandBlocker(input.command, {
55567
+ targetKey: preview.target.targetKey,
55568
+ addressKey: preview.target.addressKey
55569
+ })
55570
+ ]
55571
+ };
55572
+ }
55573
+ const beforeDocument = runtime.getCanonicalDocument();
55574
+ runtime.dispatch(command);
55575
+ const afterDocument = runtime.getCanonicalDocument();
55576
+ const after = resolveCurrentListTarget(afterDocument, { targetKey: preview.target.targetKey });
55577
+ emitUxResponse(runtime, {
55578
+ apiFn: applyCommandMetadata.name,
55579
+ intent: applyCommandMetadata.uxIntent.expectedDelta ?? "",
55580
+ mockOrLive: "live",
55581
+ uiVisible: true,
55582
+ expectedDelta: applyCommandMetadata.uxIntent.expectedDelta
55583
+ });
55584
+ return {
55585
+ applied: beforeDocument !== afterDocument,
55586
+ command: input.command,
55587
+ before: preview.target,
55588
+ ...after.kind === "resolved" ? { after: toReadback(afterDocument, after.target, after.paragraph) } : {},
55589
+ blockers: []
55590
+ };
55591
+ }
55592
+ };
55593
+ }
55594
+ function previewListCommand(document2, input) {
55595
+ const resolved = resolveCurrentListTarget(document2, input);
55596
+ if (resolved.kind !== "resolved") {
55597
+ return {
55598
+ command: input.command,
55599
+ supported: false,
55600
+ affectedTargets: [],
55601
+ blockers: [resolved.blocker]
55602
+ };
55603
+ }
55604
+ const target = toReadback(document2, resolved.target, resolved.paragraph);
55605
+ const targetRef = { targetKey: target.targetKey, addressKey: target.addressKey };
55606
+ if (!SUPPORTED_COMMANDS.includes(input.command)) {
55607
+ return {
55608
+ command: input.command,
55609
+ supported: false,
55610
+ target,
55611
+ affectedTargets: [target],
55612
+ blockers: [unsupportedCommandBlocker(input.command, targetRef)]
55613
+ };
55614
+ }
55615
+ const canContinuePrevious = canContinuePreviousSequence(document2, resolved.paragraphIndex);
55616
+ const canJoin = canJoinPreviousSequence(document2, resolved.paragraphIndex);
55617
+ const blockers = [];
55618
+ if (input.command === "continue-numbering" && !canContinuePrevious) {
55619
+ blockers.push({
55620
+ code: "list-continue-target-missing",
55621
+ ownerLayer: "L07",
55622
+ message: "No previous compatible list sequence is available for continue-numbering.",
55623
+ ...targetRef
55624
+ });
55625
+ }
55626
+ return {
55627
+ command: input.command,
55628
+ supported: blockers.length === 0,
55629
+ target,
55630
+ affectedTargets: [target],
55631
+ blockers,
55632
+ canJoin,
55633
+ canContinuePrevious
55634
+ };
55635
+ }
55636
+ function editorCommandForListCommand(command, editableTarget, timestamp, startAt) {
55637
+ const origin = { source: "api", timestamp };
55638
+ switch (command) {
55639
+ case "toggle-numbered":
55640
+ return { type: "list.toggle", kind: "numbered", editableTargets: [editableTarget], origin };
55641
+ case "toggle-bulleted":
55642
+ return { type: "list.toggle", kind: "bulleted", editableTargets: [editableTarget], origin };
55643
+ case "indent":
55644
+ return { type: "list.indent", editableTargets: [editableTarget], origin };
55645
+ case "outdent":
55646
+ return { type: "list.outdent", editableTargets: [editableTarget], origin };
55647
+ case "restart-numbering":
55648
+ return {
55649
+ type: "list.restart-numbering",
55650
+ editableTarget,
55651
+ ...startAt !== void 0 ? { startAt } : {},
55652
+ origin
55653
+ };
55654
+ case "continue-numbering":
55655
+ return { type: "list.continue-numbering", editableTarget, origin };
55656
+ default:
55657
+ return void 0;
55658
+ }
55659
+ }
55660
+ function resolveCurrentListTarget(document2, input) {
55661
+ if (input.editableTarget) {
55662
+ const shapeIssues = validateEditableTargetRef(input.editableTarget);
55663
+ if (shapeIssues.length > 0) {
55664
+ return {
55665
+ kind: "blocked",
55666
+ blocker: {
55667
+ code: "list-target-malformed",
55668
+ ownerLayer: "L07",
55669
+ message: `List target is malformed: ${shapeIssues[0]?.path ?? "$"}.`,
55670
+ targetKey: input.editableTarget.targetKey,
55671
+ addressKey: input.editableTarget.listAddress?.addressKey
55672
+ }
55673
+ };
55674
+ }
55675
+ }
55676
+ const requestedTargetKey = input.editableTarget?.targetKey ?? input.targetKey;
55677
+ const requestedAddressKey = input.editableTarget?.listAddress?.addressKey ?? input.addressKey;
55678
+ if (!requestedTargetKey && !requestedAddressKey) {
55679
+ return {
55680
+ kind: "blocked",
55681
+ blocker: {
55682
+ code: "list-target-required",
55683
+ ownerLayer: "L07",
55684
+ message: "runtime.lists requires a targetKey, addressKey, or editableTarget."
55685
+ }
55686
+ };
55687
+ }
55688
+ const currentTargets = currentListTargets(document2);
55689
+ const resolved = currentTargets.find(
55690
+ ({ target }) => requestedTargetKey !== void 0 && target.targetKey === requestedTargetKey || requestedAddressKey !== void 0 && target.listAddress?.addressKey === requestedAddressKey
55691
+ );
55692
+ if (!resolved) {
55693
+ return {
55694
+ kind: "blocked",
55695
+ blocker: {
55696
+ code: "list-target-not-found",
55697
+ ownerLayer: "L07",
55698
+ message: "List target no longer resolves in the current canonical document.",
55699
+ ...requestedTargetKey !== void 0 ? { targetKey: requestedTargetKey } : {},
55700
+ ...requestedAddressKey !== void 0 ? { addressKey: requestedAddressKey } : {}
55701
+ }
55702
+ };
55703
+ }
55704
+ if (input.editableTarget && !sameTargetStaleHash(input.editableTarget, resolved.target)) {
55705
+ return {
55706
+ kind: "blocked",
55707
+ blocker: {
55708
+ code: "list-target-stale",
55709
+ ownerLayer: "L07",
55710
+ message: "List target resolved by identity but stale discriminators changed.",
55711
+ targetKey: input.editableTarget.targetKey,
55712
+ addressKey: input.editableTarget.listAddress?.addressKey
55713
+ }
55714
+ };
55715
+ }
55716
+ if (resolved.target.editability !== "editable" || resolved.target.posture.blockers.length > 0) {
55717
+ return {
55718
+ kind: "blocked",
55719
+ blocker: {
55720
+ code: "list-target-non-editable",
55721
+ ownerLayer: "L07",
55722
+ message: resolved.target.posture.blockers.length > 0 ? `List target is not editable: ${resolved.target.posture.blockers.join(", ")}.` : "List target is not editable.",
55723
+ targetKey: resolved.target.targetKey,
55724
+ addressKey: resolved.target.listAddress?.addressKey
55725
+ }
55726
+ };
55727
+ }
55728
+ return { kind: "resolved", ...resolved };
55729
+ }
55730
+ function currentListTargets(document2) {
55731
+ const paragraphs = collectParagraphEntries(document2.content.children, "main");
55732
+ const targets = collectEditableTargetRefs(document2).filter(isListTextTarget);
55733
+ const byBlockPath = /* @__PURE__ */ new Map();
55734
+ for (const target of targets) byBlockPath.set(target.blockPath, target);
55735
+ const out = [];
55736
+ for (let paragraphIndex = 0; paragraphIndex < paragraphs.length; paragraphIndex += 1) {
55737
+ const entry = paragraphs[paragraphIndex];
55738
+ if (!entry?.paragraph.numbering) continue;
55739
+ const target = byBlockPath.get(entry.blockPath);
55740
+ if (!target) continue;
55741
+ out.push({ target, paragraph: entry.paragraph, paragraphIndex });
55742
+ }
55743
+ return out;
55744
+ }
55745
+ function collectParagraphEntries(blocks, basePath) {
55746
+ const out = [];
55747
+ collectParagraphEntriesInto(blocks, basePath, out);
55748
+ return out;
55749
+ }
55750
+ function collectParagraphEntriesInto(blocks, basePath, out) {
55751
+ for (let blockIndex = 0; blockIndex < blocks.length; blockIndex += 1) {
55752
+ const block = blocks[blockIndex];
55753
+ if (!block) continue;
55754
+ const blockPath = `${basePath}/block[${blockIndex}]`;
55755
+ switch (block.type) {
55756
+ case "paragraph":
55757
+ out.push({ paragraph: block, blockPath });
55758
+ break;
55759
+ case "table":
55760
+ for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
55761
+ const row = block.rows[rowIndex];
55762
+ if (!row) continue;
55763
+ for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex += 1) {
55764
+ const cell = row.cells[cellIndex];
55765
+ if (!cell) continue;
55766
+ collectParagraphEntriesInto(
55767
+ cell.children,
55768
+ `${blockPath}/row[${rowIndex}]/cell[${cellIndex}]`,
55769
+ out
55770
+ );
55771
+ }
55772
+ }
55773
+ break;
55774
+ case "sdt":
55775
+ collectParagraphEntriesInto(block.children, blockPath, out);
55776
+ break;
55777
+ case "custom_xml":
55778
+ break;
55779
+ default:
55780
+ break;
55781
+ }
55782
+ }
55783
+ }
55784
+ function isListTextTarget(target) {
55785
+ return target.commandFamily === "text-leaf" && target.listAddress?.operationScope === "list-text" && target.listAddress.addressKind === "list-item-text";
55786
+ }
55787
+ function sameTargetStaleHash(left, right) {
55788
+ return left.targetKey === right.targetKey && left.listAddress?.addressKey === right.listAddress?.addressKey && left.listAddress?.resolver?.staleHash === right.listAddress?.resolver?.staleHash && left.staleCheck.paragraphTextHash === right.staleCheck.paragraphTextHash && left.staleCheck.paragraphTextLength === right.staleCheck.paragraphTextLength && left.staleCheck.inlineCount === right.staleCheck.inlineCount;
55789
+ }
55790
+ function toReadback(document2, target, paragraph) {
55791
+ const numbering = paragraph.numbering;
55792
+ const instance = document2.numbering.instances[numbering.numberingInstanceId];
55793
+ const listKind = instance ? getListKind(document2.numbering, numbering.numberingInstanceId) : void 0;
55794
+ return {
55795
+ targetKey: target.targetKey,
55796
+ actionHandle: `list-action:${target.listAddress.addressKey}`,
55797
+ kind: target.kind,
55798
+ storyKey: target.storyKey,
55799
+ blockPath: target.blockPath,
55800
+ leafPath: target.leafPath,
55801
+ addressKey: target.listAddress.addressKey,
55802
+ numberingInstanceId: numbering.numberingInstanceId,
55803
+ ...instance?.abstractNumberingId ? { abstractNumberingId: instance.abstractNumberingId } : {},
55804
+ level: numbering.level,
55805
+ ...listKind ? { listKind } : {},
55806
+ editability: target.editability,
55807
+ blockers: target.posture.blockers,
55808
+ supportedCommands: SUPPORTED_COMMANDS,
55809
+ unsupportedCommands: UNSUPPORTED_COMMANDS,
55810
+ staleDiscriminators: {
55811
+ paragraphTextHash: target.staleCheck.paragraphTextHash,
55812
+ paragraphTextLength: target.staleCheck.paragraphTextLength,
55813
+ inlineCount: target.staleCheck.inlineCount,
55814
+ listAddressStaleHash: target.listAddress?.resolver?.staleHash
55815
+ }
55816
+ };
55817
+ }
55818
+ function canContinuePreviousSequence(document2, paragraphIndex) {
55819
+ const paragraphs = collectParagraphEntries(document2.content.children, "main");
55820
+ const current = paragraphs[paragraphIndex]?.paragraph;
55821
+ if (!current?.numbering) return false;
55822
+ const currentKind = getListKind(document2.numbering, current.numbering.numberingInstanceId);
55823
+ if (!currentKind) return false;
55824
+ for (let index = paragraphIndex - 1; index >= 0; index -= 1) {
55825
+ const previous = paragraphs[index]?.paragraph;
55826
+ if (!previous?.numbering) continue;
55827
+ const previousKind = getListKind(document2.numbering, previous.numbering.numberingInstanceId);
55828
+ return previousKind === currentKind && previous.numbering.numberingInstanceId !== current.numbering.numberingInstanceId;
55829
+ }
55830
+ return false;
55831
+ }
55832
+ function canJoinPreviousSequence(document2, paragraphIndex) {
55833
+ const paragraphs = collectParagraphEntries(document2.content.children, "main");
55834
+ const current = paragraphs[paragraphIndex]?.paragraph;
55835
+ const previous = paragraphs[paragraphIndex - 1]?.paragraph;
55836
+ if (!current?.numbering || !previous?.numbering) return false;
55837
+ const currentKind = getListKind(document2.numbering, current.numbering.numberingInstanceId);
55838
+ const previousKind = getListKind(document2.numbering, previous.numbering.numberingInstanceId);
55839
+ return Boolean(currentKind) && currentKind === previousKind && current.numbering.numberingInstanceId !== previous.numbering.numberingInstanceId;
55840
+ }
55841
+ function unsupportedCommandBlocker(command, target) {
55842
+ return {
55843
+ code: "list-command-unsupported",
55844
+ ownerLayer: "L07",
55845
+ message: `runtime.lists.${command} is reserved but not implemented by the L07 command surface yet.`,
55846
+ ...target.targetKey !== void 0 ? { targetKey: target.targetKey } : {},
55847
+ ...target.addressKey !== void 0 ? { addressKey: target.addressKey } : {}
55848
+ };
55849
+ }
55850
+
55050
55851
  // src/api/v3/ai/_pe2-evidence.ts
55051
55852
  function copyCoverage(coverage) {
55052
55853
  return {
@@ -57400,6 +58201,17 @@ function createTableActionFamily(runtime) {
57400
58201
  operationScope: target.table?.operationScope
57401
58202
  });
57402
58203
  }
58204
+ if (fragmentContent && fragmentContent.blocks.length === 0) {
58205
+ return blockedResult(input, proposalId, {
58206
+ code: `table-action-structured-fragment-empty:${input.operation.kind}`,
58207
+ category: "unsupported-operation",
58208
+ message: "Structured table text actions require a canonical document fragment with at least one block.",
58209
+ nextStep: 'Retry with operation.content.kind="structured" and a CanonicalDocumentFragment whose blocks array contains the paragraph or table content to paste/drop.',
58210
+ actionHandle: input.actionHandle,
58211
+ operation: input.operation.kind,
58212
+ operationScope: target.table?.operationScope
58213
+ });
58214
+ }
57403
58215
  const resolution2 = resolveEditableTextTarget({
57404
58216
  document: runtime.getCanonicalDocument(),
57405
58217
  surface: runtime.getRenderSnapshot().surface?.blocks ?? [],
@@ -57422,6 +58234,7 @@ function createTableActionFamily(runtime) {
57422
58234
  runtime.dispatch({
57423
58235
  type: "fragment.insert",
57424
58236
  fragment: fragmentContent,
58237
+ selection: createSelectionSnapshot(resolution2.range.to, resolution2.range.to),
57425
58238
  editableTarget: target,
57426
58239
  origin: { source: "api", timestamp: nowUtc }
57427
58240
  });
@@ -57434,6 +58247,17 @@ function createTableActionFamily(runtime) {
57434
58247
  });
57435
58248
  }
57436
58249
  const changed2 = runtime.getCanonicalDocument() !== before2;
58250
+ if (!changed2) {
58251
+ return blockedResult(input, proposalId, {
58252
+ code: `table-action-noop:${input.operation.kind}:${input.actionHandle}`,
58253
+ category: "runtime-noop",
58254
+ message: "The runtime accepted the table text target but the operation produced no document change.",
58255
+ nextStep: "Refresh the table action list and verify the target is still editable, the payload is non-empty when required, and structured fragments are dispatched through a command-safe table text action.",
58256
+ actionHandle: input.actionHandle,
58257
+ operation: input.operation.kind,
58258
+ operationScope: target.table?.operationScope
58259
+ });
58260
+ }
57437
58261
  const afterReadback = tableTextReadback(readEditableTargetText(runtime.getCanonicalDocument(), target));
57438
58262
  return {
57439
58263
  proposalId,
@@ -58012,6 +58836,31 @@ var hyperlinkTextEditMetadata = actionMethodMetadata(
58012
58836
  expectedDelta: "hyperlink display text changes"
58013
58837
  }
58014
58838
  );
58839
+ var validateTemplateTargetsMetadata = actionMethodMetadata(
58840
+ "validateTemplateTargets",
58841
+ "read",
58842
+ "actions-template-targets",
58843
+ "Validate template field/clause targets against current document readback, duplicate ranges, and exact action/scope handles before fill.",
58844
+ { uiVisible: false, expectsUxResponse: "none" }
58845
+ );
58846
+ var templateTargetReadMetadata = actionMethodMetadata(
58847
+ "templateTargetRead",
58848
+ "read",
58849
+ "actions-template-targets",
58850
+ "Read a template field/clause target through its exact scope/action handle when present, or diagnostic placeholder occurrence evidence otherwise.",
58851
+ { uiVisible: false, expectsUxResponse: "none" }
58852
+ );
58853
+ var templateFieldFillMetadata = actionMethodMetadata(
58854
+ "templateFieldFill",
58855
+ "mutate",
58856
+ "actions-template-targets",
58857
+ "Fill one template field only through an exact scope/action handle after same-target readback validation; raw ranges are diagnostics only.",
58858
+ {
58859
+ uiVisible: true,
58860
+ expectsUxResponse: "inline-change",
58861
+ expectedDelta: "the exact template field target text changes"
58862
+ }
58863
+ );
58015
58864
  var listOperationMetadata = actionMethodMetadata(
58016
58865
  "listOperation",
58017
58866
  "mutate",
@@ -58072,6 +58921,9 @@ var ACTION_METHODS = Object.freeze([
58072
58921
  "bookmarkEdit",
58073
58922
  "hyperlinkDestinationEdit",
58074
58923
  "hyperlinkTextEdit",
58924
+ "validateTemplateTargets",
58925
+ "templateTargetRead",
58926
+ "templateFieldFill",
58075
58927
  "listOperation",
58076
58928
  "tableFragment",
58077
58929
  "tableSelection",
@@ -58440,6 +59292,25 @@ function createActionsFamily(runtime) {
58440
59292
  origin: input.origin
58441
59293
  });
58442
59294
  },
59295
+ validateTemplateTargets(input) {
59296
+ return validateTemplateTargets(runtime, input);
59297
+ },
59298
+ templateTargetRead(input) {
59299
+ const item = validateTemplateTarget(runtime, input.target, {
59300
+ duplicateRanges: /* @__PURE__ */ new Set(),
59301
+ allowDuplicateRanges: true
59302
+ });
59303
+ return {
59304
+ status: item.status === "blocked" ? "blocked" : "read",
59305
+ ...item.target ? { target: item.target } : {},
59306
+ ...item.readback ? { readback: item.readback } : {},
59307
+ ...item.blockers ? { blockers: item.blockers } : {},
59308
+ ...item.blockerDetails ? { blockerDetails: item.blockerDetails } : {}
59309
+ };
59310
+ },
59311
+ templateFieldFill(input) {
59312
+ return applyTemplateFieldFill(runtime, input);
59313
+ },
58443
59314
  listOperation(input) {
58444
59315
  return applyListOperation(runtime, input);
58445
59316
  },
@@ -58509,6 +59380,9 @@ function runPlanStep(runtime, mode, step, plan) {
58509
59380
  if (step.kind === "tableAction" || step.kind === "tableFragment" || step.kind === "tableSelection") {
58510
59381
  return runPlanTableActionStep(runtime, mode, step, plan);
58511
59382
  }
59383
+ if (step.kind === "templateFieldFill") {
59384
+ return runPlanTemplateFieldFillStep(runtime, mode, step, plan);
59385
+ }
58512
59386
  const before = step.target ? readPlanTarget(runtime, step.target) : readDocumentPlanTarget(runtime);
58513
59387
  if (!before.ok) {
58514
59388
  return blockedPlanStepFromDetails(step.id, step.kind, before.blockerDetails);
@@ -58668,6 +59542,72 @@ function runPlanTableActionStep(runtime, mode, step, plan) {
58668
59542
  ...result.commandReference ? { commandReference: result.commandReference } : {}
58669
59543
  };
58670
59544
  }
59545
+ function runPlanTemplateFieldFillStep(runtime, mode, step, plan) {
59546
+ const validation = validateTemplateTarget(runtime, step.field, {
59547
+ duplicateRanges: /* @__PURE__ */ new Set(),
59548
+ allowDuplicateRanges: true
59549
+ });
59550
+ if (validation.status === "blocked" || !validation.canFill) {
59551
+ return blockedPlanStepFromDetails(
59552
+ step.id,
59553
+ step.kind,
59554
+ validation.blockerDetails ?? [
59555
+ blocker(
59556
+ `actions:template-field-fill:not-fillable:${templateTargetDebugId(step.field)}`,
59557
+ "blocked",
59558
+ "The template field target is not backed by an exact fill handle.",
59559
+ "Plant the field through editor APIs and pass the returned scope handle or actionHandle; raw ranges are diagnostics only."
59560
+ )
59561
+ ],
59562
+ {
59563
+ ...validation.target ? { target: validation.target } : {},
59564
+ ...validation.readback ? { beforeReadback: templateReadbackToPlanReadback(validation.readback) } : {}
59565
+ }
59566
+ );
59567
+ }
59568
+ const precondition = checkPlanPreconditions(step, templateReadbackToPlanReadback(validation.readback));
59569
+ if (precondition) {
59570
+ return blockedPlanStepFromDetails(step.id, step.kind, [precondition], {
59571
+ ...validation.target ? { target: validation.target } : {},
59572
+ ...validation.readback ? { beforeReadback: templateReadbackToPlanReadback(validation.readback) } : {}
59573
+ });
59574
+ }
59575
+ if (mode === "preview") {
59576
+ return {
59577
+ id: step.id,
59578
+ kind: step.kind,
59579
+ status: "planned",
59580
+ applied: false,
59581
+ changed: false,
59582
+ ...validation.target ? { target: validation.target } : {},
59583
+ ...validation.readback ? { beforeReadback: templateReadbackToPlanReadback(validation.readback) } : {}
59584
+ };
59585
+ }
59586
+ const applied = applyTemplateFieldFill(runtime, {
59587
+ field: step.field,
59588
+ text: step.text,
59589
+ actorId: step.actorId ?? plan.actorId,
59590
+ origin: step.origin ?? plan.origin,
59591
+ ...step.proposalId ? { proposalId: step.proposalId } : {}
59592
+ });
59593
+ const after = step.field.target ? readPlanTarget(runtime, step.field.target) : null;
59594
+ return {
59595
+ id: step.id,
59596
+ kind: step.kind,
59597
+ status: applied.status === "unsupported" ? "unsupported" : applied.applied ? "applied" : "blocked",
59598
+ applied: applied.applied,
59599
+ changed: applied.changed,
59600
+ ...applied.target ?? validation.target ? { target: applied.target ?? validation.target } : {},
59601
+ ...validation.readback ? { beforeReadback: templateReadbackToPlanReadback(validation.readback) } : {},
59602
+ ...after?.ok && after.readback ? { afterReadback: after.readback } : {},
59603
+ ...applied.proposalId ? { proposalId: applied.proposalId } : {},
59604
+ ...applied.posture ? { posture: applied.posture } : {},
59605
+ ...applied.blockers ? { blockers: applied.blockers } : {},
59606
+ ...applied.blockerDetails ? { blockerDetails: applied.blockerDetails } : {},
59607
+ ...applied.auditReference ? { auditReference: applied.auditReference } : {},
59608
+ ...applied.commandReference ? { commandReference: applied.commandReference } : {}
59609
+ };
59610
+ }
58671
59611
  function locateAll(runtime, input) {
58672
59612
  if (!input.query) {
58673
59613
  const detail = blocker(
@@ -58750,6 +59690,310 @@ function locateAll(runtime, input) {
58750
59690
  ...matches.length === 0 ? { blockers: Object.freeze([`actions:locate:not-found:${input.query}`]) } : {}
58751
59691
  };
58752
59692
  }
59693
+ function validateTemplateTargets(runtime, input) {
59694
+ if (!Array.isArray(input.targets) || input.targets.length === 0) {
59695
+ const detail = blocker(
59696
+ "actions:template-targets:empty",
59697
+ "input",
59698
+ "Template target validation requires at least one field or clause target.",
59699
+ "Pass the analyzer targets before saving the template."
59700
+ );
59701
+ return {
59702
+ status: "blocked",
59703
+ targets: Object.freeze([]),
59704
+ blockers: Object.freeze([detail.code]),
59705
+ blockerDetails: Object.freeze([detail])
59706
+ };
59707
+ }
59708
+ const duplicateRanges = /* @__PURE__ */ new Set();
59709
+ const items = input.targets.map(
59710
+ (target) => validateTemplateTarget(runtime, target, {
59711
+ duplicateRanges,
59712
+ allowDuplicateRanges: input.allowDuplicateRanges === true
59713
+ })
59714
+ );
59715
+ const blockers = items.flatMap((item) => item.blockers ?? []);
59716
+ const blockerDetails = items.flatMap((item) => item.blockerDetails ?? []);
59717
+ return {
59718
+ status: blockerDetails.length === 0 ? "valid" : items.some((item) => item.status !== "blocked") ? "partial" : "blocked",
59719
+ targets: Object.freeze(items),
59720
+ ...blockers.length > 0 ? { blockers: Object.freeze(blockers) } : {},
59721
+ ...blockerDetails.length > 0 ? { blockerDetails: Object.freeze(blockerDetails) } : {}
59722
+ };
59723
+ }
59724
+ function validateTemplateTarget(runtime, target, context) {
59725
+ const targetKind = templateTargetKind(target);
59726
+ const details = [];
59727
+ const warnings = [];
59728
+ const expected = templateExpectedText(target);
59729
+ const occurrenceCount = expected ? countOccurrences(documentText(runtime.getCanonicalDocument()), expected) : void 0;
59730
+ const rangeKey = templateLocationKey(target.location);
59731
+ if (target.fieldId && target.clauseId) {
59732
+ details.push(
59733
+ blocker(
59734
+ `actions:template-targets:mixed-field-clause:${templateTargetDebugId(target)}`,
59735
+ "input",
59736
+ "A template target cannot be both a field and a clause.",
59737
+ "Split clause boundaries from fillable fields and save them as separate template targets."
59738
+ )
59739
+ );
59740
+ }
59741
+ if (!expected && !target.target) {
59742
+ details.push(
59743
+ blocker(
59744
+ `actions:template-targets:expected-text-required:${templateTargetDebugId(target)}`,
59745
+ "input",
59746
+ "A template target without an exact handle requires placeholderText or expectedText for validation.",
59747
+ "Store the visible placeholder/current text with the target before saving the template."
59748
+ )
59749
+ );
59750
+ }
59751
+ if (rangeKey && !context.allowDuplicateRanges) {
59752
+ if (context.duplicateRanges.has(rangeKey)) {
59753
+ details.push(
59754
+ blocker(
59755
+ `actions:template-targets:duplicate-range:${rangeKey}`,
59756
+ "ambiguous-target",
59757
+ "More than one template target claims the same document range.",
59758
+ "Create one shared grouped field target, or give each field a distinct occurrence identity."
59759
+ )
59760
+ );
59761
+ } else {
59762
+ context.duplicateRanges.add(rangeKey);
59763
+ }
59764
+ }
59765
+ if (isTableTemplateLocation(target.location) && !hasTableCellIdentity(target.location)) {
59766
+ details.push(
59767
+ blocker(
59768
+ `actions:template-targets:table-cell-identity-required:${templateTargetDebugId(target)}`,
59769
+ "input",
59770
+ "A table template target must carry stable cell identity.",
59771
+ "Include cellSourceRef/cellRefId or row and column identity plus the exact actionHandle returned for the cell text."
59772
+ )
59773
+ );
59774
+ }
59775
+ if (expected && occurrenceCount !== void 0 && occurrenceCount > 1 && !hasOccurrenceIdentity(target) && !target.target) {
59776
+ details.push(
59777
+ blocker(
59778
+ `actions:template-targets:ambiguous-placeholder:${templateTargetDebugId(target)}`,
59779
+ "ambiguous-target",
59780
+ "The placeholder/current text appears more than once and the target has no occurrence identity or exact handle.",
59781
+ "Persist an occurrence refId/index or the exact scope/action handle returned by ai.actions.locateAll."
59782
+ )
59783
+ );
59784
+ }
59785
+ let summary;
59786
+ let readback = occurrenceCount !== void 0 && expected !== void 0 ? { text: expected, excerpt: excerpt(expected), isEmpty: expected.trim().length === 0, occurrenceCount } : void 0;
59787
+ if (target.target) {
59788
+ const read = readPlanTarget(runtime, target.target);
59789
+ if (!read.ok) {
59790
+ details.push(...read.blockerDetails);
59791
+ } else {
59792
+ summary = read.target;
59793
+ readback = {
59794
+ text: read.readback?.text,
59795
+ excerpt: read.readback?.excerpt,
59796
+ isEmpty: read.readback?.isEmpty,
59797
+ ...occurrenceCount !== void 0 ? { occurrenceCount } : {}
59798
+ };
59799
+ const text = read.readback?.text ?? "";
59800
+ if (expected && !text.includes(expected)) {
59801
+ details.push(
59802
+ blocker(
59803
+ `actions:template-targets:stale-readback:${templateTargetDebugId(target)}`,
59804
+ "blocked",
59805
+ "The exact handle readback no longer contains the analyzer's expected text.",
59806
+ "Re-run template analysis against the current document and save fresh targets before filling."
59807
+ )
59808
+ );
59809
+ }
59810
+ }
59811
+ }
59812
+ const canFill = targetKind === "template-field" && target.target !== void 0 && details.length === 0;
59813
+ if (targetKind === "template-field" && !target.target) {
59814
+ details.push(
59815
+ blocker(
59816
+ `actions:template-field-fill:exact-target-required:${templateTargetDebugId(target)}`,
59817
+ "blocked",
59818
+ "Template field fill requires an exact scope handle or opaque actionHandle.",
59819
+ "Plant fields through editor APIs and store the returned handle; raw offsets and YAML ranges are diagnostics only."
59820
+ )
59821
+ );
59822
+ }
59823
+ if (targetKind === "template-clause") {
59824
+ warnings.push("template-clause targets are boundary evidence; fillable placeholders must be separate template-field targets.");
59825
+ }
59826
+ const status = details.length > 0 ? "blocked" : warnings.length > 0 ? "warning" : "valid";
59827
+ return {
59828
+ status,
59829
+ targetKind,
59830
+ ...target.fieldId ? { fieldId: target.fieldId } : {},
59831
+ ...target.clauseId ? { clauseId: target.clauseId } : {},
59832
+ ...target.name ? { name: target.name } : {},
59833
+ ...target.groupId ? { groupId: target.groupId } : {},
59834
+ canFill,
59835
+ ...summary ? { target: summary } : {},
59836
+ ...readback ? { readback } : {},
59837
+ ...details.length > 0 ? { blockers: Object.freeze(details.map((detail) => detail.code)) } : {},
59838
+ ...details.length > 0 ? { blockerDetails: Object.freeze(details) } : {},
59839
+ ...warnings.length > 0 ? { warnings: Object.freeze(warnings) } : {}
59840
+ };
59841
+ }
59842
+ function applyTemplateFieldFill(runtime, input) {
59843
+ if (input.text === void 0) {
59844
+ return blockedApply(
59845
+ "actions:template-field-fill:text-required",
59846
+ "input",
59847
+ "Template field fill requires a text value.",
59848
+ "Retry with the field fill text."
59849
+ );
59850
+ }
59851
+ if (templateTargetKind(input.field) !== "template-field") {
59852
+ return blockedApply(
59853
+ `actions:template-field-fill:field-target-required:${templateTargetDebugId(input.field)}`,
59854
+ "input",
59855
+ "Template field fill accepts only template-field targets.",
59856
+ "Split clause boundaries from fields and call templateFieldFill only for fillable fields."
59857
+ );
59858
+ }
59859
+ const validation = validateTemplateTarget(runtime, input.field, {
59860
+ duplicateRanges: /* @__PURE__ */ new Set(),
59861
+ allowDuplicateRanges: true
59862
+ });
59863
+ if (validation.status === "blocked" || !validation.canFill || !input.field.target) {
59864
+ return blockedApply(
59865
+ validation.blockerDetails?.[0]?.code ?? `actions:template-field-fill:exact-target-required:${templateTargetDebugId(input.field)}`,
59866
+ validation.blockerDetails?.[0]?.category ?? "blocked",
59867
+ validation.blockerDetails?.[0]?.message ?? "Template field fill requires a validated exact scope handle or opaque actionHandle.",
59868
+ validation.blockerDetails?.[0]?.nextStep ?? "Plant the field through editor APIs and pass the returned handle; raw ranges are diagnostics only.",
59869
+ validation.blockerDetails
59870
+ );
59871
+ }
59872
+ const exactnessBlocker = templateFillExactnessBlocker(input.field, validation);
59873
+ if (exactnessBlocker) {
59874
+ return blockedApply(
59875
+ exactnessBlocker.code,
59876
+ exactnessBlocker.category,
59877
+ exactnessBlocker.message,
59878
+ exactnessBlocker.nextStep,
59879
+ [exactnessBlocker]
59880
+ );
59881
+ }
59882
+ const resolved = resolveTarget(runtime, input.field.target);
59883
+ if (!resolved.ok) return blockedApplyFromResolution(resolved);
59884
+ const result = applyRewrite(runtime, resolved.target, {
59885
+ target: input.field.target,
59886
+ text: input.text,
59887
+ actorId: input.actorId,
59888
+ origin: input.origin,
59889
+ ...input.proposalId ? { proposalId: input.proposalId } : {}
59890
+ });
59891
+ if (!result.applied) return result;
59892
+ const after = readPlanTarget(runtime, input.field.target);
59893
+ if (!after.ok || after.readback?.text !== input.text) {
59894
+ const detail = blockerWithOwner(
59895
+ `actions:template-field-fill:readback-mismatch:${templateTargetDebugId(input.field)}`,
59896
+ "blocked",
59897
+ "The field fill reported applied, but same-target readback did not match the requested text.",
59898
+ "Treat this as failed, inspect export/reopen evidence, and route the target lowering to L08/L07 before retrying.",
59899
+ "L08 semantic scopes and L07 runtime text commands"
59900
+ );
59901
+ return {
59902
+ ...result,
59903
+ status: "blocked",
59904
+ applied: false,
59905
+ changed: result.changed,
59906
+ posture: "suspect-readback",
59907
+ blockers: Object.freeze([...result.blockers ?? [], detail.code]),
59908
+ blockerDetails: Object.freeze([...result.blockerDetails ?? [], detail])
59909
+ };
59910
+ }
59911
+ return result;
59912
+ }
59913
+ function templateFillExactnessBlocker(target, validation) {
59914
+ const readback = validation.readback?.text ?? "";
59915
+ const expected = templateExpectedText(target);
59916
+ if (!expected) return null;
59917
+ if (readback === expected) return null;
59918
+ return blocker(
59919
+ `actions:template-field-fill:exact-target-not-isolated:${templateTargetDebugId(target)}`,
59920
+ "blocked",
59921
+ "The exact handle readback contains surrounding document text, not just the template field text.",
59922
+ "Plant an isolated template-field scope/action handle for the placeholder; do not fill by broad paragraph, clause, or raw range."
59923
+ );
59924
+ }
59925
+ function templateReadbackToPlanReadback(readback) {
59926
+ if (!readback) return void 0;
59927
+ return {
59928
+ ...readback.text !== void 0 ? { text: readback.text } : {},
59929
+ ...readback.excerpt !== void 0 ? { excerpt: readback.excerpt } : {},
59930
+ ...readback.isEmpty !== void 0 ? { isEmpty: readback.isEmpty } : {}
59931
+ };
59932
+ }
59933
+ function templateTargetKind(target) {
59934
+ return target.kind ?? (target.clauseId && !target.fieldId ? "template-clause" : "template-field");
59935
+ }
59936
+ function templateExpectedText(target) {
59937
+ const text = target.expectedText ?? target.placeholderText;
59938
+ return text && text.length > 0 ? text : void 0;
59939
+ }
59940
+ function templateTargetDebugId(target) {
59941
+ return target.fieldId ?? target.clauseId ?? target.name ?? target.placeholderText ?? "unknown";
59942
+ }
59943
+ function templateLocationKey(location) {
59944
+ if (!location?.refId && location?.start === void 0 && location?.end === void 0) return null;
59945
+ return [
59946
+ location.story ?? "main",
59947
+ location.refId ?? "no-ref",
59948
+ location.start ?? "no-start",
59949
+ location.end ?? "no-end"
59950
+ ].join(":");
59951
+ }
59952
+ function isTableTemplateLocation(location) {
59953
+ return Boolean(
59954
+ location?.blockKind === "table-cell" || location?.tableRefId || location?.rowRefId || location?.cellRefId
59955
+ );
59956
+ }
59957
+ function hasTableCellIdentity(location) {
59958
+ return Boolean(
59959
+ location?.cellRefId || location?.rowRefId && location.columnIndex !== void 0 || location?.rowIndex !== void 0 && location?.columnIndex !== void 0
59960
+ );
59961
+ }
59962
+ function hasOccurrenceIdentity(target) {
59963
+ return Boolean(
59964
+ target.occurrence?.refId || target.occurrence?.occurrenceIndexInRef !== void 0 || target.occurrence?.occurrenceIndexGlobal !== void 0 || target.location?.refId || target.location?.cellRefId
59965
+ );
59966
+ }
59967
+ function countOccurrences(text, query) {
59968
+ if (!query) return 0;
59969
+ let count = 0;
59970
+ let index = 0;
59971
+ while (index <= text.length) {
59972
+ const found = text.indexOf(query, index);
59973
+ if (found === -1) break;
59974
+ count += 1;
59975
+ index = found + Math.max(1, query.length);
59976
+ }
59977
+ return count;
59978
+ }
59979
+ function documentText(document2) {
59980
+ return document2.content.children.map((block) => blockText(block)).join("\n");
59981
+ }
59982
+ function blockText(block) {
59983
+ switch (block.type) {
59984
+ case "paragraph":
59985
+ return collectInlineText2(block.children);
59986
+ case "table":
59987
+ return block.rows.map(
59988
+ (row) => row.cells.map((cell) => cell.children.map((child) => blockText(child)).join("\n")).join(" ")
59989
+ ).join("\n");
59990
+ case "sdt":
59991
+ case "custom_xml":
59992
+ return block.children.map((child) => blockText(child)).join("\n");
59993
+ default:
59994
+ return "";
59995
+ }
59996
+ }
58753
59997
  function resolveTarget(runtime, target) {
58754
59998
  if ("actionHandle" in target) {
58755
59999
  const action = findTableAction(runtime, target.actionHandle);
@@ -59460,6 +60704,14 @@ function applyPlanStep(runtime, step, plan) {
59460
60704
  actorId: step.actorId ?? plan.actorId,
59461
60705
  origin: step.origin ?? plan.origin
59462
60706
  });
60707
+ case "templateFieldFill":
60708
+ return createActionsFamily(runtime).actions.templateFieldFill({
60709
+ field: step.field,
60710
+ text: step.text,
60711
+ actorId: step.actorId ?? plan.actorId,
60712
+ origin: step.origin ?? plan.origin,
60713
+ ...step.proposalId ? { proposalId: step.proposalId } : {}
60714
+ });
59463
60715
  case "listOperation":
59464
60716
  return createActionsFamily(runtime).actions.listOperation({
59465
60717
  target: step.target,
@@ -62187,7 +63439,8 @@ function createApiV3(handle, opts) {
62187
63439
  chart: createChartFamily(handle),
62188
63440
  search: createSearchFamily(handle),
62189
63441
  table: createTableFamily(handle),
62190
- viewport: createViewportFamily(handle)
63442
+ viewport: createViewportFamily(handle),
63443
+ lists: createListsFamily(handle)
62191
63444
  };
62192
63445
  const ui = opts?.ui ? createUiApi(handle, opts.ui) : void 0;
62193
63446
  const api = ui ? { runtime, ai, ui } : { runtime, ai };