@stll/folio-core 0.40.0 → 0.41.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 (47) hide show
  1. package/dist/ai-edits/clean-text.d.ts +28 -6
  2. package/dist/ai-edits/clean-text.js +28 -13
  3. package/dist/ai-edits/headless.d.ts +12 -0
  4. package/dist/ai-edits/headless.js +26 -3
  5. package/dist/ai-edits/snapshot.d.ts +6 -1
  6. package/dist/ai-edits/snapshot.js +15 -10
  7. package/dist/ai-suggestions/text-positions.js +15 -3
  8. package/dist/compare/inline-atoms.js +2 -2
  9. package/dist/compat/eigenpal.d.ts +3 -2
  10. package/dist/compat/eigenpal.js +2 -1
  11. package/dist/display-list/primitives.d.ts +2 -1
  12. package/dist/document-operations.d.ts +3 -2
  13. package/dist/docx/blockPlainText.d.ts +8 -0
  14. package/dist/docx/blockPlainText.js +40 -0
  15. package/dist/docx/compatibility.d.ts +16 -2
  16. package/dist/docx/compatibility.js +30 -9
  17. package/dist/docx/footnoteParser.js +4 -23
  18. package/dist/docx/graphicFrameLocks.d.ts +22 -0
  19. package/dist/docx/graphicFrameLocks.js +55 -0
  20. package/dist/docx/groupDrawingParser.d.ts +7 -1
  21. package/dist/docx/groupDrawingParser.js +11 -2
  22. package/dist/docx/headerFooterParser.d.ts +5 -1
  23. package/dist/docx/headerFooterParser.js +7 -21
  24. package/dist/docx/imageParser.js +5 -0
  25. package/dist/docx/imageRawXml.d.ts +33 -1
  26. package/dist/docx/imageRawXml.js +56 -1
  27. package/dist/docx/runParser.js +43 -21
  28. package/dist/docx/serializer/runSerializer.js +4 -2
  29. package/dist/docx/server/createBilingualDocument.js +31 -5
  30. package/dist/docx/shapeParser.js +32 -6
  31. package/dist/docx/vmlImageParser.d.ts +11 -1
  32. package/dist/docx/vmlImageParser.js +29 -2
  33. package/dist/index.d.ts +3 -2
  34. package/dist/index.js +2 -1
  35. package/dist/internal/compare/inline-presentation.d.ts +11 -3
  36. package/dist/internal/compare/inline-presentation.js +8 -1
  37. package/dist/prosemirror/attrs/index.js +33 -3
  38. package/dist/prosemirror/conversion/fromProseDoc.d.ts +13 -2
  39. package/dist/prosemirror/conversion/fromProseDoc.js +80 -27
  40. package/dist/prosemirror/conversion/index.d.ts +2 -2
  41. package/dist/prosemirror/conversion/toProseDoc.js +10 -2
  42. package/dist/prosemirror/extensions/nodes/ImageExtension.js +6 -0
  43. package/dist/prosemirror/imageCommit.js +7 -3
  44. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +16 -1
  45. package/dist/prosemirror/runFormattingInlineCarriers.js +20 -1
  46. package/dist/prosemirror/schema/nodes.d.ts +20 -0
  47. package/package.json +2 -2
@@ -44,6 +44,18 @@ type CleanTextStructuralBoundary = {
44
44
  clear?: PageBreakRunAttrs["clear"];
45
45
  /** Whether the post-tracked-changes projection retains this carrier. */
46
46
  presentInCleanView: boolean;
47
+ } | {
48
+ /**
49
+ * A field result: several clean-text characters over a single PM
50
+ * position. Only the whole span is addressable, so a text range may
51
+ * start or end at its edges but never inside it.
52
+ */
53
+ type: "field";
54
+ offset: number;
55
+ /** Characters the result contributes; always greater than one. */
56
+ length: number;
57
+ from: number;
58
+ to: number;
47
59
  };
48
60
  type ResolveCleanTextRangeOptions = {
49
61
  cleanBlock: CleanBlockText;
@@ -51,17 +63,27 @@ type ResolveCleanTextRangeOptions = {
51
63
  endOffset: number;
52
64
  };
53
65
  /**
54
- * Resolve clean-text offsets without selecting a zero-width structural atom.
66
+ * Resolve clean-text offsets without selecting a structural atom.
55
67
  *
56
- * A range wholly on one side of a boundary is biased away from the atom. A
57
- * range spanning both sides is unrepresentable as a generic text selection
58
- * and returns `null`; a structural operation must own that mutation instead.
68
+ * A range wholly on one side of a zero-width boundary is biased away from the
69
+ * atom. A range spanning both sides, or cutting into a field result, is
70
+ * unrepresentable as a generic text selection and returns `null`; a structural
71
+ * operation must own that mutation instead.
59
72
  */
60
73
  declare const resolveCleanTextRange: ({ cleanBlock, startOffset, endOffset }: ResolveCleanTextRangeOptions) => {
61
74
  from: number;
62
75
  to: number;
63
76
  } | null;
64
- declare const buildCleanBlockText: (blockNode: Node, blockFrom: number) => CleanBlockText;
77
+ type BuildCleanBlockTextOptions = {
78
+ /**
79
+ * `"text"` reads a field as the result Word shows, which is the view a reader
80
+ * and the AI reason against. `"omitted"` drops it, which is what an alignment
81
+ * coordinate needs: an atom present on only one side must not shift the
82
+ * offsets that locate it.
83
+ */
84
+ fieldResults: "text" | "omitted";
85
+ };
86
+ declare const buildCleanBlockText: (blockNode: Node, blockFrom: number, { fieldResults }?: BuildCleanBlockTextOptions) => CleanBlockText;
65
87
  /**
66
88
  * A "redline-aware" view of a textblock: the same left-to-right traversal as
67
89
  * {@link buildCleanBlockText}, but every tracked change and comment anchor is
@@ -83,4 +105,4 @@ declare const buildCleanBlockText: (blockNode: Node, blockFrom: number) => Clean
83
105
  */
84
106
  declare const buildAnnotatedBlockText: (blockNode: Node) => string;
85
107
  //#endregion
86
- export { CleanBlockText, CleanTextStructuralBoundary, buildAnnotatedBlockText, buildCleanBlockText, resolveCleanTextRange };
108
+ export { BuildCleanBlockTextOptions, CleanBlockText, CleanTextStructuralBoundary, buildAnnotatedBlockText, buildCleanBlockText, resolveCleanTextRange };
@@ -1,13 +1,15 @@
1
1
  import { expectPageBreakRunAttrs } from "../prosemirror/attrs/index.js";
2
- import { runFormattingInlineControlCharacter } from "../prosemirror/runFormattingInlineCarriers.js";
2
+ import { runFormattingInlineAtomCleanText, runFormattingInlineControlCharacter } from "../prosemirror/runFormattingInlineCarriers.js";
3
3
  //#region src/ai-edits/clean-text.ts
4
4
  const EMPTY_CLEAN_TEXT_STRUCTURAL_BOUNDARIES = Object.freeze([]);
5
+ const cutsIntoSpan = ({ offset, length }, boundaryOffset) => boundaryOffset > offset && boundaryOffset < offset + length;
5
6
  /**
6
- * Resolve clean-text offsets without selecting a zero-width structural atom.
7
+ * Resolve clean-text offsets without selecting a structural atom.
7
8
  *
8
- * A range wholly on one side of a boundary is biased away from the atom. A
9
- * range spanning both sides is unrepresentable as a generic text selection
10
- * and returns `null`; a structural operation must own that mutation instead.
9
+ * A range wholly on one side of a zero-width boundary is biased away from the
10
+ * atom. A range spanning both sides, or cutting into a field result, is
11
+ * unrepresentable as a generic text selection and returns `null`; a structural
12
+ * operation must own that mutation instead.
11
13
  */
12
14
  const resolveCleanTextRange = ({ cleanBlock, startOffset, endOffset }) => {
13
15
  if (!Number.isInteger(startOffset) || !Number.isInteger(endOffset) || startOffset < 0 || endOffset < startOffset || endOffset > cleanBlock.text.length) return null;
@@ -22,6 +24,10 @@ const resolveCleanTextRange = ({ cleanBlock, startOffset, endOffset }) => {
22
24
  let from = baseFrom;
23
25
  let to = baseTo;
24
26
  for (const boundary of structuralBoundaries) {
27
+ if (boundary.type === "field") {
28
+ if (cutsIntoSpan(boundary, startOffset) || cutsIntoSpan(boundary, endOffset)) return null;
29
+ continue;
30
+ }
25
31
  if (boundary.offset > startOffset && boundary.offset < endOffset) return null;
26
32
  if (boundary.offset === startOffset) from = Math.max(from, boundary.to);
27
33
  if (startOffset !== endOffset && boundary.offset === endOffset) to = Math.min(to, boundary.from);
@@ -40,7 +46,8 @@ const INSERTION_MARK = "insertion";
40
46
  const COMMENT_MARK = "comment";
41
47
  const HIDDEN_MARK = "hidden";
42
48
  const isOmittedFromCleanView = (node) => node.marks.some((mark) => mark.type.name === DELETION_MARK || mark.type.name === HIDDEN_MARK);
43
- const buildCleanBlockText = (blockNode, blockFrom) => {
49
+ const DEFAULT_BUILD_CLEAN_BLOCK_TEXT_OPTIONS = { fieldResults: "text" };
50
+ const buildCleanBlockText = (blockNode, blockFrom, { fieldResults } = DEFAULT_BUILD_CLEAN_BLOCK_TEXT_OPTIONS) => {
44
51
  let text = "";
45
52
  const offsets = [];
46
53
  let structuralBoundaries;
@@ -59,12 +66,19 @@ const buildCleanBlockText = (blockNode, blockFrom) => {
59
66
  });
60
67
  return false;
61
68
  }
62
- const controlCharacter = runFormattingInlineControlCharacter(node);
63
- if (controlCharacter !== null) {
69
+ const atomText = fieldResults === "omitted" ? runFormattingInlineControlCharacter(node) : runFormattingInlineAtomCleanText(node);
70
+ if (atomText !== null) {
64
71
  if (isOmittedFromCleanView(node)) return false;
65
72
  const startPos = blockFrom + 1 + pos;
66
- offsets.push(startPos);
67
- text += controlCharacter;
73
+ if (atomText.length > 1) (structuralBoundaries ??= []).push({
74
+ type: "field",
75
+ offset: text.length,
76
+ length: atomText.length,
77
+ from: startPos,
78
+ to: startPos + node.nodeSize
79
+ });
80
+ for (let index = 0; index < atomText.length; index++) offsets.push(startPos);
81
+ text += atomText;
68
82
  lastEnd = startPos + node.nodeSize;
69
83
  return false;
70
84
  }
@@ -105,16 +119,17 @@ const buildCleanBlockText = (blockNode, blockFrom) => {
105
119
  const buildAnnotatedBlockText = (blockNode) => {
106
120
  const segments = [];
107
121
  blockNode.descendants((node) => {
108
- if (!node.isText || node.text === void 0) return true;
122
+ const text = node.isText ? node.text : runFormattingInlineAtomCleanText(node);
123
+ if (text === void 0 || text === null) return true;
109
124
  const annotation = annotationOf(node.marks);
110
125
  const previous = segments.at(-1);
111
126
  if (previous && sameAnnotation(previous.annotation, annotation)) {
112
- previous.text += node.text;
127
+ previous.text += text;
113
128
  return false;
114
129
  }
115
130
  segments.push({
116
131
  annotation,
117
- text: node.text
132
+ text
118
133
  });
119
134
  return false;
120
135
  });
@@ -514,6 +514,18 @@ declare class FolioDocxReviewer {
514
514
  private createComparisonHeaderFooter;
515
515
  private canImportHeaderFooterContent;
516
516
  private getNoteStory;
517
+ /**
518
+ * A loaded story's blocks, so its text comes from the same walk an unloaded
519
+ * one uses.
520
+ *
521
+ * The two used to be separate walks and disagreed: the model walk separates
522
+ * paragraphs, joins table cells with a tab and reads the accepted
523
+ * tracked-change view, while the editor walk concatenated text nodes and saw
524
+ * none of that. The same note therefore read one way before it was loaded and
525
+ * another after. This is the conversion the save path already performs on the
526
+ * same states, so the text now describes exactly what a save would write.
527
+ */
528
+ private storyBlocks;
517
529
  private getHeaderFooterStoryText;
518
530
  private getNoteStoryText;
519
531
  private getStoryText;
@@ -1530,14 +1530,37 @@ var FolioDocxReviewer = class FolioDocxReviewer {
1530
1530
  if (story.type === "footnote") return this.baseDocument.package.footnotes?.find((note) => note.id === story.noteId && !isSeparatorFootnote(note));
1531
1531
  return this.baseDocument.package.endnotes?.find((note) => note.id === story.noteId && !isSeparatorEndnote(note));
1532
1532
  }
1533
+ /**
1534
+ * A loaded story's blocks, so its text comes from the same walk an unloaded
1535
+ * one uses.
1536
+ *
1537
+ * The two used to be separate walks and disagreed: the model walk separates
1538
+ * paragraphs, joins table cells with a tab and reads the accepted
1539
+ * tracked-change view, while the editor walk concatenated text nodes and saw
1540
+ * none of that. The same note therefore read one way before it was loaded and
1541
+ * another after. This is the conversion the save path already performs on the
1542
+ * same states, so the text now describes exactly what a save would write.
1543
+ */
1544
+ storyBlocks(state, source) {
1545
+ return state ? proseDocToBlocks(state.doc, source.content, this.baseDocument.package.styles, { emptyFieldResult: "authored" }) : source.content;
1546
+ }
1533
1547
  getHeaderFooterStoryText(story, source) {
1534
1548
  const state = this.secondaryStoryStates.get(headerFooterStoryKey(story))?.state;
1535
- return normalizeFolioAIBlockText(state?.doc.textContent ?? getHeaderFooterText(source));
1549
+ return normalizeFolioAIBlockText(getHeaderFooterText({
1550
+ ...source,
1551
+ content: this.storyBlocks(state, source)
1552
+ }));
1536
1553
  }
1537
1554
  getNoteStoryText(story, source) {
1538
1555
  const state = this.secondaryStoryStates.get(noteStoryKey(story))?.state;
1539
- const sourceText = source.type === "footnote" ? getFootnoteText(source) : getEndnoteText(source);
1540
- return normalizeFolioAIBlockText(state?.doc.textContent ?? sourceText);
1556
+ const content = this.storyBlocks(state, source);
1557
+ return normalizeFolioAIBlockText(source.type === "footnote" ? getFootnoteText({
1558
+ ...source,
1559
+ content
1560
+ }) : getEndnoteText({
1561
+ ...source,
1562
+ content
1563
+ }));
1541
1564
  }
1542
1565
  getStoryText(story) {
1543
1566
  if (story.type === "main") return this.getContentAsText();
@@ -66,7 +66,12 @@ declare const isFolioAIContentBlock: ({ text }: Pick<FolioAIBlock, "text">) => b
66
66
  */
67
67
  declare const trailingBodyBlockId: ({ blocks }: FolioAIEditSnapshot) => string | null;
68
68
  declare const hashFolioAIBlockText: (text: string) => string;
69
- /** Canonical public projection of the clean view's zero-width structure. */
69
+ /**
70
+ * Canonical public projection of the clean view's zero-width structure.
71
+ *
72
+ * A field boundary stays internal: it marks text the reader already sees, so it
73
+ * belongs to range resolution rather than to a block's published structure.
74
+ */
70
75
  declare const projectFolioAIBlockStructuralBoundaries: ({ structuralBoundaries }: Pick<CleanBlockText, "structuralBoundaries">) => readonly FolioAIBlockStructuralBoundary[];
71
76
  /** Stable precondition fingerprint for a block's zero-width structure. */
72
77
  declare const hashFolioAIBlockStructuralBoundaries: (cleanBlock: Pick<CleanBlockText, "structuralBoundaries">) => string;
@@ -4,7 +4,7 @@ import { marksToTextFormatting } from "../prosemirror/conversion/fromProseDoc.js
4
4
  import { directParagraphAlignment } from "../prosemirror/paragraphAlignment.js";
5
5
  import { directParagraphIndentation } from "../prosemirror/paragraphIndentation.js";
6
6
  import { directParagraphSpacing } from "../prosemirror/paragraphSpacing.js";
7
- import { runFormattingInlineControlCharacter } from "../prosemirror/runFormattingInlineCarriers.js";
7
+ import { runFormattingInlineAtomCleanText } from "../prosemirror/runFormattingInlineCarriers.js";
8
8
  import { authoredRunFormattingFromAttrs } from "../prosemirror/runFormattingProvenance.js";
9
9
  import { readAuthoredRunFormatting, reconcileRunFormattingMarks } from "../prosemirror/runFormattingReconciliation.js";
10
10
  import { paragraphRunStyleContext } from "../prosemirror/runStyleFormatting.js";
@@ -231,15 +231,20 @@ const hashFolioAIBlockText = (text) => {
231
231
  };
232
232
  const EMPTY_FOLIO_AI_BLOCK_STRUCTURAL_BOUNDARIES = Object.freeze([]);
233
233
  const EMPTY_FOLIO_AI_BLOCK_STRUCTURAL_BOUNDARY_HASH = hashFolioAIBlockText(JSON.stringify(EMPTY_FOLIO_AI_BLOCK_STRUCTURAL_BOUNDARIES));
234
- /** Canonical public projection of the clean view's zero-width structure. */
234
+ /**
235
+ * Canonical public projection of the clean view's zero-width structure.
236
+ *
237
+ * A field boundary stays internal: it marks text the reader already sees, so it
238
+ * belongs to range resolution rather than to a block's published structure.
239
+ */
235
240
  const projectFolioAIBlockStructuralBoundaries = ({ structuralBoundaries }) => {
236
241
  let projected;
237
- for (const { clear, offset, presentInCleanView } of structuralBoundaries) {
238
- if (!presentInCleanView) continue;
242
+ for (const boundary of structuralBoundaries) {
243
+ if (boundary.type !== "pageBreakRun" || !boundary.presentInCleanView) continue;
239
244
  (projected ??= []).push({
240
245
  type: "pageBreak",
241
- offset,
242
- ...clear !== void 0 ? { clear } : {}
246
+ offset: boundary.offset,
247
+ ...boundary.clear !== void 0 ? { clear: boundary.clear } : {}
243
248
  });
244
249
  }
245
250
  return projected ?? EMPTY_FOLIO_AI_BLOCK_STRUCTURAL_BOUNDARIES;
@@ -531,13 +536,13 @@ const getPreviewRuns = ({ node, nodeFrom, cleanBlock, styleResolver }) => {
531
536
  let paragraphStyleContext;
532
537
  let cleanOffset = 0;
533
538
  node.descendants((child, relativePosition) => {
534
- const text = child.isText ? child.text : runFormattingInlineControlCharacter(child);
535
- if (text === void 0 || text === null) return true;
539
+ const text = child.isText ? child.text : runFormattingInlineAtomCleanText(child);
540
+ if (text === void 0 || text === null || text.length === 0) return true;
536
541
  if (child.marks.some((mark) => mark.type.name === DELETION_MARK || mark.type.name === HIDDEN_MARK)) return false;
537
542
  const start = nodeFrom + 1 + relativePosition;
538
543
  while ((cleanBlock.offsets[cleanOffset] ?? Number.POSITIVE_INFINITY) < start) cleanOffset++;
539
- const endOffset = cleanOffset + text.length - 1;
540
- if (cleanBlock.offsets[cleanOffset] !== start || cleanBlock.offsets[endOffset] !== start + text.length - 1) return false;
544
+ const lastCharacterPosition = child.isText ? start + text.length - 1 : start;
545
+ if (cleanBlock.offsets[cleanOffset] !== start || cleanBlock.offsets[cleanOffset + text.length - 1] !== lastCharacterPosition) return false;
541
546
  cleanOffset += text.length;
542
547
  const style = getPreviewRunStyle(child.marks, defaultStyle);
543
548
  const hasAuthorshipCarrier = child.marks.some(({ type }) => type.name === RUN_FORMATTING_OVERRIDE_MARK || type.name === CHARACTER_STYLE_MARK);
@@ -1,3 +1,4 @@
1
+ import { runFormattingInlineAtomResultText } from "../prosemirror/runFormattingInlineCarriers.js";
1
2
  //#region src/ai-suggestions/text-positions.ts
2
3
  const BLOCK_SEPARATOR = "\n";
3
4
  /**
@@ -15,11 +16,22 @@ function buildPositionalText(doc, from = 0, to = doc.content.size) {
15
16
  if (node.type.name === "pageBreakRun") {
16
17
  structuralBoundaries.push({
17
18
  textOffset: textLength,
18
- from: pos,
19
- to: pos + node.nodeSize
19
+ length: 0
20
20
  });
21
21
  return false;
22
22
  }
23
+ const resultText = runFormattingInlineAtomResultText(node);
24
+ if (resultText !== null) {
25
+ if (resultText.length === 0 || pos < from || pos + node.nodeSize > to) return false;
26
+ structuralBoundaries.push({
27
+ textOffset: textLength,
28
+ length: resultText.length
29
+ });
30
+ chunks.push(resultText);
31
+ for (let index = 0; index < resultText.length; index++) offsets.push(pos);
32
+ textLength += resultText.length;
33
+ return false;
34
+ }
23
35
  if (node.isText) {
24
36
  const text = node.text ?? "";
25
37
  const startInNode = Math.max(from, pos);
@@ -54,7 +66,7 @@ function buildPositionalText(doc, from = 0, to = doc.content.size) {
54
66
  text,
55
67
  pmPositionAt,
56
68
  pmRangeAt: (startTextIndex, endTextIndex) => {
57
- if (!Number.isInteger(startTextIndex) || !Number.isInteger(endTextIndex) || startTextIndex < 0 || endTextIndex <= startTextIndex || endTextIndex > text.length || structuralBoundaries.some(({ textOffset }) => textOffset > startTextIndex && textOffset < endTextIndex)) return null;
69
+ if (!Number.isInteger(startTextIndex) || !Number.isInteger(endTextIndex) || startTextIndex < 0 || endTextIndex <= startTextIndex || endTextIndex > text.length || structuralBoundaries.some(({ textOffset, length }) => length === 0 ? textOffset > startTextIndex && textOffset < endTextIndex : startTextIndex > textOffset && startTextIndex < textOffset + length || endTextIndex > textOffset && endTextIndex < textOffset + length)) return null;
58
70
  const rangeFrom = pmPositionAt(startTextIndex);
59
71
  const finalCharacter = offsets[endTextIndex - 1];
60
72
  if (finalCharacter === void 0) return null;
@@ -46,7 +46,7 @@ const atomKey = (node) => canonicalJson({
46
46
  content: node.content.toJSON()
47
47
  });
48
48
  const atomBlockOf = ({ node, from }) => {
49
- const clean = buildCleanBlockText(node, from);
49
+ const clean = buildCleanBlockText(node, from, { fieldResults: "omitted" });
50
50
  const supported = [];
51
51
  const unsupportedTopology = [];
52
52
  let unalignable = false;
@@ -237,7 +237,7 @@ const sameParagraphSourcePosition = ({ sourceBlocks, reviewed, offset }) => {
237
237
  if (typeof paraId !== "string" || paraId.length === 0) return null;
238
238
  const source = sourceBlocks.get(paraId);
239
239
  if (!source || source.node.type !== reviewed.node.type) return null;
240
- const clean = buildCleanBlockText(source.node, source.from);
240
+ const clean = buildCleanBlockText(source.node, source.from, { fieldResults: "omitted" });
241
241
  return clean.text === reviewed.cleanText ? clean.offsets[offset] ?? null : null;
242
242
  };
243
243
  /**
@@ -20,7 +20,8 @@ import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
20
20
  import { DocumentStyleCatalog, DocumentStyleCatalogEntry, ExtractDocumentStyleSetOptions, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
21
21
  import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
22
22
  import { createDocx } from "../docx/rezip.js";
23
- import { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, InspectDocxCompatibilityOptions, inspectDocxCompatibility } from "../docx/compatibility.js";
23
+ import { DRAWING_SAFETY_CLASSES, DrawingSafetyClass } from "../docx/imageRawXml.js";
24
+ import { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, DocxDrawingClassification, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, InspectDocxCompatibilityOptions, inspectDocxCompatibility } from "../docx/compatibility.js";
24
25
  import { BlockRect } from "../paged-layout/blockGeometry.js";
25
26
  import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
26
27
  import { scrollFolioPositionIntoView } from "../paged-layout/scrollToPmPosition.js";
@@ -39,4 +40,4 @@ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled
39
40
  import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
40
41
  type Document = document_d_exports.Document;
41
42
  type DocxConformanceClass = document_d_exports.DocxConformanceClass;
42
- 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_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, 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_CONTENT_COMPARISON_LIMITS, 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_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, 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 FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, 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, InvalidFolioContentComparisonError, 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, compareContent, 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 };
43
+ 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_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS, type CompareChange, type CompareChangeLocation, type CompareCompatibility, type CompareContentOptions, CompareDocxApplyError, type CompareDocxError, CompareDocxFinalParagraphMarkError, CompareDocxOperationLimitError, type CompareDocxOptions, CompareDocxParseError, CompareDocxRoundTripError, CompareDocxSerializeError, type CompareFolioRequirement, type CompareResult, type CompareRevisionFormat, 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, DRAWING_SAFETY_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 DocxDrawingClassification, type DrawingSafetyClass, type EmbeddedFont, type EmbeddedFontParts, type ExtractDocumentStyleSetOptions, FOLIO_CONTENT_COMPARISON_LIMITS, 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_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, type FinalParagraphMarkRevision, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockStructuralBoundary, 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 FolioAIInlineBooleanProperty, type FolioAIInlineFormatting, type FolioAIInlineFormattingPatch, type FolioAIParagraphSpacing, type FolioAISignatureParty, type FolioBlockId, type FolioContentBlock, type FolioContentBlockProperty, type FolioContentComparison, type FolioContentComparisonError, type FolioContentComparisonEvent, type FolioContentComparisonLimit, FolioContentComparisonLimitError, type FolioContentContainerPathEntry, type FolioContentFormatRange, type FolioContentFormattingChange, type FolioContentIdStability, type FolioContentInlineBooleanProperty, type FolioContentInlineComparisonResult, type FolioContentInlineFormatting, type FolioContentInlineFormattingPatch, FolioContentInlinePresentationProjectionError, type FolioContentLineSpacingRule, type FolioContentParagraphAlignment, type FolioContentParagraphFormattingPatch, type FolioContentParagraphKind, type FolioContentParagraphSpacing, type FolioContentRun, type FolioContentSnapshot, type FolioContentStructuralChange, type FolioContentTableLocation, type FolioContentTextSegment, 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, InvalidFolioContentComparisonError, 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, compareContent, 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 };
@@ -11,6 +11,7 @@ import { COMPARE_REVISION_FORMATS, COMPARE_UNSUPPORTED_REASONS, CompareDocxApply
11
11
  import { COMPARE_VERIFICATION_CAUSES, COMPARE_VERIFICATION_INVARIANTS } from "../compare/verification.js";
12
12
  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_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
13
13
  import { inspectDocxCompatibility } from "../docx/compatibility.js";
14
+ import { DRAWING_SAFETY_CLASSES } from "../docx/imageRawXml.js";
14
15
  import { createDocx } from "../docx/rezip.js";
15
16
  import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
16
17
  import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
@@ -32,4 +33,4 @@ import { currentFolioBlockId, deriveBlockId, getFolioParaIdFromBlockId, isFolioB
32
33
  import { createEmptyDocument } from "../utils/createDocument.js";
33
34
  import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
34
35
  import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
35
- export { COMPARE_REVISION_FORMATS, 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_CONTENT_COMPARISON_LIMITS, 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_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, 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, compareContent, 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 };
36
+ export { COMPARE_REVISION_FORMATS, 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, DRAWING_SAFETY_CLASSES, FOLIO_CONTENT_COMPARISON_LIMITS, 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_LINE_SPACING_RULE_VALUES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioContentComparisonLimitError, FolioContentInlinePresentationProjectionError, InvalidCompareDocxOptionsError, InvalidFolioContentComparisonError, 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, compareContent, 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 };
@@ -2,6 +2,7 @@ import { DisplayColor, DisplayGlyphRun, DisplayHitRegion, DisplayPrimitive } fro
2
2
  import { hasCursiveLetter, joinsAcrossBoundary } from "../utils/cursiveJoining.js";
3
3
  import { hasComplexScript, isComplexScriptCodePoint } from "../utils/scriptSegments.js";
4
4
  //#region src/display-list/primitives.d.ts
5
+ type PrimitiveKind = DisplayPrimitive["kind"];
5
6
  /**
6
7
  * Left edge of every code point of a run, as an offset from the run's `xPx`.
7
8
  *
@@ -15,7 +16,7 @@ import { hasComplexScript, isComplexScriptCodePoint } from "../utils/scriptSegme
15
16
  * advances rightward from its origin whatever the paragraph does.
16
17
  */
17
18
  declare const glyphCellOffsetsPx: (run: DisplayGlyphRun) => readonly number[];
18
- declare const DISPLAY_PRIMITIVE_KINDS: ("glyphRun" | "rect" | "line" | "image" | "clipGroup" | "rotateGroup" | "opacityGroup")[];
19
+ declare const DISPLAY_PRIMITIVE_KINDS: readonly PrimitiveKind[];
19
20
  /**
20
21
  * Dash geometry of each stroke pattern, as multiples of the stroke thickness.
21
22
  *
@@ -1,12 +1,13 @@
1
+ import { document_d_exports } from "./types/document.js";
1
2
  import { FolioTableTemplates } from "./ai-edits/table-template.js";
2
3
  import { FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditNormalization, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAITextRangeHandle } from "./ai-edits/types.js";
3
4
  import { FolioAIEditView, FolioRevisionStamp, FolioWordDiffOptions } from "./ai-edits/apply.js";
4
5
  //#region src/document-operations.d.ts
5
6
  declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
6
7
  /** 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")[];
8
+ declare const FOLIO_PARAGRAPH_ALIGNMENT_VALUES: readonly document_d_exports.ParagraphAlignment[];
8
9
  /** `w:spacing/@w:lineRule` values accepted by the operation contract. */
9
- declare const FOLIO_LINE_SPACING_RULE_VALUES: readonly ("auto" | "exact" | "atLeast")[];
10
+ declare const FOLIO_LINE_SPACING_RULE_VALUES: readonly document_d_exports.LineSpacingRule[];
10
11
  /** `w:br/@w:clear` values accepted on an authored hard page break. */
11
12
  declare const FOLIO_PAGE_BREAK_CLEAR_VALUES: readonly ["none", "left", "right", "all"];
12
13
  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"];
@@ -0,0 +1,8 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/docx/blockPlainText.d.ts
3
+ type PlainTextBlock = document_d_exports.Paragraph | document_d_exports.Table | document_d_exports.BlockSdt;
4
+ /** One entry per block, so callers can join or count lines as they need. */
5
+ declare const collectBlockTexts: (blocks: readonly PlainTextBlock[]) => string[];
6
+ declare const blockPlainText: (blocks: readonly PlainTextBlock[]) => string;
7
+ //#endregion
8
+ export { PlainTextBlock, blockPlainText, collectBlockTexts };
@@ -0,0 +1,40 @@
1
+ import { getParagraphText } from "./paragraphParser.js";
2
+ import { panic } from "better-result";
3
+ //#region src/docx/blockPlainText.ts
4
+ /**
5
+ * The one plain-text projection of a block sequence.
6
+ *
7
+ * Every story — body, header, footer, footnote, endnote — reads through here,
8
+ * so a reader, a hash and a comparison all see the same string for the same
9
+ * content. Header and footer text used to come from a separate walk that
10
+ * handled only text runs, silently dropping fields, hyperlinks, tabs, breaks
11
+ * and tracked changes, so the same paragraph read one way in a note and another
12
+ * in a header.
13
+ *
14
+ * Separators carry the structure a reader needs: paragraphs and table rows are
15
+ * newline-separated, cells within a row tab-separated. `getParagraphText` owns
16
+ * everything below block level and reads the accepted tracked-change view.
17
+ */
18
+ /** One entry per block, so callers can join or count lines as they need. */
19
+ const collectBlockTexts = (blocks) => {
20
+ const texts = [];
21
+ for (const block of blocks) switch (block.type) {
22
+ case "paragraph":
23
+ texts.push(getParagraphText(block));
24
+ break;
25
+ case "table":
26
+ for (const row of block.rows) {
27
+ if (row.formatting?.hidden === true) continue;
28
+ texts.push(row.cells.map((cell) => collectBlockTexts(cell.content).join("\n")).join(" "));
29
+ }
30
+ break;
31
+ case "blockSdt":
32
+ texts.push(...collectBlockTexts(block.content));
33
+ break;
34
+ default: panic(`Unsupported block in plain-text extraction: ${JSON.stringify(block)}`);
35
+ }
36
+ return texts;
37
+ };
38
+ const blockPlainText = (blocks) => collectBlockTexts(blocks).join("\n");
39
+ //#endregion
40
+ export { blockPlainText, collectBlockTexts };
@@ -1,4 +1,5 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
+ import { DrawingSafetyClass } from "./imageRawXml.js";
2
3
  //#region src/docx/compatibility.d.ts
3
4
  type DocxCompatibilityReason = "opaqueDrawing";
4
5
  type FolioDocxCompatibilityHost = "browser" | "server" | "unknown";
@@ -26,14 +27,27 @@ type DocxCompatibilityIssue = {
26
27
  code: DocxCompatibilityReason;
27
28
  location: DocxCompatibilityLocation;
28
29
  };
30
+ /** A drawing and the fate the run serializer holds for it. */
31
+ type DocxDrawingClassification = {
32
+ class: DrawingSafetyClass;
33
+ location: DocxCompatibilityLocation;
34
+ };
35
+ /**
36
+ * Schema 2 replaced the per-drawing boolean judgement with
37
+ * {@link DocxDrawingClassification} and stopped reporting a replayable drawing
38
+ * as an issue; `issues` now holds opaque drawings only.
39
+ */
29
40
  type DocxCompatibility = {
30
- schemaVersion: 1;
41
+ schemaVersion: 2;
31
42
  context: DocxCompatibilityContext;
32
43
  canSafelyEdit: boolean;
44
+ /** Every drawing the walk reached, classified. */
45
+ drawings: DocxDrawingClassification[];
46
+ /** The blocking subset: drawings a save can neither replay nor regenerate. */
33
47
  issues: DocxCompatibilityIssue[];
34
48
  reasons: DocxCompatibilityReason[];
35
49
  unsupportedContentCount: number;
36
50
  };
37
51
  declare const inspectDocxCompatibility: (doc: document_d_exports.Document, options?: InspectDocxCompatibilityOptions) => DocxCompatibility;
38
52
  //#endregion
39
- export { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, DocxCompatibilityReason, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, InspectDocxCompatibilityOptions, inspectDocxCompatibility };
53
+ export { DocxCompatibility, DocxCompatibilityContext, DocxCompatibilityIssue, DocxCompatibilityLocation, DocxCompatibilityPart, DocxCompatibilityReason, DocxDrawingClassification, FolioDocxCompatibilityHost, FolioDocxCompatibilityProfile, InspectDocxCompatibilityOptions, inspectDocxCompatibility };
@@ -1,5 +1,16 @@
1
- import { DOCX_CONFORMANCE_CLASSES, DRAWING_RAW_XML_MODES } from "@stll/docx-core/model";
1
+ import { DRAWING_SAFETY_CLASSES, classifyDrawingSafety } from "./imageRawXml.js";
2
+ import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
2
3
  //#region src/docx/compatibility.ts
4
+ /**
5
+ * Whether a parsed package can be edited without losing content on save.
6
+ *
7
+ * Every part walked here is re-serialized from the model at some point: the
8
+ * repack always rebuilds `word/document.xml`, headers and footers replay their
9
+ * captured bytes only while their content fingerprint is unchanged, and note
10
+ * parts are preserved except for edited paragraphs spliced back by `w:paraId`.
11
+ * So an opaque drawing anywhere in this walk is a real risk, while a drawing the
12
+ * serializer replays verbatim is not, whichever part holds it.
13
+ */
3
14
  const resolveCompatibilityContext = (doc, options) => ({
4
15
  host: options.host ?? "unknown",
5
16
  profile: options.profile ?? doc.package.conformanceClass ?? DOCX_CONFORMANCE_CLASSES.UNKNOWN
@@ -7,13 +18,16 @@ const resolveCompatibilityContext = (doc, options) => ({
7
18
  const inspectDocxCompatibility = (doc, options = {}) => {
8
19
  const context = resolveCompatibilityContext(doc, options);
9
20
  const reasons = /* @__PURE__ */ new Set();
21
+ const drawings = [];
10
22
  const issues = [];
11
- const record = (location) => {
23
+ const record = (drawing) => {
24
+ drawings.push(drawing);
25
+ if (drawing.class !== DRAWING_SAFETY_CLASSES.OPAQUE) return;
12
26
  const code = "opaqueDrawing";
13
27
  reasons.add(code);
14
28
  issues.push({
15
29
  code,
16
- location
30
+ location: drawing.location
17
31
  });
18
32
  };
19
33
  inspectBlocks(doc.package.document.content, {
@@ -54,9 +68,10 @@ const inspectDocxCompatibility = (doc, options = {}) => {
54
68
  record
55
69
  });
56
70
  return {
57
- schemaVersion: 1,
71
+ schemaVersion: 2,
58
72
  context,
59
73
  canSafelyEdit: issues.length === 0,
74
+ drawings,
60
75
  issues,
61
76
  reasons: Array.from(reasons),
62
77
  unsupportedContentCount: issues.length
@@ -146,11 +161,17 @@ function inspectHyperlink(hyperlink, context) {
146
161
  });
147
162
  }
148
163
  function inspectRun(run, context) {
149
- for (const [contentIndex, content] of run.content.entries()) if (content.type === "drawing" && content.rawXml && content.rawXmlMode !== DRAWING_RAW_XML_MODES.PRESERVE_ONLY) context.record({
150
- ...context.blockId === void 0 ? {} : { blockId: context.blockId },
151
- part: context.part,
152
- path: `${context.path}.content[${contentIndex}]`
153
- });
164
+ for (const [contentIndex, content] of run.content.entries()) {
165
+ if (content.type !== "drawing") continue;
166
+ context.record({
167
+ class: classifyDrawingSafety(content),
168
+ location: {
169
+ ...context.blockId === void 0 ? {} : { blockId: context.blockId },
170
+ part: context.part,
171
+ path: `${context.path}.content[${contentIndex}]`
172
+ }
173
+ });
174
+ }
154
175
  }
155
176
  //#endregion
156
177
  export { inspectDocxCompatibility };