@stll/folio-core 0.35.0 → 0.36.0

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 (80) hide show
  1. package/dist/ai-edits/apply.js +370 -118
  2. package/dist/ai-edits/headless.js +16 -10
  3. package/dist/ai-edits/index.d.ts +2 -2
  4. package/dist/ai-edits/index.js +2 -2
  5. package/dist/ai-edits/snapshot.js +6 -1
  6. package/dist/ai-edits/types.d.ts +19 -6
  7. package/dist/ai-edits/word-diff.d.ts +18 -3
  8. package/dist/ai-edits/word-diff.js +556 -67
  9. package/dist/compare/compare.js +7 -16
  10. package/dist/compare/plan.js +8 -5
  11. package/dist/compare/verification.d.ts +8 -9
  12. package/dist/compare/verification.js +51 -46
  13. package/dist/compat/eigenpal.d.ts +2 -2
  14. package/dist/compat/eigenpal.js +2 -2
  15. package/dist/controller/headerFooterEditorManager.js +5 -5
  16. package/dist/controller/hiddenEditorApi.js +1 -1
  17. package/dist/controller/noteEditorManager.js +2 -2
  18. package/dist/document-operations.d.ts +5 -3
  19. package/dist/document-operations.js +32 -5
  20. package/dist/docx/commentParser.js +2 -4
  21. package/dist/docx/commentRangeIntegrity.js +2 -4
  22. package/dist/docx/documentClone.d.ts +2 -0
  23. package/dist/docx/documentClone.js +2 -0
  24. package/dist/docx/headerFooterParser.js +2 -4
  25. package/dist/docx/normalizeBaseDirection.js +5 -7
  26. package/dist/docx/paragraphParser.js +27 -29
  27. package/dist/docx/paragraphPropertySource.d.ts +49 -0
  28. package/dist/docx/paragraphPropertySource.js +113 -0
  29. package/dist/docx/runConsolidator.js +3 -4
  30. package/dist/docx/runParser.js +2 -15
  31. package/dist/docx/sectionParser.js +1 -15
  32. package/dist/docx/serializer/paragraphSerializer.js +287 -30
  33. package/dist/docx/serializer/runSerializer.js +2 -10
  34. package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
  35. package/dist/docx/serializer/tableSerializer.js +4 -23
  36. package/dist/docx/serializer/trackedChangeAttributes.d.ts +9 -0
  37. package/dist/docx/serializer/trackedChangeAttributes.js +21 -0
  38. package/dist/docx/server/createBilingualDocument.js +8 -10
  39. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
  40. package/dist/docx/server/validateDocxConformance.js +17 -13
  41. package/dist/docx/tableParser.js +1 -37
  42. package/dist/docx/trackedChangeInfo.d.ts +11 -0
  43. package/dist/docx/trackedChangeInfo.js +38 -0
  44. package/dist/docx/verbatimCapture.d.ts +20 -9
  45. package/dist/docx/verbatimCapture.js +208 -8
  46. package/dist/docx/xmlParser.d.ts +3 -1
  47. package/dist/docx/xmlParser.js +6 -1
  48. package/dist/docx/xmlSafety.d.ts +1 -1
  49. package/dist/docx/xmlSafety.js +157 -0
  50. package/dist/index.d.ts +2 -2
  51. package/dist/index.js +2 -2
  52. package/dist/layout-bridge/convert/headerFooterLayout.js +4 -4
  53. package/dist/layout-bridge/convert/toFlowBlocks.js +12 -7
  54. package/dist/markdown/renderBlock.js +7 -10
  55. package/dist/prosemirror/attrs/index.js +15 -0
  56. package/dist/prosemirror/commands/comments.js +365 -32
  57. package/dist/prosemirror/commands/pageBreak.js +1 -1
  58. package/dist/prosemirror/commands/propertyChangeScope.d.ts +26 -4
  59. package/dist/prosemirror/commands/propertyChangeScope.js +65 -3
  60. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -4
  61. package/dist/prosemirror/conversion/fromProseDoc.js +130 -18
  62. package/dist/prosemirror/conversion/toProseDoc.js +27 -12
  63. package/dist/prosemirror/extensions/core/ParagraphExtension.js +48 -4
  64. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
  65. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +20 -7
  66. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  67. package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
  68. package/dist/prosemirror/paragraphAlignment.js +13 -0
  69. package/dist/prosemirror/plugins/suggestionMode.js +1 -1
  70. package/dist/prosemirror/schema/marks.d.ts +2 -0
  71. package/dist/prosemirror/schema/nodes.d.ts +12 -1
  72. package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
  73. package/dist/redline.js +4 -1
  74. package/dist/server.d.ts +2 -2
  75. package/dist/server.js +2 -2
  76. package/dist/utils/mergeDocumentContent.js +3 -3
  77. package/dist/utils/replaceText.js +2 -1
  78. package/dist/version-comparison.js +6 -4
  79. package/dist/watermark/index.js +2 -4
  80. package/package.json +7 -2
@@ -1,6 +1,7 @@
1
1
  import { FolioDocxReviewer } from "../ai-edits/headless.js";
2
2
  import { numberingReferenceKeysOf } from "../ai-edits/snapshot.js";
3
3
  import { projectTableGeometry } from "../ai-edits/table-geometry.js";
4
+ import { createScopedWordDiffOptions } from "../ai-edits/word-diff.js";
4
5
  import "../document-operations.js";
5
6
  import { pairFolioDocumentStories } from "../document-stories.js";
6
7
  import { planStoryCompare } from "./plan.js";
@@ -76,16 +77,6 @@ const existingRevisionsOf = (reviewer) => {
76
77
  present
77
78
  };
78
79
  };
79
- /**
80
- * One story's text-and-structure projection: every block's text tagged with
81
- * the table cell it sits in. The tag is what makes the self-check below see a
82
- * paragraph that landed beside a table instead of inside it.
83
- */
84
- const projectBlocks = (blocks) => {
85
- return blocks.map(({ text, table, styleId, listLevel }) => {
86
- return `${table ? `t${String(table.tableIndex)}r${String(table.rowIndex)}c${String(table.cellIndex)}g${String(table.gridColumnIndex)}x${String(table.columnSpan)}y${String(table.rowSpan)}p${String(table.paragraphIndex)}` : "body"}|${styleId ?? ""}|${listLevel ?? ""}|${text}`;
87
- });
88
- };
89
80
  /** Verify formatting only where the plan claims a text-equal formatting change. */
90
81
  const formattingRoundTripFailure = ({ invariant, story, changes, actualBlocks, expectedBlocks, expectedBlockId }) => {
91
82
  const expectedIndexById = new Map(expectedBlocks.map(({ id }, index) => [id, index]));
@@ -321,14 +312,14 @@ const applyComparison = ({ reviewer, targetReviewer, revisionStamp, granularity,
321
312
  const failures = [];
322
313
  let idSeed = revisionStamp.idSeed;
323
314
  let documentChanged = false;
315
+ const wordDiff = createScopedWordDiffOptions({ granularity });
324
316
  for (const { pair, plan } of planned) {
325
317
  changes.push(...plan.changes);
326
318
  if (plan.operations.length === 0 && plan.tableGeometryPairings.length === 0) continue;
327
- const baseBeforeBlocks = reviewer.readReviewedStory({
319
+ const baseBefore = reviewer.readReviewedStory({
328
320
  story: pair.baseStory,
329
321
  view: "final"
330
322
  })?.snapshot.blocks ?? [];
331
- const baseBefore = projectBlocks(baseBeforeBlocks);
332
323
  const baseBeforeGeometry = projectTableGeometry(reviewer.storyTables({ story: pair.baseStory }));
333
324
  const targetTables = new Map(targetReviewer.storyTables({ story: pair.targetStory }).map(({ index, node }) => [index, node]));
334
325
  const afterGeometry = reviewer.matchStoryTableGeometry({
@@ -352,7 +343,7 @@ const applyComparison = ({ reviewer, targetReviewer, revisionStamp, granularity,
352
343
  date: revisionStamp.date,
353
344
  idSeed
354
345
  },
355
- wordDiff: { granularity },
346
+ wordDiff,
356
347
  batch: {
357
348
  version: 1,
358
349
  mode: "tracked-changes",
@@ -376,8 +367,8 @@ const applyComparison = ({ reviewer, targetReviewer, revisionStamp, granularity,
376
367
  const acceptFailure = classifyProjectionMismatch({
377
368
  invariant: "accept-reproduces-target",
378
369
  story: pair.baseStory,
379
- actual: projectBlocks(acceptedStory?.snapshot.blocks ?? []),
380
- expected: projectBlocks(pair.targetSnapshot.blocks)
370
+ actual: acceptedStory?.snapshot.blocks ?? [],
371
+ expected: pair.targetSnapshot.blocks
381
372
  });
382
373
  if (acceptFailure) failures.push(acceptFailure);
383
374
  else {
@@ -398,7 +389,7 @@ const applyComparison = ({ reviewer, targetReviewer, revisionStamp, granularity,
398
389
  const rejectFailure = classifyProjectionMismatch({
399
390
  invariant: "reject-reproduces-base",
400
391
  story: pair.baseStory,
401
- actual: projectBlocks(rejectedStory?.snapshot.blocks ?? []),
392
+ actual: rejectedStory?.snapshot.blocks ?? [],
402
393
  expected: baseBefore
403
394
  });
404
395
  if (rejectFailure) failures.push(rejectFailure);
@@ -737,14 +737,15 @@ const columnCellTexts = (blocks) => {
737
737
  };
738
738
  /**
739
739
  * The paragraph properties that differ, or `null` when they agree. Only the
740
- * ones a block projection can see and an operation can set: a list level and
741
- * a paragraph style, the two edits that move no words and are invisible in a
742
- * text diff.
740
+ * ones a block projection can see and an operation can set: a list level, a
741
+ * paragraph style, and direct alignment. These edits move no words and are
742
+ * invisible in a text diff.
743
743
  */
744
744
  const changedParagraphProperties = (baseBlock, targetBlock) => {
745
745
  const properties = {};
746
746
  if ((baseBlock.styleId ?? null) !== (targetBlock.styleId ?? null)) properties.styleId = targetBlock.styleId ?? null;
747
747
  if (baseBlock.listLevel !== targetBlock.listLevel) properties.listLevel = targetBlock.listLevel ?? null;
748
+ if (baseBlock.directAlignment !== targetBlock.directAlignment) properties.alignment = targetBlock.directAlignment ?? null;
748
749
  return Object.keys(properties).length > 0 ? properties : null;
749
750
  };
750
751
  const locationOf = (story, block) => block.table ? {
@@ -895,7 +896,8 @@ const withTrailingDeletionRules = ({ baseSnapshot, targetSnapshot, operations, n
895
896
  text: insert.text,
896
897
  ...insert.moveId !== void 0 && { moveId: insert.moveId },
897
898
  styleId: insert.styleId ?? null,
898
- listLevel: insert.listLevel ?? null
899
+ listLevel: insert.listLevel ?? null,
900
+ alignment: insert.alignment ?? null
899
901
  };
900
902
  }
901
903
  }
@@ -985,7 +987,8 @@ const planStoryCompare = ({ story, baseSnapshot, targetSnapshot, maxOperations }
985
987
  text: block.text,
986
988
  ...moveSourceId !== void 0 && { moveId: moveIdOf(moveSourceId) },
987
989
  styleId: block.styleId ?? null,
988
- listLevel: block.listLevel ?? null
990
+ listLevel: block.listLevel ?? null,
991
+ alignment: block.directAlignment ?? null
989
992
  };
990
993
  if (anchorId !== null) {
991
994
  operations.push({
@@ -10,7 +10,7 @@ type CompareVerificationInvariant = (typeof COMPARE_VERIFICATION_INVARIANTS)[num
10
10
  * that fits is the one reported, because a block in the wrong container is a
11
11
  * different finding from a block whose words are wrong even when both are true.
12
12
  */
13
- declare const COMPARE_VERIFICATION_CAUSES: readonly ["invisible-structure", "block-count", "container", "table-geometry", "style", "list-level", "inline-formatting", "whitespace", "text"];
13
+ declare const COMPARE_VERIFICATION_CAUSES: readonly ["invisible-structure", "block-count", "container", "table-geometry", "style", "list-level", "alignment", "inline-formatting", "whitespace", "text"];
14
14
  type CompareVerificationCause = (typeof COMPARE_VERIFICATION_CAUSES)[number];
15
15
  /** One invariant that did not hold, in one story. */
16
16
  type CompareVerificationFailure = {
@@ -35,15 +35,14 @@ type CompareVerification = {
35
35
  };
36
36
  /** Effective supported formatting with equivalent adjacent runs normalized. */
37
37
  declare const projectSupportedInlineFormatting: ({ text, previewRuns }: FolioAIBlock) => string;
38
- /** Element by element, never by joining: a block's text may hold the separator. */
39
- declare const sameProjection: (left: readonly string[], right: readonly string[]) => boolean;
40
- type ClassifyOptions = {
38
+ type ProjectedBlock = Pick<FolioAIBlock, "text" | "table" | "styleId" | "listLevel" | "directAlignment">;
39
+ type ClassifyOptions<T> = {
41
40
  invariant: CompareVerificationInvariant;
42
41
  story: FolioDocumentStoryHandle;
43
42
  /** What the redline actually leaves. */
44
- actual: readonly string[];
43
+ actual: readonly T[];
45
44
  /** What the invariant says it should leave. */
46
- expected: readonly string[];
45
+ expected: readonly T[];
47
46
  };
48
47
  /**
49
48
  * The failure two table-geometry projections describe, or `null` when they
@@ -51,14 +50,14 @@ type ClassifyOptions = {
51
50
  * whether the count itself did — never a property value, which could carry a
52
51
  * style name either document chose.
53
52
  */
54
- declare const classifyGeometryMismatch: ({ invariant, story, actual, expected }: ClassifyOptions) => CompareVerificationFailure | null;
53
+ declare const classifyGeometryMismatch: ({ invariant, story, actual, expected }: ClassifyOptions<string>) => CompareVerificationFailure | null;
55
54
  /**
56
55
  * The failure two projections describe, or `null` when they agree.
57
56
  *
58
57
  * Total over the causes by construction: the last branch is unconditional, so
59
58
  * a divergence always produces a failure rather than being dropped.
60
59
  */
61
- declare const classifyProjectionMismatch: ({ invariant, story, actual, expected }: ClassifyOptions) => CompareVerificationFailure | null;
60
+ declare const classifyProjectionMismatch: ({ invariant, story, actual, expected }: ClassifyOptions<ProjectedBlock>) => CompareVerificationFailure | null;
62
61
  /**
63
62
  * A container whose last paragraph carries a revision on its mark.
64
63
  *
@@ -99,4 +98,4 @@ declare const revisedFinalParagraphMarks: (packageModel: unknown, { since }?: {
99
98
  since?: number;
100
99
  }) => FinalParagraphMarkRevision[];
101
100
  //#endregion
102
- export { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision, classifyGeometryMismatch, classifyProjectionMismatch, projectSupportedInlineFormatting, revisedFinalParagraphMarks, sameProjection };
101
+ export { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareVerification, CompareVerificationCause, CompareVerificationFailure, CompareVerificationInvariant, FinalParagraphMarkRevision, classifyGeometryMismatch, classifyProjectionMismatch, projectSupportedInlineFormatting, revisedFinalParagraphMarks };
@@ -6,10 +6,10 @@ import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
6
6
  *
7
7
  * The check compares two block projections: what accepting the generated
8
8
  * revisions leaves against the target, and what rejecting them leaves against
9
- * the base. A projection carries each block's container, style, list level and
10
- * text, so WHICH field diverged names which part of the pipeline lost the
11
- * difference — and that is worth reporting as a typed cause rather than as one
12
- * opaque "did not reproduce".
9
+ * the base. A projection carries each block's container, style, list level,
10
+ * direct alignment and text, so WHICH field diverged names which part of the
11
+ * pipeline lost the difference — and that is worth reporting as a typed cause
12
+ * rather than as one opaque "did not reproduce".
13
13
  *
14
14
  * Every `detail` string here is structural: counts, offsets, container kinds.
15
15
  * Never a phrase of either document, because a caller may log it, put it in a
@@ -30,6 +30,7 @@ const COMPARE_VERIFICATION_CAUSES = Object.freeze([
30
30
  "table-geometry",
31
31
  "style",
32
32
  "list-level",
33
+ "alignment",
33
34
  "inline-formatting",
34
35
  "whitespace",
35
36
  "text"
@@ -68,28 +69,18 @@ const projectSupportedInlineFormatting = ({ text, previewRuns }) => {
68
69
  }
69
70
  return projected.map(({ length, style }) => `${String(length)}:${style}`).join(",");
70
71
  };
71
- const parseProjection = (entry) => {
72
- const first = entry.indexOf("|");
73
- const second = entry.indexOf("|", first + 1);
74
- const third = entry.indexOf("|", second + 1);
75
- if (first === -1 || second === -1 || third === -1) return {
76
- container: "",
77
- styleId: "",
78
- listLevel: "",
79
- text: entry
80
- };
81
- return {
82
- container: entry.slice(0, first),
83
- styleId: entry.slice(first + 1, second),
84
- listLevel: entry.slice(second + 1, third),
85
- text: entry.slice(third + 1)
86
- };
72
+ const sameContainer = (left, right) => {
73
+ if (!left || !right) return left === right;
74
+ return left.outerTableIndex === right.outerTableIndex && left.tableIndex === right.tableIndex && left.rowIndex === right.rowIndex && left.cellIndex === right.cellIndex && left.gridColumnIndex === right.gridColumnIndex && left.columnSpan === right.columnSpan && left.rowSpan === right.rowSpan && left.paragraphIndex === right.paragraphIndex;
87
75
  };
88
- const CONTAINER_PATTERN = /^t(\d+)r(\d+)c(\d+)p(\d+)$/u;
89
- const containerKind = (container) => CONTAINER_PATTERN.test(container) ? "cell" : "body";
76
+ const sameProjectedBlock = (left, right) => sameContainer(left.table, right.table) && left.styleId === right.styleId && left.listLevel === right.listLevel && left.directAlignment === right.directAlignment && left.text === right.text;
77
+ const containerKind = (container) => container ? "cell" : "body";
90
78
  const collapseWhitespace = (text) => text.replace(/\s+/gu, " ").trim();
91
- /** Element by element, never by joining: a block's text may hold the separator. */
92
- const sameProjection = (left, right) => left.length === right.length && left.every((entry, index) => entry === right[index]);
79
+ const sameBlockProjection = (left, right) => left.length === right.length && left.every((entry, index) => {
80
+ const other = right[index];
81
+ return other !== void 0 && sameProjectedBlock(entry, other);
82
+ });
83
+ const sameStringProjection = (left, right) => left.length === right.length && left.every((entry, index) => entry === right[index]);
93
84
  /**
94
85
  * The same projection with every table coordinate renumbered by first
95
86
  * appearance, so it counts the blocks the model holds rather than the
@@ -116,19 +107,28 @@ const byVisibleOrdinal = (entries) => {
116
107
  };
117
108
  const paragraphCounts = /* @__PURE__ */ new Map();
118
109
  return entries.map((entry) => {
119
- const first = entry.indexOf("|");
120
- const match = CONTAINER_PATTERN.exec(entry.slice(0, first));
121
- if (!match) return entry;
122
- const [, table = "", row = "", cell = ""] = match;
123
- const tableOrdinal = ordinalWithin("t", table);
110
+ const container = entry.table;
111
+ if (!container) return entry;
112
+ const outerTableOrdinal = ordinalWithin("t", String(container.outerTableIndex));
113
+ const tableOrdinal = ordinalWithin("t", String(container.tableIndex));
124
114
  const rowScope = `r${String(tableOrdinal)}`;
125
- const rowOrdinal = ordinalWithin(rowScope, row);
115
+ const rowOrdinal = ordinalWithin(rowScope, String(container.rowIndex));
126
116
  const cellScope = `c${String(tableOrdinal)}.${String(rowOrdinal)}`;
127
- const cellOrdinal = ordinalWithin(cellScope, cell);
128
- const cellKey = `${cellScope}:${cell}`;
117
+ const cellOrdinal = ordinalWithin(cellScope, String(container.cellIndex));
118
+ const cellKey = `${cellScope}:${String(container.cellIndex)}`;
129
119
  const paragraphOrdinal = paragraphCounts.get(cellKey) ?? 0;
130
120
  paragraphCounts.set(cellKey, paragraphOrdinal + 1);
131
- return `t${String(tableOrdinal)}r${String(rowOrdinal)}c${String(cellOrdinal)}p${String(paragraphOrdinal)}` + entry.slice(first);
121
+ return {
122
+ ...entry,
123
+ table: {
124
+ ...container,
125
+ outerTableIndex: outerTableOrdinal,
126
+ tableIndex: tableOrdinal,
127
+ rowIndex: rowOrdinal,
128
+ cellIndex: cellOrdinal,
129
+ paragraphIndex: paragraphOrdinal
130
+ }
131
+ };
132
132
  });
133
133
  };
134
134
  /**
@@ -137,15 +137,19 @@ const byVisibleOrdinal = (entries) => {
137
137
  */
138
138
  const firstDivergence = (actual, expected) => {
139
139
  const shared = Math.min(actual.length, expected.length);
140
- for (let index = 0; index < shared; index++) if (actual[index] !== expected[index]) return {
141
- index,
142
- actual: parseProjection(actual[index] ?? ""),
143
- expected: parseProjection(expected[index] ?? "")
144
- };
140
+ for (let index = 0; index < shared; index++) {
141
+ const left = actual[index];
142
+ const right = expected[index];
143
+ if (left !== void 0 && right !== void 0 && !sameProjectedBlock(left, right)) return {
144
+ index,
145
+ actual: left,
146
+ expected: right
147
+ };
148
+ }
145
149
  return {
146
150
  index: shared,
147
- actual: shared < actual.length ? parseProjection(actual[shared] ?? "") : null,
148
- expected: shared < expected.length ? parseProjection(expected[shared] ?? "") : null
151
+ actual: actual.at(shared) ?? null,
152
+ expected: expected.at(shared) ?? null
149
153
  };
150
154
  };
151
155
  /**
@@ -155,7 +159,7 @@ const firstDivergence = (actual, expected) => {
155
159
  * style name either document chose.
156
160
  */
157
161
  const classifyGeometryMismatch = ({ invariant, story, actual, expected }) => {
158
- if (sameProjection(actual, expected)) return null;
162
+ if (sameStringProjection(actual, expected)) return null;
159
163
  return {
160
164
  invariant,
161
165
  cause: "table-geometry",
@@ -170,25 +174,26 @@ const classifyGeometryMismatch = ({ invariant, story, actual, expected }) => {
170
174
  * a divergence always produces a failure rather than being dropped.
171
175
  */
172
176
  const classifyProjectionMismatch = ({ invariant, story, actual, expected }) => {
173
- if (sameProjection(actual, expected)) return null;
177
+ if (sameBlockProjection(actual, expected)) return null;
174
178
  const failure = (cause, detail) => ({
175
179
  invariant,
176
180
  cause,
177
181
  story,
178
182
  detail
179
183
  });
180
- if (sameProjection(byVisibleOrdinal(actual), byVisibleOrdinal(expected))) return failure("invisible-structure", `every block matches once table coordinates count visible blocks (${String(expected.length)} blocks)`);
184
+ if (sameBlockProjection(byVisibleOrdinal(actual), byVisibleOrdinal(expected))) return failure("invisible-structure", `every block matches once table coordinates count visible blocks (${String(expected.length)} blocks)`);
181
185
  const divergence = firstDivergence(actual, expected);
182
186
  const at = `at block ${String(divergence.index)}/${String(expected.length)}`;
183
187
  const counts = `${String(actual.length)} blocks against ${String(expected.length)}`;
184
188
  if (divergence.actual === null || divergence.expected === null) return failure("block-count", `${actual.length > expected.length ? "more" : "fewer"} blocks than expected (${counts}), diverging ${at}`);
185
189
  const { actual: left, expected: right } = divergence;
186
- if (left.container !== right.container) return failure("container", `a block sits in a ${containerKind(left.container)} where it is expected in a ${containerKind(right.container)}, ${at} (${counts})`);
190
+ if (!sameContainer(left.table, right.table)) return failure("container", `a block sits in a ${containerKind(left.table)} where it is expected in a ${containerKind(right.table)}, ${at} (${counts})`);
187
191
  if (left.text === right.text && left.styleId !== right.styleId) return failure("style", `the paragraph style did not move ${at} (${counts})`);
188
192
  if (left.text === right.text && left.listLevel !== right.listLevel) return failure("list-level", `the list level did not move ${at} (${counts})`);
193
+ if (left.text === right.text && left.directAlignment !== right.directAlignment) return failure("alignment", `the direct paragraph alignment did not move ${at} (${counts})`);
189
194
  if (collapseWhitespace(left.text) === collapseWhitespace(right.text)) return failure("whitespace", `a block's text differs only in whitespace ${at} (${counts})`);
190
195
  if (actual.length !== expected.length) return failure("block-count", `${counts}, first differing ${at}`);
191
- return failure("text", `a ${containerKind(left.container)} block's text does not match ${at}, length ${String(left.text.length)} against ${String(right.text.length)} (${counts})`);
196
+ return failure("text", `a ${containerKind(left.table)} block's text does not match ${at}, length ${String(left.text.length)} against ${String(right.text.length)} (${counts})`);
192
197
  };
193
198
  const isAParagraphMarkChangeKind = (value) => PARAGRAPH_MARK_CHANGE_KINDS.some((kind) => kind === value);
194
199
  const isRecord = (value) => typeof value === "object" && value !== null;
@@ -274,4 +279,4 @@ const revisedFinalParagraphMarks = (packageModel, { since = 0 } = {}) => {
274
279
  return found;
275
280
  };
276
281
  //#endregion
277
- export { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, classifyGeometryMismatch, classifyProjectionMismatch, projectSupportedInlineFormatting, revisedFinalParagraphMarks, sameProjection };
282
+ export { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, classifyGeometryMismatch, classifyProjectionMismatch, projectSupportedInlineFormatting, revisedFinalParagraphMarks };
@@ -2,7 +2,7 @@ import { document_d_exports } from "../types/document.js";
2
2
  import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIBlockTableLocation, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditNormalization, FolioAIEditNormalizationCode, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "../ai-edits/types.js";
3
3
  import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments } from "../ai-edits/word-diff.js";
4
4
  import { FolioAIEditApplyOutcome, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "../ai-edits/apply.js";
5
- import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
5
+ import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
6
6
  import { createFolioAIEditSnapshot, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "../ai-edits/snapshot.js";
7
7
  import { DeriveBlockIdInput, FolioBlockId, currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
8
8
  import { AIBarStatus, AIChatMode, AICitation, AICitationSource, AIGenerateInput, AISuggestion, AISuggestionApplyMode, AISuggestionPreset, AISuggestionSeverity, AISuggestionStatus, DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
@@ -37,4 +37,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
37
37
  import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
38
38
  type Document = document_d_exports.Document;
39
39
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
40
- export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
40
+ export { type AIBarStatus, type AIChatMode, type AICitation, type AICitationRange, type AICitationSource, type AIGenerateInput, type AISuggestion, type AISuggestionApplyMode, type AISuggestionPreset, type AISuggestionSeverity, type AISuggestionStatus, type AcceptAutocompleteResult, type AnonymizationMatch, type AnonymizationTerm, type ApplyFolioDocumentOperationsOptions, type ApplyResult, type AutocompleteSuggestionPluginOptions, type AutocompleteSuggestionState, type AutocompleteSuggestionStatus, type AutocompleteTriggerCheck, type AutocompleteTriggerOptions, type AutocompleteTriggerSkipReason, type BlockRect, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFormatRange, type CompareResult, type CompareUnsupportedPart, type CompareUnsupportedReason, type CompareVerification, type CompareVerificationCause, type CompareVerificationFailure, type CompareVerificationInvariant, type CreateEmptyDocumentOptions, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, type DeriveBlockIdInput, type DirectiveKind, type DirectiveRange, type Document, type DocumentPreset, type DocumentStyleCatalog, type DocumentStyleCatalogEntry, type DocumentStyleSet, type DocxCompatibility, type DocxCompatibilityContext, type DocxCompatibilityIssue, type DocxCompatibilityLocation, type DocxCompatibilityPart, type DocxConformanceClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAISignatureParty, type FolioBlockId, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocxCompatibilityHost, type FolioDocxCompatibilityProfile, type FolioRevisionStamp, type FolioWordDiffOptions, type ImageMeta, type ImageRef, type InspectDocxCompatibilityOptions, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, type MarkdownOptions, type MarkdownResult, type PositionalText, type ResolvedAnchor, STELLA_STYLE_SET_NAME, type TemplatePreviewSpan, type TemplatePreviewValue, type TemplatePreviewValues, type TemplateSlashMenuKeyAction, type TemplateSlashMenuState, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -8,7 +8,7 @@ import { DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
8
8
  import { MAX_COMPARE_OPERATIONS, compareDocx } from "../compare/compare.js";
9
9
  import { COMPARE_UNSUPPORTED_REASONS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, InvalidCompareDocxOptionsError } from "../compare/types.js";
10
10
  import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS } from "../compare/verification.js";
11
- import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
11
+ import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
12
12
  import { inspectDocxCompatibility } from "../docx/compatibility.js";
13
13
  import { createDocx } from "../docx/rezip.js";
14
14
  import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
@@ -31,4 +31,4 @@ import { currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioB
31
31
  import { createEmptyDocument } from "../utils/createDocument.js";
32
32
  import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
33
33
  import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
34
- export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
34
+ export { COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, CompareDocxApplyError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, DEFAULT_AI_SUGGESTION_PRESETS, DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION, DOCX_CONFORMANCE_CLASSES, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidCompareDocxOptionsError, InvalidFolioDocumentOperationBatchError, MAX_COMPARE_OPERATIONS, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, WORD_DIFF_GRANULARITIES, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, compareDocx, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, currentFolioBlockId, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, isFolioAIContentBlock, isFolioBlockId, isFolioDocumentOperationModeSupported, isSequentialFolioBlockId, isSuggestionStale, isSupportedFolioDocumentOperationVersion, mergeDocumentContent, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, resetTemplateSlashQuery, resolveSuggestionAnchor, scanDirectives, scopeEmbeddedFontFamily, scrollFolioPositionIntoView, setAICitationsMeta, setAISuggestionsMeta, setActiveCitationMeta, setAnonymizationTermsMeta, setEmbeddedFontFamilyMap, setFocusedSuggestionMeta, setGoogleFontsEnabled, setTemplatePreviewValues, shouldTriggerAutocomplete, startAutocompleteSuggestion, templateSlashMenuKey, toMarkdown, toMarkdownResult };
@@ -1,4 +1,5 @@
1
1
  import { clearHeaderFooterVerbatimXml } from "../docx/headerFooterVerbatim.js";
2
+ import { cloneParagraphWithPropertySource } from "../docx/paragraphPropertySource.js";
2
3
  import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
3
4
  import { headerFooterToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
4
5
  import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js";
@@ -14,10 +15,9 @@ const DETACHED_WATERMARK_HOST = Symbol.for("stll.detachedWatermarkHost");
14
15
  const headerFooterToProseDocWithDetachedWatermarkHost = (headerFooter, options) => {
15
16
  return headerFooterToProseDoc(headerFooter.content.map((block, blockIndex) => {
16
17
  if (blockIndex !== headerFooter.watermarkBlockIndex || block.type !== "paragraph") return block;
17
- return {
18
- ...block,
19
- [DETACHED_WATERMARK_HOST]: true
20
- };
18
+ const marked = cloneParagraphWithPropertySource(block, {});
19
+ Reflect.set(marked, DETACHED_WATERMARK_HOST, true);
20
+ return marked;
21
21
  }), options);
22
22
  };
23
23
  const buildInitialState = (headerFooter, styles, theme, manager) => {
@@ -151,7 +151,7 @@ const createHeaderFooterEditorManager = (deps) => {
151
151
  if (!source || !existing) continue;
152
152
  const updated = {
153
153
  ...existing,
154
- content: proseDocToBlocks(view.state.doc)
154
+ content: proseDocToBlocks(view.state.doc, existing.content)
155
155
  };
156
156
  clearHeaderFooterVerbatimXml(updated);
157
157
  if (kind === "header") {
@@ -1,7 +1,7 @@
1
1
  import { fromProseDoc } from "../prosemirror/conversion/fromProseDoc.js";
2
2
  import { CellSelection } from "prosemirror-tables";
3
- import { redo, undo } from "prosemirror-history";
4
3
  import { NodeSelection, Selection, TextSelection } from "prosemirror-state";
4
+ import { redo, undo } from "prosemirror-history";
5
5
  //#region src/controller/hiddenEditorApi.ts
6
6
  /**
7
7
  * Hidden-editor imperative API
@@ -169,7 +169,7 @@ const createNoteEditorManager = (deps) => {
169
169
  }
170
170
  const updated = {
171
171
  ...current,
172
- content: proseDocToBlocks(story.view.state.doc)
172
+ content: proseDocToBlocks(story.view.state.doc, current.content)
173
173
  };
174
174
  footnotes[index] = updated;
175
175
  story.appliedNote = updated;
@@ -186,7 +186,7 @@ const createNoteEditorManager = (deps) => {
186
186
  }
187
187
  const updated = {
188
188
  ...current,
189
- content: proseDocToBlocks(story.view.state.doc)
189
+ content: proseDocToBlocks(story.view.state.doc, current.content)
190
190
  };
191
191
  endnotes[index] = updated;
192
192
  story.appliedNote = updated;
@@ -3,6 +3,8 @@ import { FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditNormaliza
3
3
  import { FolioAIEditView, FolioRevisionStamp, FolioWordDiffOptions } from "./ai-edits/apply.js";
4
4
  //#region src/document-operations.d.ts
5
5
  declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
6
+ /** Direct paragraph-alignment values accepted by the operation contract. */
7
+ declare const FOLIO_PARAGRAPH_ALIGNMENT_VALUES: readonly ("left" | "center" | "right" | "both" | "distribute" | "mediumKashida" | "highKashida" | "lowKashida" | "thaiDistribute")[];
6
8
  declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "splitBlock", "mergeBlockWithNext", "setBlockParagraphProperties", "insertTable", "deleteTable", "commentOnBlock", "insertSignatureTable", "insertTableRow", "deleteTableRow", "insertTableColumn", "deleteTableColumn", "mergeTableCells", "splitTableCell"];
7
9
  declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes", "suggested"];
8
10
  declare const FOLIO_DOCUMENT_OPERATION_STORIES: readonly ["main", "header", "footer", "footnote", "endnote"];
@@ -93,8 +95,8 @@ declare const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE: Readonly<{
93
95
  readonly replaceRange: readonly ["id", "type", "range", "severity", "area", "precondition", "suggestionId", "replace", "comment"];
94
96
  readonly commentOnRange: readonly ["id", "type", "range", "severity", "area", "precondition", "comment"];
95
97
  readonly formatRange: readonly ["id", "type", "range", "severity", "area", "precondition", "suggestionId", "formatting"];
96
- readonly insertAfterBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
97
- readonly insertBeforeBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
98
+ readonly insertAfterBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "alignment", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
99
+ readonly insertBeforeBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "inheritFormatting", "alignment", "listLevel", "moveId", "pageBreakBefore", "styleId", "comment"];
98
100
  readonly replaceBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "text", "preserveFormatting", "styleId", "comment"];
99
101
  readonly deleteBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "moveId", "comment"];
100
102
  readonly splitBlock: readonly ["id", "type", "blockId", "severity", "area", "precondition", "suggestionId", "offset", "separator"];
@@ -278,4 +280,4 @@ type ApplyFolioDocumentOperationsOptions = {
278
280
  };
279
281
  declare const applyFolioDocumentOperations: ({ view, snapshot, batch, story, author, createCommentId, createUndoHandle, revisionStamp, wordDiff, tableTemplates }: ApplyFolioDocumentOperationsOptions) => FolioDocumentOperationResult;
280
282
  //#endregion
281
- export { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationBatchPrecondition, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationQueuedOperation, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
283
+ export { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationBatchPrecondition, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationQueuedOperation, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
@@ -1,7 +1,10 @@
1
1
  import { applyFolioAIEditOperations, previewFolioAIEditOperations } from "./ai-edits/apply.js";
2
+ import { PARAGRAPH_ALIGNMENT_VALUES } from "./types/documentEnumValues.js";
2
3
  import { TaggedError } from "better-result";
3
4
  //#region src/document-operations.ts
4
5
  const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION = 1;
6
+ /** Direct paragraph-alignment values accepted by the operation contract. */
7
+ const FOLIO_PARAGRAPH_ALIGNMENT_VALUES = Object.freeze([...PARAGRAPH_ALIGNMENT_VALUES]);
5
8
  const FOLIO_DOCUMENT_OPERATION_TYPES = Object.freeze([
6
9
  "replaceInBlock",
7
10
  "replaceRange",
@@ -185,6 +188,12 @@ const readClearableNonNegativeInteger = (value, key, path) => {
185
188
  if (candidate === void 0) return;
186
189
  return candidate === null ? null : readNonNegativeInteger(value, key, path);
187
190
  };
191
+ const readClearableParagraphAlignment = ({ value, key, path }) => {
192
+ const candidate = value[key];
193
+ if (candidate === void 0 || candidate === null) return candidate;
194
+ for (const alignment of FOLIO_PARAGRAPH_ALIGNMENT_VALUES) if (candidate === alignment) return alignment;
195
+ return invalidBatch(`${path}.${key}`, `expected one of ${FOLIO_PARAGRAPH_ALIGNMENT_VALUES.join(", ")} or null when provided`);
196
+ };
188
197
  /**
189
198
  * A rectangular grid of cell texts. Rectangular because a table whose rows
190
199
  * hold different cell counts is not a table any consumer can lay out, and the
@@ -209,13 +218,23 @@ const readParagraphProperties = (value, path) => {
209
218
  const candidate = value["properties"];
210
219
  const propertiesPath = `${path}.properties`;
211
220
  if (!isPlainObject(candidate)) return invalidBatch(propertiesPath, "expected an object");
212
- assertAllowedKeys(candidate, propertiesPath, ["styleId", "listLevel"]);
221
+ assertAllowedKeys(candidate, propertiesPath, [
222
+ "styleId",
223
+ "listLevel",
224
+ "alignment"
225
+ ]);
213
226
  const styleId = candidate["styleId"] === null ? null : readOptionalString(candidate, "styleId", propertiesPath);
214
227
  const listLevel = readClearableNonNegativeInteger(candidate, "listLevel", propertiesPath);
215
- if (styleId === void 0 && listLevel === void 0) return invalidBatch(propertiesPath, "expected at least one property to set");
228
+ const alignment = readClearableParagraphAlignment({
229
+ value: candidate,
230
+ key: "alignment",
231
+ path: propertiesPath
232
+ });
233
+ if (styleId === void 0 && listLevel === void 0 && alignment === void 0) return invalidBatch(propertiesPath, "expected at least one property to set");
216
234
  return {
217
235
  ...styleId !== void 0 && { styleId },
218
- ...listLevel !== void 0 && { listLevel }
236
+ ...listLevel !== void 0 && { listLevel },
237
+ ...alignment !== void 0 && { alignment }
219
238
  };
220
239
  };
221
240
  const readTextRange = (value, path) => {
@@ -354,6 +373,7 @@ const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE = Object.freeze({
354
373
  ...COMMON_OPERATION_KEYS,
355
374
  "text",
356
375
  "inheritFormatting",
376
+ "alignment",
357
377
  "listLevel",
358
378
  "moveId",
359
379
  "pageBreakBefore",
@@ -364,6 +384,7 @@ const FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE = Object.freeze({
364
384
  ...COMMON_OPERATION_KEYS,
365
385
  "text",
366
386
  "inheritFormatting",
387
+ "alignment",
367
388
  "listLevel",
368
389
  "moveId",
369
390
  "pageBreakBefore",
@@ -545,6 +566,11 @@ const parseDocumentOperation = (value, index) => {
545
566
  const styleId = value["styleId"] === null ? null : readOptionalString(value, "styleId", path);
546
567
  const moveId = readOptionalString(value, "moveId", path);
547
568
  const listLevel = readClearableNonNegativeInteger(value, "listLevel", path);
569
+ const alignment = readClearableParagraphAlignment({
570
+ value,
571
+ key: "alignment",
572
+ path
573
+ });
548
574
  return {
549
575
  ...operationMeta,
550
576
  id,
@@ -552,6 +578,7 @@ const parseDocumentOperation = (value, index) => {
552
578
  blockId,
553
579
  text: readString(value, "text", path),
554
580
  ...inheritFormatting !== void 0 && { inheritFormatting },
581
+ ...alignment !== void 0 && { alignment },
555
582
  ...listLevel !== void 0 && { listLevel },
556
583
  ...moveId !== void 0 && { moveId },
557
584
  ...pageBreakBefore !== void 0 && { pageBreakBefore },
@@ -561,7 +588,7 @@ const parseDocumentOperation = (value, index) => {
561
588
  }
562
589
  if (type === "replaceBlock") {
563
590
  const preserveFormatting = readOptionalBoolean(value, "preserveFormatting", path);
564
- const styleId = readOptionalString(value, "styleId", path);
591
+ const styleId = value["styleId"] === null ? null : readOptionalString(value, "styleId", path);
565
592
  return {
566
593
  ...operationMeta,
567
594
  id,
@@ -981,4 +1008,4 @@ const applyFolioDocumentOperations = ({ view, snapshot, batch, story = "main", a
981
1008
  };
982
1009
  };
983
1010
  //#endregion
984
- export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
1011
+ export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_BATCH_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_KEYS_BY_TYPE, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
@@ -1,4 +1,5 @@
1
1
  import { parseParagraph } from "./paragraphParser.js";
2
+ import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
2
3
  import { parseRunProperties } from "./runParser.js";
3
4
  import { findChild, getAttribute, getChildElements, getLocalName, parseXml } from "./xmlParser.js";
4
5
  //#region src/docx/commentParser.ts
@@ -14,10 +15,7 @@ const normalizeFirstCommentParagraph = (paragraphElement, paragraph, theme) => {
14
15
  const annotationReferenceFormatting = normalizeAnnotationReferenceFormatting(runProperties ? parseRunProperties(runProperties, theme) : void 0);
15
16
  const firstParsedContent = paragraph.content.at(0);
16
17
  return {
17
- paragraph: firstParsedContent?.type === "run" && firstParsedContent.content.length === 0 ? {
18
- ...paragraph,
19
- content: paragraph.content.slice(1)
20
- } : paragraph,
18
+ paragraph: firstParsedContent?.type === "run" && firstParsedContent.content.length === 0 ? cloneParagraphWithPropertySource(paragraph, { content: paragraph.content.slice(1) }) : paragraph,
21
19
  ...annotationReferenceFormatting !== void 0 ? { annotationReferenceFormatting } : {}
22
20
  };
23
21
  };