@stll/folio-core 0.15.1 → 0.15.3

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 (156) hide show
  1. package/dist/ai-edits/apply.js +2 -2
  2. package/dist/ai-edits/blockRange.js +1 -1
  3. package/dist/ai-edits/headless.js +9 -9
  4. package/dist/ai-edits/index.js +5 -5
  5. package/dist/ai-edits/read.js +1 -1
  6. package/dist/ai-edits/table-cell-mutations.js +2 -2
  7. package/dist/compat/eigenpal.js +19 -19
  8. package/dist/content-controls/mutateContentControls.js +1 -1
  9. package/dist/controller/contentControlWidgetController.js +1 -1
  10. package/dist/controller/headerFooterEditorManager.js +5 -5
  11. package/dist/controller/hiddenEditorManager.js +5 -5
  12. package/dist/controller/layoutPipeline.js +10 -10
  13. package/dist/controller/noteEditorManager.js +5 -5
  14. package/dist/docx/blockContentParser.js +4 -4
  15. package/dist/docx/commentParser.js +30 -2
  16. package/dist/docx/documentParser.js +27 -3
  17. package/dist/docx/drawingIdNormalization.d.ts +5 -0
  18. package/dist/docx/drawingIdNormalization.js +35 -0
  19. package/dist/docx/drawingUtils.d.ts +1 -1
  20. package/dist/docx/drawingUtils.js +111 -27
  21. package/dist/docx/encryption/agileDecryption.js +1 -1
  22. package/dist/docx/encryption/encryptionInfo.js +1 -1
  23. package/dist/docx/encryption/index.js +1 -1
  24. package/dist/docx/encryption/openEncryptedDocx.js +3 -3
  25. package/dist/docx/fieldParser.js +1 -1
  26. package/dist/docx/footnoteParser.js +2 -2
  27. package/dist/docx/groupDrawingParser.js +1 -1
  28. package/dist/docx/headerFooterParser.js +3 -3
  29. package/dist/docx/headerFooterVerbatim.d.ts +2 -1
  30. package/dist/docx/headerFooterVerbatim.js +6 -1
  31. package/dist/docx/hyperlinkParser.js +1 -1
  32. package/dist/docx/imageParser.js +3 -3
  33. package/dist/docx/index.js +1 -1
  34. package/dist/docx/paragraphParser.js +8 -5
  35. package/dist/docx/paragraphTextBoxEnrichment.js +4 -4
  36. package/dist/docx/paragraphTraversal.d.ts +5 -3
  37. package/dist/docx/paragraphTraversal.js +20 -13
  38. package/dist/docx/parser.js +17 -7
  39. package/dist/docx/parserEnums.d.ts +4 -1
  40. package/dist/docx/parserEnums.js +5 -2
  41. package/dist/docx/rezip.js +9 -9
  42. package/dist/docx/runConsolidator.js +0 -1
  43. package/dist/docx/runParser.js +22 -6
  44. package/dist/docx/sectionParser.js +2 -2
  45. package/dist/docx/selectiveSave.js +7 -7
  46. package/dist/docx/serializer/commentSerializer.js +13 -8
  47. package/dist/docx/serializer/documentSerializer.js +7 -3
  48. package/dist/docx/serializer/headerFooterSerializer.js +3 -3
  49. package/dist/docx/serializer/noteSerializer.js +2 -2
  50. package/dist/docx/serializer/numberingSerializer.js +1 -1
  51. package/dist/docx/serializer/paragraphSerializer.js +2 -2
  52. package/dist/docx/serializer/runSerializer.js +19 -13
  53. package/dist/docx/serializer/sectionPropertiesSerializer.js +4 -3
  54. package/dist/docx/serializer/stylesSerializer.js +3 -3
  55. package/dist/docx/serializer/tableSerializer.js +1 -1
  56. package/dist/docx/server/docxToMarkdown.js +1 -1
  57. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +1 -1
  58. package/dist/docx/server/extractDocxText.js +1 -1
  59. package/dist/docx/server/validateDocxConformance.js +3 -3
  60. package/dist/docx/shapeParser.js +5 -113
  61. package/dist/docx/styleParser.js +3 -3
  62. package/dist/docx/tableParser.js +11 -9
  63. package/dist/docx/textBoxParser.js +2 -2
  64. package/dist/docx/vmlImageParser.js +2 -2
  65. package/dist/fonts/embeddedFonts.js +2 -2
  66. package/dist/index.js +18 -18
  67. package/dist/layout-bridge/convert/footnoteLayout.js +2 -2
  68. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -2
  69. package/dist/layout-bridge/convert/paragraphFrames.js +2 -2
  70. package/dist/layout-bridge/convert/toFlowBlocks.js +10 -10
  71. package/dist/layout-bridge/engine/clickToPosition.js +2 -2
  72. package/dist/layout-bridge/engine/hitTest.js +1 -1
  73. package/dist/layout-bridge/engine/measuring/index.js +6 -6
  74. package/dist/layout-bridge/engine/selectionRects.js +5 -5
  75. package/dist/layout-engine/index.js +6 -6
  76. package/dist/layout-engine/measure/cache.js +2 -2
  77. package/dist/layout-engine/measure/index.js +6 -6
  78. package/dist/layout-engine/measure/lineBreaks.js +1 -1
  79. package/dist/layout-engine/measure/listMarkerWidth.js +1 -1
  80. package/dist/layout-engine/measure/measureBlocks.js +7 -7
  81. package/dist/layout-engine/measure/measureContainer.js +3 -3
  82. package/dist/layout-engine/measure/measureHelpers.js +1 -1
  83. package/dist/layout-engine/measure/measureParagraph.js +7 -7
  84. package/dist/layout-engine/measure/tableCellFlow.js +1 -1
  85. package/dist/layout-engine/paginator.js +1 -1
  86. package/dist/layout-engine/tableRowBreak.js +2 -2
  87. package/dist/layout-painter/index.js +5 -5
  88. package/dist/layout-painter/registry/modules/textBox.js +1 -1
  89. package/dist/layout-painter/renderImage.js +1 -1
  90. package/dist/layout-painter/renderPage.js +7 -7
  91. package/dist/layout-painter/renderParagraph.js +13 -13
  92. package/dist/layout-painter/renderTable.js +6 -6
  93. package/dist/layout-painter/renderTextBox.js +1 -1
  94. package/dist/managers/DocumentLoaderManager.js +3 -3
  95. package/dist/managers/TableSelectionManager.js +1 -1
  96. package/dist/managers/editorShortcuts.js +1 -1
  97. package/dist/markdown/fromMarkdown.js +1 -1
  98. package/dist/markdown/index.js +1 -1
  99. package/dist/markdown/renderRuns.js +1 -1
  100. package/dist/markdown/renderTable.js +1 -1
  101. package/dist/model.d.ts +3 -3
  102. package/dist/model.js +3 -3
  103. package/dist/prosemirror/attrs/index.d.ts +4 -2
  104. package/dist/prosemirror/attrs/index.js +17 -2
  105. package/dist/prosemirror/commands/comments.js +3 -3
  106. package/dist/prosemirror/commands/contentControls.js +1 -1
  107. package/dist/prosemirror/commands/contentControlsBlockFill.js +1 -1
  108. package/dist/prosemirror/commands/formatting.js +1 -1
  109. package/dist/prosemirror/commands/hyperlink.js +1 -1
  110. package/dist/prosemirror/commands/image.js +2 -2
  111. package/dist/prosemirror/commands/index.js +6 -6
  112. package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
  113. package/dist/prosemirror/commands/tableCellMergeResolution.js +1 -1
  114. package/dist/prosemirror/commentOps.js +1 -1
  115. package/dist/prosemirror/conversion/fromProseDoc.js +13 -9
  116. package/dist/prosemirror/conversion/index.js +1 -1
  117. package/dist/prosemirror/conversion/toProseDoc.js +9 -9
  118. package/dist/prosemirror/extensions/StarterKit.js +4 -4
  119. package/dist/prosemirror/extensions/core/ParagraphExtension.js +4 -4
  120. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +2 -2
  121. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -3
  122. package/dist/prosemirror/extensions/features/BidiShortcutExtension.js +2 -2
  123. package/dist/prosemirror/extensions/features/ContentControlWidgetsExtension.js +1 -1
  124. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +2 -2
  125. package/dist/prosemirror/extensions/features/ListExtension.js +3 -3
  126. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -1
  127. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +2 -2
  128. package/dist/prosemirror/extensions/features/PasteStyleInlinerExtension.js +1 -1
  129. package/dist/prosemirror/extensions/features/SelectionTrackerExtension.js +1 -1
  130. package/dist/prosemirror/extensions/marks/CharacterSpacingExtension.js +1 -1
  131. package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
  132. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +1 -1
  133. package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
  134. package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
  135. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
  136. package/dist/prosemirror/extensions/nodes/FieldExtension.js +1 -1
  137. package/dist/prosemirror/extensions/nodes/TabExtension.js +32 -9
  138. package/dist/prosemirror/extensions/nodes/TableExtension.js +1 -1
  139. package/dist/prosemirror/index.js +15 -15
  140. package/dist/prosemirror/insertOperations.js +3 -3
  141. package/dist/prosemirror/plugins/templateDirectives.js +1 -1
  142. package/dist/prosemirror/schema/index.d.ts +2 -2
  143. package/dist/prosemirror/schema/nodes.d.ts +4 -1
  144. package/dist/prosemirror/styles/styleResolver.js +1 -1
  145. package/dist/prosemirror/validation.js +5 -3
  146. package/dist/redline.js +1 -1
  147. package/dist/render-dom/BodySelectionOverlay.js +2 -2
  148. package/dist/server.js +15 -15
  149. package/dist/style-sets/extract.js +1 -1
  150. package/dist/types/content.d.ts +2 -2
  151. package/dist/types/documentEnumValues.d.ts +4 -1
  152. package/dist/types/documentEnumValues.js +14 -1
  153. package/dist/types/index.d.ts +2 -1
  154. package/dist/utils/formatToStyle.js +1 -1
  155. package/dist/version-comparison.js +2 -2
  156. package/package.json +2 -2
@@ -5,10 +5,10 @@ import { stripBlockIdentityAttrs } from "./block-identity.js";
5
5
  import { buildCleanBlockText } from "./clean-text.js";
6
6
  import { hasInlineEmphasis, parseInlineEmphasisRuns, stripInlineEmphasisMarkers } from "./inline-emphasis.js";
7
7
  import { hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
8
- import { planTableMutations } from "./table-mutation-plan.js";
9
- import { findEnclosingTableBoundary, findEnclosingTableCell, findEnclosingTableRow, tableRectangleCutsMergedCell } from "./table-targets.js";
10
8
  import { mergeTableRectangle, mergeTrackedVerticalTableCells, splitTableRectangle, splitTrackedVerticalTableCell } from "./table-cell-mutations.js";
9
+ import { planTableMutations } from "./table-mutation-plan.js";
11
10
  import { applyTableColumnDeletion, applyTableColumnInsertion, applyTableRowDeletion, applyTableRowInsertion, findTableColumnInsertion, findTableRowInsertion, getTableColumnCoordinateKey } from "./table-row-column-mutations.js";
11
+ import { findEnclosingTableBoundary, findEnclosingTableCell, findEnclosingTableRow, tableRectangleCutsMergedCell } from "./table-targets.js";
12
12
  import { diffWordSegments } from "./word-diff.js";
13
13
  import { TableMap } from "prosemirror-tables";
14
14
  //#region src/ai-edits/apply.ts
@@ -1,7 +1,7 @@
1
+ import { findParagraphByParaId } from "../prosemirror/utils/findParagraphByParaId.js";
1
2
  import { getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex } from "../types/block-id.js";
2
3
  import { buildCleanBlockText } from "./clean-text.js";
3
4
  import { createFolioAIEditSnapshot, hashFolioAIBlockText } from "./snapshot.js";
4
- import { findParagraphByParaId } from "../prosemirror/utils/findParagraphByParaId.js";
5
5
  //#region src/ai-edits/blockRange.ts
6
6
  const resolveFolioAIBlockRange = ({ blockId, doc, snapshot }) => {
7
7
  const paraId = getFolioParaIdFromBlockId(blockId);
@@ -1,19 +1,19 @@
1
- import { getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
2
- import { deterministicHexId } from "../utils/hexId.js";
3
- import { schema, singletonManager } from "../prosemirror/schema/index.js";
4
- import { footnoteToProseDoc, headerFooterToProseDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
5
- import { proseDocToBlocks, updateDocumentContent } from "../prosemirror/conversion/fromProseDoc.js";
6
- import { buildAnnotatedBlockText } from "./clean-text.js";
7
- import { createFolioAIEditSnapshot, normalizeFolioAIBlockText } from "./snapshot.js";
8
1
  import { applyFolioDocumentOperations } from "../document-operations.js";
9
2
  import { getEndnoteText, getFootnoteText, isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
10
3
  import { getHeaderFooterText } from "../docx/headerFooterParser.js";
11
4
  import { parseDocx } from "../docx/parser.js";
12
- import { repackDocx } from "../docx/rezip.js";
13
- import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
14
5
  import { createReply } from "../docx/replyToComment.js";
6
+ import { repackDocx } from "../docx/rezip.js";
15
7
  import { attemptSelectiveSave } from "../docx/selectiveSave.js";
16
8
  import { acceptAIEditRevision, acceptAllChanges, rejectAIEditRevision, rejectAllChanges } from "../prosemirror/commands/comments.js";
9
+ import { proseDocToBlocks, updateDocumentContent } from "../prosemirror/conversion/fromProseDoc.js";
10
+ import { footnoteToProseDoc, headerFooterToProseDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
11
+ import { getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
12
+ import { schema, singletonManager } from "../prosemirror/schema/index.js";
13
+ import { deterministicHexId } from "../utils/hexId.js";
14
+ import { buildAnnotatedBlockText } from "./clean-text.js";
15
+ import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
16
+ import { createFolioAIEditSnapshot, normalizeFolioAIBlockText } from "./snapshot.js";
17
17
  import { TaggedError } from "better-result";
18
18
  import { EditorState } from "prosemirror-state";
19
19
  //#region src/ai-edits/headless.ts
@@ -1,11 +1,11 @@
1
+ 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";
1
2
  import { getFolioParaIdFromBlockId } from "../types/block-id.js";
2
- import { buildAnnotatedBlockText } from "./clean-text.js";
3
- import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
4
- import { diffWordSegments } from "./word-diff.js";
5
3
  import { applyFolioAIEditOperations } from "./apply.js";
6
- 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";
7
4
  import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "./blockRange.js";
5
+ import { buildAnnotatedBlockText } from "./clean-text.js";
6
+ import { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, UnsupportedFolioReviewedViewError, isFolioResolvedReviewedView, isFolioReviewedView } from "./headless.js";
8
7
  import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
9
8
  import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
10
- import { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, UnsupportedFolioReviewedViewError, isFolioResolvedReviewedView, isFolioReviewedView } from "./headless.js";
9
+ import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
10
+ import { diffWordSegments } from "./word-diff.js";
11
11
  export { 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_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
@@ -1,6 +1,6 @@
1
1
  import { expectRunPropertyChangeMarkAttrs } from "../prosemirror/attrs/index.js";
2
- import { createFolioAIEditSnapshot } from "./snapshot.js";
3
2
  import { getTableCellMergeChange } from "../prosemirror/tableCellMergeRevision.js";
3
+ import { createFolioAIEditSnapshot } from "./snapshot.js";
4
4
  //#region src/ai-edits/read.ts
5
5
  /** Map each snapshot block's start position to its stable id. */
6
6
  const blockStartIdsFromDoc = (doc) => {
@@ -1,7 +1,7 @@
1
1
  import { expectTableCellAttrs } from "../prosemirror/attrs/index.js";
2
- import { markStructuralChange } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
3
- import { standaloneTableCellToProseMirror } from "../prosemirror/conversion/toProseDoc.js";
4
2
  import { standaloneTableCellFromProseMirror } from "../prosemirror/conversion/fromProseDoc.js";
3
+ import { standaloneTableCellToProseMirror } from "../prosemirror/conversion/toProseDoc.js";
4
+ import { markStructuralChange } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
5
5
  import { tableRectanglesEqual } from "./table-mutation-plan.js";
6
6
  import { tableRectangleCutsMergedCell } from "./table-targets.js";
7
7
  import { Result } from "better-result";
@@ -1,31 +1,31 @@
1
- import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
2
- import { deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
1
+ import { applyFolioAIEditOperations } from "../ai-edits/apply.js";
3
2
  import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "../ai-edits/snapshot.js";
4
3
  import { diffWordSegments } from "../ai-edits/word-diff.js";
5
- import { applyFolioAIEditOperations } from "../ai-edits/apply.js";
4
+ import { applySuggestions } from "../ai-suggestions/apply.js";
5
+ import { isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
6
+ import { buildPositionalText } from "../ai-suggestions/text-positions.js";
7
+ import { DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
6
8
  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";
7
- import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "../style-sets/types.js";
8
- import { createEmptyDocument } from "../utils/createDocument.js";
9
- import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
10
- import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
11
- import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
12
- import { createDocx } from "../docx/rezip.js";
13
9
  import { inspectDocxCompatibility } from "../docx/compatibility.js";
14
- import { DEFAULT_AI_SUGGESTION_PRESETS } from "../ai-suggestions/types.js";
15
- import { buildPositionalText } from "../ai-suggestions/text-positions.js";
16
- import { isSuggestionStale, resolveSuggestionAnchor } from "../ai-suggestions/conflict.js";
17
- import { applySuggestions } from "../ai-suggestions/apply.js";
18
- import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
10
+ import { createDocx } from "../docx/rezip.js";
11
+ import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
12
+ import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
13
+ import { fromMarkdown } from "../markdown/fromMarkdown.js";
14
+ import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
19
15
  import { scrollFolioPositionIntoView } from "../paged-layout/scrollToPmPosition.js";
20
16
  import { getFolioCaretViewportRect, getFolioSelectionViewportRect } from "../paged-layout/selectionViewportRect.js";
21
17
  import { createAICitationDecorationsPlugin, setAICitationsMeta, setActiveCitationMeta } from "../prosemirror/plugins/aiCitationDecorations.js";
18
+ import { setAISuggestionsMeta, setFocusedSuggestionMeta } from "../prosemirror/plugins/aiSuggestionDecorations.js";
22
19
  import { anonymizationDecorationsKey, getAnonymizationMatches, setAnonymizationTermsMeta } from "../prosemirror/plugins/anonymizationDecorations.js";
20
+ import { DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acceptAutocompleteWord, appendAutocompleteToken, autocompleteSuggestionKey, autocompleteSuggestionPlugin, clearAutocompleteSuggestion, finishAutocompleteSuggestion, getAutocompleteSuggestion, shouldTriggerAutocomplete, startAutocompleteSuggestion } from "../prosemirror/plugins/autocompleteSuggestion.js";
23
21
  import { getTemplateDirectives, scanDirectives } from "../prosemirror/plugins/templateDirectives.js";
24
22
  import { setTemplatePreviewValues } from "../prosemirror/plugins/templatePreviewValues.js";
25
23
  import { clearTemplateSlashMenu, consumeTemplateSlashQuery, getTemplateSlashMenu, resetTemplateSlashQuery, templateSlashMenuKey } from "../prosemirror/plugins/templateSlashMenu.js";
26
- import { DEFAULT_AUTOCOMPLETE_DEAD_ZONE_NODES, acceptAutocompleteSuggestion, acceptAutocompleteWord, appendAutocompleteToken, autocompleteSuggestionKey, autocompleteSuggestionPlugin, clearAutocompleteSuggestion, finishAutocompleteSuggestion, getAutocompleteSuggestion, shouldTriggerAutocomplete, startAutocompleteSuggestion } from "../prosemirror/plugins/autocompleteSuggestion.js";
27
- import { fromMarkdown } from "../markdown/fromMarkdown.js";
28
- import { toMarkdown, toMarkdownResult } from "../markdown/index.js";
29
- import { buildEmbeddedFontFamilyMap, extractEmbeddedFonts, getEmbeddedFontFaces, scopeEmbeddedFontFamily } from "../fonts/embeddedFonts.js";
30
- import { DOCX_CONFORMANCE_CLASSES } from "../index.js";
24
+ import { extractDocumentStyleSet, extractDocumentStyleSetFromDocx, inspectDocumentStyles, inspectDocumentStylesFromDocx } from "../style-sets/extract.js";
25
+ import { STELLA_STYLE_SET_NAME, createStellaStyleDocumentPreset, createStellaStyleSet } from "../style-sets/stellaStyle.js";
26
+ import { DOCUMENT_PRESET_VERSION, DOCUMENT_STYLE_SET_VERSION } from "../style-sets/types.js";
27
+ import { deriveBlockId, getFolioParaIdFromBlockId, isFolioBlockId, isSequentialFolioBlockId } from "../types/block-id.js";
28
+ import { createEmptyDocument } from "../utils/createDocument.js";
29
+ import { getGoogleFontsEnabled, setEmbeddedFontFamilyMap, setGoogleFontsEnabled } from "../utils/fontResolver.js";
30
+ import { mergeDocumentContent } from "../utils/mergeDocumentContent.js";
31
31
  export { 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, InvalidFolioDocumentOperationBatchError, STELLA_STYLE_SET_NAME, UnsupportedFolioDocumentOperationVersionError, acceptAutocompleteSuggestion, acceptAutocompleteWord, anonymizationDecorationsKey, appendAutocompleteToken, applyFolioAIEditOperations, applyFolioDocumentOperations, applySuggestions, assertSupportedFolioDocumentOperationVersion, autocompleteSuggestionKey, autocompleteSuggestionPlugin, buildEmbeddedFontFamilyMap, buildPositionalText, clearAutocompleteSuggestion, clearTemplateSlashMenu, consumeTemplateSlashQuery, createAICitationDecorationsPlugin, createDocx, createEmptyDocument, createFolioAIEditSnapshot, createStellaStyleDocumentPreset, createStellaStyleSet, deriveBlockId, diffWordSegments, extractDocumentStyleSet, extractDocumentStyleSetFromDocx, extractEmbeddedFonts, finishAutocompleteSuggestion, fromMarkdown, getAnonymizationMatches, getAutocompleteSuggestion, getEmbeddedFontFaces, getFolioCaretViewportRect, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getFolioSelectionViewportRect, getGoogleFontsEnabled, getTemplateDirectives, getTemplateSlashMenu, hashFolioAIBlockText, inspectDocumentStyles, inspectDocumentStylesFromDocx, inspectDocxCompatibility, 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,5 +1,5 @@
1
- import { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError } from "./errors.js";
2
1
  import { formatDate } from "../docx/fieldParser.js";
2
+ import { ContentControlBoundError, ContentControlLockedError, ContentControlTypeError } from "./errors.js";
3
3
  //#region src/content-controls/mutateContentControls.ts
4
4
  /**
5
5
  * Pure (immutable) write helpers for block-level content controls.
@@ -1,5 +1,5 @@
1
- import { CONTENT_CONTROL_WIDGET_EVENT_NAME, dispatchDatePick, dispatchDropdownPick, handleContentControlWidgetClick } from "../prosemirror/plugins/contentControlWidgets.js";
2
1
  import { Subscribable } from "../managers/Subscribable.js";
2
+ import { CONTENT_CONTROL_WIDGET_EVENT_NAME, dispatchDatePick, dispatchDropdownPick, handleContentControlWidgetClick } from "../prosemirror/plugins/contentControlWidgets.js";
3
3
  //#region src/controller/contentControlWidgetController.ts
4
4
  const CLOSED_SNAPSHOT = { status: "closed" };
5
5
  const PICKER_GAP_PX = 4;
@@ -1,12 +1,12 @@
1
+ import { clearHeaderFooterVerbatimXml } from "../docx/headerFooterVerbatim.js";
2
+ import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
3
+ import { headerFooterToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
1
4
  import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js";
5
+ import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
2
6
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
3
- import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
4
7
  import { ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
5
- import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
8
+ import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
6
9
  import { schema } from "../prosemirror/schema/index.js";
7
- import { headerFooterToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
8
- import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
9
- import { clearHeaderFooterVerbatimXml } from "../docx/headerFooterVerbatim.js";
10
10
  import { EditorState } from "prosemirror-state";
11
11
  import { EditorView } from "prosemirror-view";
12
12
  //#region src/controller/headerFooterEditorManager.ts
@@ -1,12 +1,12 @@
1
+ import { recordHiddenEditorPhase, recordHiddenEditorStateCreate } from "../layout-engine/layoutInstrumentation.js";
2
+ import { suppressHiddenEditorScrollToSelection } from "../paged-layout/hiddenEditorScroll.js";
3
+ import { isReadOnlyEditKey } from "../paged-layout/readOnlyEditAttempt.js";
4
+ import { createEmptyDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
1
5
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
2
- import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
3
6
  import { ensureParaIdsInDoc, ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
7
+ import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
4
8
  import { schema } from "../prosemirror/schema/index.js";
5
- import { createEmptyDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
6
9
  import { createHiddenEditorApi } from "./hiddenEditorApi.js";
7
- import { recordHiddenEditorPhase, recordHiddenEditorStateCreate } from "../layout-engine/layoutInstrumentation.js";
8
- import { suppressHiddenEditorScrollToSelection } from "../paged-layout/hiddenEditorScroll.js";
9
- import { isReadOnlyEditKey } from "../paged-layout/readOnlyEditAttempt.js";
10
10
  import { panic } from "better-result";
11
11
  import { EditorState } from "prosemirror-state";
12
12
  import { EditorView } from "prosemirror-view";
@@ -1,26 +1,26 @@
1
- import { getDocumentWatermark } from "../watermark/index.js";
2
- import "../layout-engine/types.js";
3
- import { resolveEffectiveParagraphSpacingTree } from "../layout-engine/paragraphSpacing.js";
4
- import { renderPages } from "../layout-painter/renderPage.js";
5
- import { templatePreviewValuesKey } from "../prosemirror/plugins/templatePreviewValues.js";
6
1
  import { resolveDocumentGridLinePitch } from "../docx/documentGrid.js";
7
- import { getMargins, getPageSize, twipsToPixels } from "../paged-layout/sectionGeometry.js";
8
- import { getColumns } from "../layout-bridge/sectionColumns.js";
9
- import { toFlowBlocks } from "../layout-bridge/convert/toFlowBlocks.js";
10
- import { recordLayoutComplete, recordLayoutError, recordLayoutPhase, recordLayoutStart } from "../layout-engine/layoutInstrumentation.js";
11
2
  import { buildBookmarkPageMap } from "../fields/bookmarkPages.js";
12
3
  import { buildBookmarkText } from "../fields/bookmarkText.js";
13
4
  import { buildHeaderFooterFieldValues, fieldValuesEqual, resolveFieldValues } from "../fields/resolveFieldValues.js";
14
5
  import { buildSectionPageCounts } from "../fields/sectionPageCounts.js";
15
6
  import { buildSeqValues } from "../fields/seqValues.js";
16
- import { installCanvasMeasureProvider } from "../layout-engine/measure/measureContainer.js";
17
7
  import { buildFootnoteContentMap, collectEndnoteRefs, collectFootnoteRefs, computeNoteDisplayNumbers, remapNoteMarkerText } from "../layout-bridge/convert/footnoteLayout.js";
18
8
  import { applyTemplatePreviewToBlocks } from "../layout-bridge/convert/templatePreviewFlow.js";
9
+ import { toFlowBlocks } from "../layout-bridge/convert/toFlowBlocks.js";
10
+ import { getColumns } from "../layout-bridge/sectionColumns.js";
19
11
  import { layoutDocument } from "../layout-engine/index.js";
20
12
  import { resolveJustificationCompatibility } from "../layout-engine/justificationCompatibility.js";
13
+ import { recordLayoutComplete, recordLayoutError, recordLayoutPhase, recordLayoutStart } from "../layout-engine/layoutInstrumentation.js";
21
14
  import { measureBlocks, measureSingleBlockWithoutFloatingZones } from "../layout-engine/measure/measureBlocks.js";
15
+ import { installCanvasMeasureProvider } from "../layout-engine/measure/measureContainer.js";
16
+ import { resolveEffectiveParagraphSpacingTree } from "../layout-engine/paragraphSpacing.js";
17
+ import "../layout-engine/types.js";
18
+ import { renderPages } from "../layout-painter/renderPage.js";
22
19
  import { tryBuildIncrementalMeasures } from "../paged-layout/incrementalMeasure.js";
23
20
  import { computePerBlockMeasureInputs } from "../paged-layout/sectionBlockWidths.js";
21
+ import { getMargins, getPageSize, twipsToPixels } from "../paged-layout/sectionGeometry.js";
22
+ import { templatePreviewValuesKey } from "../prosemirror/plugins/templatePreviewValues.js";
23
+ import { getDocumentWatermark } from "../watermark/index.js";
24
24
  //#region src/controller/layoutPipeline.ts
25
25
  function bodyMarginsClearHeaderFooter({ authoredMargins, preparedHeader, preparedFooter }) {
26
26
  const headerBottom = preparedHeader ? (authoredMargins.header ?? 0) + (preparedHeader.marginPushBottom ?? preparedHeader.height) : authoredMargins.top;
@@ -1,12 +1,12 @@
1
+ import { isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
2
+ import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
3
+ import { footnoteToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
1
4
  import { ExtensionManager } from "../prosemirror/extensions/ExtensionManager.js";
5
+ import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
2
6
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
3
- import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
4
7
  import { ensureParaIdsInState } from "../prosemirror/extensions/features/ParaIdAllocatorExtension.js";
5
- import { createStarterKit } from "../prosemirror/extensions/StarterKit.js";
8
+ import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
6
9
  import { schema } from "../prosemirror/schema/index.js";
7
- import { footnoteToProseDoc } from "../prosemirror/conversion/toProseDoc.js";
8
- import { proseDocToBlocks } from "../prosemirror/conversion/fromProseDoc.js";
9
- import { isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
10
10
  import { EditorState } from "prosemirror-state";
11
11
  import { EditorView } from "prosemirror-view";
12
12
  //#region src/controller/noteEditorManager.ts
@@ -1,12 +1,12 @@
1
- import { elementToXml, findChild, getChildElements, getLocalName, mergeXmlnsDeclarations } from "./xmlParser.js";
2
- import { padDecimal } from "./numberingParser.js";
3
1
  import { parseBookmarkEnd, parseBookmarkStart } from "./bookmarkParser.js";
4
- import { parseSdtProperties } from "./sdtProperties.js";
5
- import { parseParagraph } from "./paragraphParser.js";
6
2
  import { appendBookmarkMarkerToLastParagraphInBlocks, prependBookmarkMarkersToFirstParagraphInBlocks } from "./bookmarkPlacement.js";
7
3
  import { convertBulletToUnicode } from "./bulletMarkers.js";
4
+ import { padDecimal } from "./numberingParser.js";
5
+ import { parseParagraph } from "./paragraphParser.js";
8
6
  import { enrichParagraphTextBoxes } from "./paragraphTextBoxEnrichment.js";
7
+ import { parseSdtProperties } from "./sdtProperties.js";
9
8
  import { parseTable } from "./tableParser.js";
9
+ import { elementToXml, findChild, getChildElements, getLocalName, mergeXmlnsDeclarations } from "./xmlParser.js";
10
10
  //#region src/docx/blockContentParser.ts
11
11
  const toRoman = (numParam) => {
12
12
  let num = numParam;
@@ -1,6 +1,26 @@
1
- import { findChild, getAttribute, getChildElements, parseXml } from "./xmlParser.js";
2
1
  import { parseParagraph } from "./paragraphParser.js";
2
+ import { parseRunProperties } from "./runParser.js";
3
+ import { findChild, getAttribute, getChildElements, getLocalName, parseXml } from "./xmlParser.js";
3
4
  //#region src/docx/commentParser.ts
5
+ const DEFAULT_ANNOTATION_REFERENCE_STYLE_ID = "CommentReference";
6
+ const normalizeAnnotationReferenceFormatting = (formatting) => {
7
+ if (formatting?.styleId === DEFAULT_ANNOTATION_REFERENCE_STYLE_ID && Object.keys(formatting).length === 1) return;
8
+ return formatting;
9
+ };
10
+ const normalizeFirstCommentParagraph = (paragraphElement, paragraph, theme) => {
11
+ const firstContentElement = getChildElements(paragraphElement).find((element) => getLocalName(element.name) !== "pPr");
12
+ if (!firstContentElement || getLocalName(firstContentElement.name) !== "r" || !findChild(firstContentElement, "w", "annotationRef")) return { paragraph };
13
+ const runProperties = findChild(firstContentElement, "w", "rPr");
14
+ const annotationReferenceFormatting = normalizeAnnotationReferenceFormatting(runProperties ? parseRunProperties(runProperties, theme) : void 0);
15
+ const firstParsedContent = paragraph.content.at(0);
16
+ return {
17
+ paragraph: firstParsedContent?.type === "run" && firstParsedContent.content.length === 0 ? {
18
+ ...paragraph,
19
+ content: paragraph.content.slice(1)
20
+ } : paragraph,
21
+ ...annotationReferenceFormatting !== void 0 ? { annotationReferenceFormatting } : {}
22
+ };
23
+ };
4
24
  /**
5
25
  * Build a lookup from paraId → dateUtc from commentsExtensible.xml
6
26
  *
@@ -91,9 +111,16 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
91
111
  const date = (paraId ? dateUtcByParaId.get(paraId) : void 0) ?? localDate;
92
112
  const done = (paraId ? extendedByParaId.get(paraId) : void 0)?.done;
93
113
  const paragraphs = [];
114
+ let annotationReferenceFormatting;
94
115
  for (const contentChild of getChildElements(child)) if ((contentChild.name?.replace(/^.*:/u, "") ?? "") === "p") {
95
116
  const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media);
96
- paragraphs.push(paragraph);
117
+ if (paragraphs.length > 0) {
118
+ paragraphs.push(paragraph);
119
+ continue;
120
+ }
121
+ const normalized = normalizeFirstCommentParagraph(contentChild, paragraph, theme);
122
+ annotationReferenceFormatting = normalized.annotationReferenceFormatting;
123
+ paragraphs.push(normalized.paragraph);
97
124
  }
98
125
  const commentIndex = comments.length;
99
126
  if (paraId) {
@@ -106,6 +133,7 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
106
133
  ...initials !== void 0 ? { initials } : {},
107
134
  ...date !== void 0 ? { date } : {},
108
135
  ...done !== void 0 ? { done } : {},
136
+ ...annotationReferenceFormatting !== void 0 ? { annotationReferenceFormatting } : {},
109
137
  content: paragraphs
110
138
  });
111
139
  }
@@ -1,8 +1,8 @@
1
- import { collectXmlnsDeclarations, findChild, parseXml } from "./xmlParser.js";
2
- import { getDefaultSectionProperties, parseSectionProperties } from "./sectionParser.js";
3
- import { getParagraphText } from "./paragraphParser.js";
4
1
  import { parseBlockContent } from "./blockContentParser.js";
2
+ import { getParagraphText } from "./paragraphParser.js";
3
+ import { getDefaultSectionProperties, parseSectionProperties } from "./sectionParser.js";
5
4
  import { parseStreamingXml } from "./streamingXmlParser.js";
5
+ import { collectXmlnsDeclarations, findChild, getLocalName, parseXml } from "./xmlParser.js";
6
6
  //#region src/docx/documentParser.ts
7
7
  /**
8
8
  * Regular expression to match template variables {{...}}
@@ -86,6 +86,29 @@ function buildSections(content, finalSectPr) {
86
86
  return sections;
87
87
  }
88
88
  /**
89
+ * Some producers place the body-level sectPr before all content. Consumers
90
+ * apply section properties in source order, but canonical serialization moves
91
+ * the body-level sectPr to the end and would therefore reverse the effective
92
+ * formats around paragraph section breaks.
93
+ *
94
+ * Rotate that leading property through the canonical paragraph-break slots so
95
+ * serialization repairs the element order without changing the observed
96
+ * section sequence.
97
+ */
98
+ function canonicalizeLeadingBodySectionProperties(bodyElement, body) {
99
+ const firstBodyChild = bodyElement.elements?.find(({ type }) => type === "element");
100
+ if (getLocalName(firstBodyChild?.name) !== "sectPr" || body.finalSectionProperties === void 0) return;
101
+ const sectionBreakParagraphs = body.content.filter((block) => block.type === "paragraph" && block.sectionProperties !== void 0);
102
+ if (sectionBreakParagraphs.length === 0) return;
103
+ let nextProperties = body.finalSectionProperties;
104
+ for (const paragraph of sectionBreakParagraphs) {
105
+ const currentProperties = paragraph.sectionProperties;
106
+ paragraph.sectionProperties = nextProperties;
107
+ nextProperties = currentProperties;
108
+ }
109
+ body.finalSectionProperties = nextProperties;
110
+ }
111
+ /**
89
112
  * Parse document.xml body content
90
113
  *
91
114
  * @param xml - Raw XML content of document.xml
@@ -107,6 +130,7 @@ function parseDocumentBody(xml, styles = null, theme = null, numbering = null, r
107
130
  result.content = parseBlockContent(bodyEl, styles, theme, numbering, rels, media, { rootXmlns: collectXmlnsDeclarations(documentEl) });
108
131
  const finalSectPr = findChild(bodyEl, "w", "sectPr");
109
132
  if (finalSectPr) result.finalSectionProperties = parseSectionProperties(finalSectPr);
133
+ canonicalizeLeadingBodySectionProperties(bodyEl, result);
110
134
  result.sections = buildSections(result.content, result.finalSectionProperties);
111
135
  return result;
112
136
  }
@@ -0,0 +1,5 @@
1
+ import { DocxParagraphSurfaces } from "./paragraphTraversal.js";
2
+ //#region src/docx/drawingIdNormalization.d.ts
3
+ declare const normalizeDrawingIds: (surfaces: DocxParagraphSurfaces) => void;
4
+ //#endregion
5
+ export { normalizeDrawingIds };
@@ -0,0 +1,35 @@
1
+ import { visitDocxParagraphs, visitParagraphRuns } from "./paragraphTraversal.js";
2
+ //#region src/docx/drawingIdNormalization.ts
3
+ const GENERATED_DRAWING_ID_START = 1e5;
4
+ const needsGeneratedId = ({ id }) => id === void 0 || id === "" || id === "0";
5
+ const normalizeDrawingIds = (surfaces) => {
6
+ const entries = [];
7
+ visitDocxParagraphs(surfaces, (paragraph) => {
8
+ visitParagraphRuns(paragraph, (run) => {
9
+ for (const content of run.content) {
10
+ if (content.type === "shape") {
11
+ entries.push({
12
+ drawing: content.shape,
13
+ generateWhenMissing: true
14
+ });
15
+ continue;
16
+ }
17
+ if (content.type === "drawing") entries.push({
18
+ drawing: content.image,
19
+ generateWhenMissing: content.rawXml === void 0
20
+ });
21
+ }
22
+ });
23
+ });
24
+ const usedIds = new Set(entries.flatMap(({ drawing }) => needsGeneratedId(drawing) ? [] : [drawing.id]));
25
+ let nextId = GENERATED_DRAWING_ID_START;
26
+ for (const { drawing, generateWhenMissing } of entries) {
27
+ if (!generateWhenMissing || !needsGeneratedId(drawing)) continue;
28
+ while (usedIds.has(String(nextId))) nextId += 1;
29
+ drawing.id = String(nextId);
30
+ usedIds.add(drawing.id);
31
+ nextId += 1;
32
+ }
33
+ };
34
+ //#endregion
35
+ export { normalizeDrawingIds };
@@ -48,7 +48,7 @@ declare function parsePositionV(posV: XmlElement | null): document_d_exports.Ima
48
48
  /**
49
49
  * Parse position for anchored drawings (combines positionH + positionV).
50
50
  */
51
- declare function parseAnchorPosition(anchor: XmlElement): document_d_exports.ImagePosition | undefined;
51
+ declare function parseAnchorPosition(anchor: XmlElement): document_d_exports.ImagePosition;
52
52
  /** Known wrap element names */
53
53
  declare const WRAP_ELEMENT_NAMES: string[];
54
54
  /**