@stll/folio-core 0.52.0 → 0.54.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 (389) hide show
  1. package/README.md +23 -0
  2. package/dist/ai-edits/apply.d.ts +26 -1
  3. package/dist/ai-edits/apply.js +1779 -141
  4. package/dist/ai-edits/batch-claims.d.ts +145 -0
  5. package/dist/ai-edits/batch-claims.js +275 -0
  6. package/dist/ai-edits/blockRange.js +9 -3
  7. package/dist/ai-edits/character-boundaries.d.ts +43 -0
  8. package/dist/ai-edits/character-boundaries.js +95 -0
  9. package/dist/ai-edits/clean-text.d.ts +33 -3
  10. package/dist/ai-edits/clean-text.js +52 -6
  11. package/dist/ai-edits/comment-lifecycle.d.ts +18 -0
  12. package/dist/ai-edits/comment-lifecycle.js +52 -0
  13. package/dist/ai-edits/headless.d.ts +91 -7
  14. package/dist/ai-edits/headless.js +520 -51
  15. package/dist/ai-edits/index.d.ts +2 -1
  16. package/dist/ai-edits/index.js +2 -1
  17. package/dist/ai-edits/minimal-replacement.d.ts +21 -6
  18. package/dist/ai-edits/minimal-replacement.js +134 -15
  19. package/dist/ai-edits/newListNumbering.d.ts +23 -0
  20. package/dist/ai-edits/newListNumbering.js +94 -0
  21. package/dist/ai-edits/note-references.d.ts +96 -0
  22. package/dist/ai-edits/note-references.js +139 -0
  23. package/dist/ai-edits/pending-suggestions.d.ts +79 -0
  24. package/dist/ai-edits/pending-suggestions.js +306 -0
  25. package/dist/ai-edits/read.d.ts +6 -4
  26. package/dist/ai-edits/read.js +113 -50
  27. package/dist/ai-edits/result-validation.d.ts +29 -0
  28. package/dist/ai-edits/result-validation.js +164 -0
  29. package/dist/ai-edits/revisionStretches.d.ts +17 -0
  30. package/dist/ai-edits/revisionStretches.js +80 -0
  31. package/dist/ai-edits/snapshot.d.ts +36 -3
  32. package/dist/ai-edits/snapshot.js +180 -25
  33. package/dist/ai-edits/table-cell-mutations.d.ts +4 -2
  34. package/dist/ai-edits/table-cell-mutations.js +6 -2
  35. package/dist/ai-edits/table-geometry.d.ts +1 -1
  36. package/dist/ai-edits/table-row-column-mutations.d.ts +44 -17
  37. package/dist/ai-edits/table-row-column-mutations.js +86 -34
  38. package/dist/ai-edits/types.d.ts +155 -16
  39. package/dist/compare/compare.d.ts +1 -1
  40. package/dist/compare/compare.js +65 -16
  41. package/dist/compare/content-alignment.d.ts +5 -1
  42. package/dist/compare/content-alignment.js +52 -34
  43. package/dist/compare/content-types.d.ts +7 -0
  44. package/dist/compare/content.d.ts +4 -1
  45. package/dist/compare/content.js +6 -1
  46. package/dist/compare/formatting.js +2 -1
  47. package/dist/compare/inline-atoms.d.ts +21 -4
  48. package/dist/compare/inline-atoms.js +138 -16
  49. package/dist/compare/inline-provenance.js +1 -1
  50. package/dist/compare/plan.js +10 -5
  51. package/dist/compare/scenario.js +14 -3
  52. package/dist/compare/section-boundary-properties.js +1 -1
  53. package/dist/compare/types.d.ts +4 -2
  54. package/dist/compare/types.js +2 -1
  55. package/dist/compare/verification.d.ts +1 -1
  56. package/dist/compare/verification.js +15 -3
  57. package/dist/controller/committedLayoutDiff.d.ts +25 -0
  58. package/dist/controller/committedLayoutDiff.js +71 -0
  59. package/dist/controller/contentControlWidgetController.d.ts +1 -1
  60. package/dist/controller/folioEditor.d.ts +1 -1
  61. package/dist/controller/fontReadiness.d.ts +70 -3
  62. package/dist/controller/fontReadiness.js +100 -10
  63. package/dist/controller/headerFooterEditorManager.js +6 -1
  64. package/dist/controller/layoutPipeline.d.ts +12 -10
  65. package/dist/controller/layoutPipeline.js +65 -11
  66. package/dist/controller/layoutRunOptions.d.ts +24 -0
  67. package/dist/controller/layoutRunOptions.js +17 -0
  68. package/dist/controller/layoutScheduler.d.ts +19 -14
  69. package/dist/controller/layoutScheduler.js +15 -12
  70. package/dist/controller/layoutSession.d.ts +26 -2
  71. package/dist/controller/layoutSession.js +1 -1
  72. package/dist/controller/noteEditorManager.js +8 -3
  73. package/dist/document-operations.d.ts +11 -2
  74. package/dist/document-operations.js +230 -21
  75. package/dist/docx/altChunk.d.ts +8 -0
  76. package/dist/docx/altChunk.js +17 -0
  77. package/dist/docx/archiveInflation.d.ts +127 -0
  78. package/dist/docx/archiveInflation.js +181 -0
  79. package/dist/docx/attributeRemainder.d.ts +1 -1
  80. package/dist/docx/blockContentParser.d.ts +64 -1
  81. package/dist/docx/blockContentParser.js +17 -4
  82. package/dist/docx/blockCustomXmlShell.d.ts +7 -0
  83. package/dist/docx/blockCustomXmlShell.js +14 -0
  84. package/dist/docx/blockPlainText.js +7 -0
  85. package/dist/docx/commentAnchorIndex.js +1 -1
  86. package/dist/docx/commentRangeIntegrity.js +8 -3
  87. package/dist/docx/commentReferenceNormalization.js +1 -1
  88. package/dist/docx/commentReplyMarkers.js +20 -1
  89. package/dist/docx/compatibility.d.ts +1 -1
  90. package/dist/docx/compatibility.js +34 -13
  91. package/dist/docx/containerChildren.gen.d.ts +1 -1
  92. package/dist/docx/containerChildren.gen.js +1 -0
  93. package/dist/docx/documentParser.js +12 -12
  94. package/dist/docx/drawingIdNormalization.d.ts +3 -1
  95. package/dist/docx/drawingIdNormalization.js +6 -1
  96. package/dist/docx/ensureParaIds.js +119 -97
  97. package/dist/docx/footnoteParser.js +8 -4
  98. package/dist/docx/headerFooterParser.js +3 -3
  99. package/dist/docx/headerFooterReferenceNormalization.d.ts +20 -1
  100. package/dist/docx/headerFooterReferenceNormalization.js +52 -27
  101. package/dist/docx/hyperlinkParser.d.ts +1 -1
  102. package/dist/docx/index.d.ts +1 -1
  103. package/dist/docx/listNumberingInstances.d.ts +59 -0
  104. package/dist/docx/listNumberingInstances.js +249 -0
  105. package/dist/docx/metadataPrivacy.js +24 -1
  106. package/dist/docx/normalizeBaseDirection.js +2 -1
  107. package/dist/docx/noteReferenceMark.d.ts +15 -0
  108. package/dist/docx/noteReferenceMark.js +48 -0
  109. package/dist/docx/opaqueCarrier.d.ts +7 -0
  110. package/dist/docx/opaqueCarrier.js +38 -0
  111. package/dist/docx/packageParts.js +4 -1
  112. package/dist/docx/paragraphParser.js +96 -27
  113. package/dist/docx/paragraphPropertySource.d.ts +4 -2
  114. package/dist/docx/paragraphPropertySource.js +10 -2
  115. package/dist/docx/paragraphTraversal.js +1 -0
  116. package/dist/docx/parseWarningMessage.js +4 -1
  117. package/dist/docx/parser.js +175 -22
  118. package/dist/docx/rezip.js +31 -7
  119. package/dist/docx/sdtProperties.js +1 -1
  120. package/dist/docx/sdtPropertiesPatch.js +3 -0
  121. package/dist/docx/selectiveSave.js +16 -9
  122. package/dist/docx/selectiveXmlPatch.d.ts +3 -1
  123. package/dist/docx/selectiveXmlPatch.js +186 -39
  124. package/dist/docx/serializer/blockCustomXmlSerializer.d.ts +5 -0
  125. package/dist/docx/serializer/blockCustomXmlSerializer.js +4 -0
  126. package/dist/docx/serializer/documentSerializer.js +2 -0
  127. package/dist/docx/serializer/headerFooterSerializer.js +2 -0
  128. package/dist/docx/serializer/noteSerializer.js +3 -1
  129. package/dist/docx/serializer/paragraphSerializer.js +33 -9
  130. package/dist/docx/serializer/tableSerializer.js +25 -38
  131. package/dist/docx/server/boundedArchive.d.ts +8 -13
  132. package/dist/docx/server/boundedArchive.js +70 -59
  133. package/dist/docx/server/createBilingualDocument.js +3 -3
  134. package/dist/docx/server/extractDocxText.d.ts +8 -2
  135. package/dist/docx/server/extractDocxText.js +2 -2
  136. package/dist/docx/server/validateDocxConformance.d.ts +1 -1
  137. package/dist/docx/server/validateDocxConformance.js +1 -0
  138. package/dist/docx/tableParser.d.ts +157 -1
  139. package/dist/docx/tableParser.js +89 -10
  140. package/dist/docx/textBoxParser.js +1 -1
  141. package/dist/docx/unzip.d.ts +20 -2
  142. package/dist/docx/unzip.js +136 -25
  143. package/dist/docx/wordprocessingPrefixes.d.ts +78 -0
  144. package/dist/docx/wordprocessingPrefixes.js +286 -0
  145. package/dist/fonts/embeddedFonts.js +1 -1
  146. package/dist/i18n/messages/catalogs.gen.d.ts +170 -34
  147. package/dist/i18n/messages/catalogs.gen.js +187 -51
  148. package/dist/i18n/messages/messages.gen.d.ts +10 -2
  149. package/dist/internal/compare/inline-presentation.d.ts +2 -1
  150. package/dist/internal/compare/inline-presentation.js +11 -10
  151. package/dist/internal/headlessRevisionResolutionGuard.d.ts +2 -8
  152. package/dist/internal/headlessRevisionResolutionGuard.js +2 -11
  153. package/dist/internal/indexedPositionMap.d.ts +11 -0
  154. package/dist/internal/indexedPositionMap.js +42 -0
  155. package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
  156. package/dist/internal/revisionResolutionEdits.d.ts +13 -0
  157. package/dist/internal/revisionResolutionEdits.js +19 -0
  158. package/dist/internal/revisionResolutionInline.d.ts +24 -0
  159. package/dist/internal/{headlessRevisionResolution.js → revisionResolutionInline.js} +61 -43
  160. package/dist/internal/revisionResolutionStep.d.ts +34 -0
  161. package/dist/internal/revisionResolutionStep.js +282 -0
  162. package/dist/internal/revisionResolutionTracking.d.ts +11 -0
  163. package/dist/internal/revisionResolutionTracking.js +124 -0
  164. package/dist/internal/wholeStoryRevisionResolution.d.ts +56 -0
  165. package/dist/internal/wholeStoryRevisionResolution.js +600 -0
  166. package/dist/layout-bridge/convert/markupViewFlow.d.ts +20 -0
  167. package/dist/layout-bridge/convert/markupViewFlow.js +123 -0
  168. package/dist/layout-bridge/convert/tableConversion.js +1 -1
  169. package/dist/layout-bridge/convert/toFlowBlocks.js +10 -1
  170. package/dist/layout-engine/layoutInstrumentation.d.ts +9 -1
  171. package/dist/layout-engine/layoutInstrumentation.js +4 -1
  172. package/dist/layout-engine/measure/cache.d.ts +18 -1
  173. package/dist/layout-engine/measure/cache.js +31 -1
  174. package/dist/layout-engine/measure/font-metrics.worker.js +3 -7
  175. package/dist/layout-engine/measure/measureContainer.js +7 -47
  176. package/dist/layout-engine/measure/measureHelpers.d.ts +6 -1
  177. package/dist/layout-engine/measure/measureHelpers.js +22 -2
  178. package/dist/layout-engine/measure/measureParagraph.js +2 -2
  179. package/dist/layout-engine/measure/measureWorker.js +2 -3
  180. package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +6 -7
  181. package/dist/layout-engine/measure/measureWorkerProtocol.js +1 -2
  182. package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +12 -1
  183. package/dist/layout-engine/measure/paragraphMeasureShared.js +14 -1
  184. package/dist/layout-engine/types.d.ts +6 -0
  185. package/dist/layout-painter/renderPage.js +1 -0
  186. package/dist/layout-painter/renderParagraph.js +1 -1
  187. package/dist/managers/ContextMenuManager.js +5 -2
  188. package/dist/managers/types.d.ts +3 -0
  189. package/dist/markdown/escape.d.ts +2 -2
  190. package/dist/markdown/escape.js +4 -5
  191. package/dist/markdown/fromMarkdown.js +2 -1
  192. package/dist/markdown/internals.d.ts +11 -1
  193. package/dist/markdown/internals.js +24 -3
  194. package/dist/markdown/renderBlock.js +121 -25
  195. package/dist/markdown/renderParagraph.d.ts +13 -1
  196. package/dist/markdown/renderParagraph.js +85 -38
  197. package/dist/markdown/renderRuns.d.ts +10 -1
  198. package/dist/markdown/renderRuns.js +323 -69
  199. package/dist/markdown/renderTable.js +24 -12
  200. package/dist/markdown/trailers.js +2 -2
  201. package/dist/markdown/types.d.ts +29 -7
  202. package/dist/paged-layout/incrementalMeasure.d.ts +1 -2
  203. package/dist/paged-layout/incrementalMeasure.js +1 -9
  204. package/dist/paged-layout/transactionDirtyRange.d.ts +1 -3
  205. package/dist/paged-layout/transactionDirtyRange.js +29 -41
  206. package/dist/panel-layout.d.ts +83 -0
  207. package/dist/panel-layout.js +96 -0
  208. package/dist/prosemirror/anchoredTextBoxes.d.ts +37 -0
  209. package/dist/prosemirror/anchoredTextBoxes.js +156 -0
  210. package/dist/prosemirror/attrs/index.d.ts +6 -2
  211. package/dist/prosemirror/attrs/index.js +172 -1
  212. package/dist/prosemirror/clearRunColor.d.ts +6 -0
  213. package/dist/prosemirror/clearRunColor.js +46 -0
  214. package/dist/prosemirror/commands/comments.d.ts +7 -8
  215. package/dist/prosemirror/commands/comments.js +281 -212
  216. package/dist/prosemirror/commands/contentControls.d.ts +1 -1
  217. package/dist/prosemirror/commands/formatPainter.d.ts +1 -1
  218. package/dist/prosemirror/commands/formatPainter.js +1 -1
  219. package/dist/prosemirror/commands/formatting.d.ts +1 -1
  220. package/dist/prosemirror/commands/hyperlink.js +2 -1
  221. package/dist/prosemirror/commands/index.d.ts +2 -2
  222. package/dist/prosemirror/commands/index.js +2 -2
  223. package/dist/prosemirror/commands/paragraph.d.ts +7 -1
  224. package/dist/prosemirror/commands/paragraph.js +9 -1
  225. package/dist/prosemirror/commands/paragraphBookmarkJoin.d.ts +13 -0
  226. package/dist/prosemirror/commands/paragraphBookmarkJoin.js +22 -0
  227. package/dist/prosemirror/commands/pastePlainText.d.ts +1 -1
  228. package/dist/prosemirror/commands/propertyChangeScope.d.ts +3 -2
  229. package/dist/prosemirror/commands/propertyChangeScope.js +24 -3
  230. package/dist/prosemirror/commands/resolveAllTableChanges.d.ts +40 -0
  231. package/dist/prosemirror/commands/resolveAllTableChanges.js +620 -0
  232. package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.d.ts +15 -0
  233. package/dist/prosemirror/commands/resolveNodePropertyChangeAttrs.js +46 -0
  234. package/dist/prosemirror/commands/resolveParagraphProperties.d.ts +16 -0
  235. package/dist/prosemirror/commands/resolveParagraphProperties.js +73 -0
  236. package/dist/prosemirror/commands/sectionBreak.js +2 -1
  237. package/dist/prosemirror/commands/tableCellMergeResolution.d.ts +15 -2
  238. package/dist/prosemirror/commands/tableCellMergeResolution.js +23 -7
  239. package/dist/prosemirror/containerFinalParagraph.d.ts +11 -5
  240. package/dist/prosemirror/containerFinalParagraph.js +7 -6
  241. package/dist/prosemirror/contentControlRevisions.d.ts +1 -1
  242. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  243. package/dist/prosemirror/conversion/fromProseDoc.js +177 -605
  244. package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -11
  245. package/dist/prosemirror/conversion/toProseDoc.js +70 -154
  246. package/dist/prosemirror/documentSchema.d.ts +8 -0
  247. package/dist/prosemirror/documentSchema.js +18 -0
  248. package/dist/prosemirror/emptyFieldResultRuns.d.ts +18 -0
  249. package/dist/prosemirror/emptyFieldResultRuns.js +33 -0
  250. package/dist/prosemirror/extensions/ExtensionManager.d.ts +1 -1
  251. package/dist/prosemirror/extensions/ExtensionManager.js +3 -1
  252. package/dist/prosemirror/extensions/StarterKit.js +5 -1
  253. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  254. package/dist/prosemirror/extensions/core/ParagraphExtension.js +116 -63
  255. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +4 -1
  256. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +24 -3
  257. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.d.ts +20 -0
  258. package/dist/prosemirror/extensions/features/JoinedRunStyleExtension.js +43 -0
  259. package/dist/prosemirror/extensions/features/ListExtension.js +167 -128
  260. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.d.ts +19 -2
  261. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +33 -20
  262. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +31 -2
  263. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +270 -99
  264. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +3 -2
  265. package/dist/prosemirror/extensions/features/pasteCleanup.js +2 -1
  266. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +1 -1
  267. package/dist/prosemirror/extensions/features/pastedHtmlLists.d.ts +12 -0
  268. package/dist/prosemirror/extensions/features/pastedHtmlLists.js +124 -0
  269. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +33 -11
  270. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +8 -4
  271. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +21 -18
  272. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +37 -17
  273. package/dist/prosemirror/extensions/marks/StrikeExtension.js +2 -2
  274. package/dist/prosemirror/extensions/marks/SubscriptExtension.js +2 -2
  275. package/dist/prosemirror/extensions/marks/SuperscriptExtension.js +2 -2
  276. package/dist/prosemirror/extensions/marks/TextColorExtension.js +4 -3
  277. package/dist/prosemirror/extensions/marks/markUtils.d.ts +15 -8
  278. package/dist/prosemirror/extensions/marks/markUtils.js +25 -10
  279. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.d.ts +12 -0
  280. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +46 -0
  281. package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.d.ts +6 -0
  282. package/dist/prosemirror/extensions/nodes/BlockCustomXmlExtension.js +52 -0
  283. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +2 -2
  284. package/dist/prosemirror/extensions/nodes/FieldExtension.d.ts +3 -3
  285. package/dist/prosemirror/extensions/nodes/FieldExtension.js +50 -15
  286. package/dist/prosemirror/extensions/nodes/HardBreakExtension.js +5 -3
  287. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +4 -1
  288. package/dist/prosemirror/extensions/nodes/TableExtension.d.ts +1 -1
  289. package/dist/prosemirror/extensions/nodes/TableExtension.js +121 -226
  290. package/dist/prosemirror/extensions/types.d.ts +11 -1
  291. package/dist/prosemirror/findReplaceSelection.js +1 -1
  292. package/dist/prosemirror/hyperlinkRemoval.d.ts +9 -0
  293. package/dist/prosemirror/hyperlinkRemoval.js +129 -0
  294. package/dist/prosemirror/index.d.ts +5 -3
  295. package/dist/prosemirror/index.js +5 -3
  296. package/dist/prosemirror/indexedNodeLookup.d.ts +17 -0
  297. package/dist/prosemirror/indexedNodeLookup.js +103 -0
  298. package/dist/prosemirror/listAutoformatMarkers.d.ts +19 -0
  299. package/dist/prosemirror/listAutoformatMarkers.js +98 -0
  300. package/dist/prosemirror/listInstanceReferences.d.ts +12 -0
  301. package/dist/prosemirror/listInstanceReferences.js +72 -0
  302. package/dist/prosemirror/listLabels.d.ts +24 -0
  303. package/dist/prosemirror/listLabels.js +111 -0
  304. package/dist/prosemirror/listNumbering.d.ts +92 -0
  305. package/dist/prosemirror/listNumbering.js +330 -0
  306. package/dist/prosemirror/listRendering.d.ts +27 -0
  307. package/dist/prosemirror/listRendering.js +27 -0
  308. package/dist/prosemirror/listRenderingAttrs.d.ts +11 -2
  309. package/dist/prosemirror/listRenderingAttrs.js +8 -1
  310. package/dist/prosemirror/markupViewNotes.d.ts +8 -0
  311. package/dist/prosemirror/markupViewNotes.js +49 -0
  312. package/dist/prosemirror/markupViewProjection.d.ts +97 -0
  313. package/dist/prosemirror/markupViewProjection.js +88 -0
  314. package/dist/prosemirror/noteReferenceReview.d.ts +77 -0
  315. package/dist/prosemirror/noteReferenceReview.js +332 -0
  316. package/dist/prosemirror/numberingAttr.d.ts +9 -1
  317. package/dist/prosemirror/numberingAttr.js +9 -1
  318. package/dist/prosemirror/outlineLevelAttr.js +1 -1
  319. package/dist/prosemirror/paragraphIndentation.d.ts +10 -1
  320. package/dist/prosemirror/paragraphIndentation.js +32 -7
  321. package/dist/prosemirror/paragraphMarkJoin.d.ts +21 -0
  322. package/dist/prosemirror/paragraphMarkJoin.js +26 -0
  323. package/dist/prosemirror/paragraphPropertyCarry.d.ts +64 -0
  324. package/dist/prosemirror/paragraphPropertyCarry.js +158 -0
  325. package/dist/prosemirror/plugins/createDocScanPlugin.d.ts +1 -1
  326. package/dist/prosemirror/plugins/documentNumbering.d.ts +27 -1
  327. package/dist/prosemirror/plugins/documentNumbering.js +97 -11
  328. package/dist/prosemirror/plugins/documentStyleState.d.ts +26 -0
  329. package/dist/prosemirror/plugins/documentStyleState.js +32 -0
  330. package/dist/prosemirror/plugins/documentStyles.d.ts +3 -13
  331. package/dist/prosemirror/plugins/documentStyles.js +67 -17
  332. package/dist/prosemirror/plugins/index.d.ts +2 -1
  333. package/dist/prosemirror/plugins/index.js +2 -1
  334. package/dist/prosemirror/plugins/paragraphStyleResolution.d.ts +15 -0
  335. package/dist/prosemirror/plugins/paragraphStyleResolution.js +230 -0
  336. package/dist/prosemirror/plugins/suggestionMode.d.ts +27 -3
  337. package/dist/prosemirror/plugins/suggestionMode.js +490 -63
  338. package/dist/prosemirror/plugins/templateDirectives.d.ts +1 -1
  339. package/dist/prosemirror/plugins/transactionInvariants.d.ts +32 -0
  340. package/dist/prosemirror/plugins/transactionInvariants.js +86 -0
  341. package/dist/prosemirror/positionSweep.d.ts +24 -0
  342. package/dist/prosemirror/positionSweep.js +222 -0
  343. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +23 -3
  344. package/dist/prosemirror/rebaseParagraphRunFormatting.js +39 -13
  345. package/dist/prosemirror/rebaseParagraphRuns.d.ts +36 -0
  346. package/dist/prosemirror/rebaseParagraphRuns.js +99 -0
  347. package/dist/prosemirror/rejoinRunCarriers.d.ts +1 -1
  348. package/dist/prosemirror/replacedAnnotations.d.ts +33 -1
  349. package/dist/prosemirror/replacedAnnotations.js +170 -1
  350. package/dist/prosemirror/runFormattingFromMarks.d.ts +18 -0
  351. package/dist/prosemirror/runFormattingFromMarks.js +567 -0
  352. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +1 -1
  353. package/dist/prosemirror/runFormattingReconciliation.js +10 -9
  354. package/dist/prosemirror/schema/index.d.ts +2 -2
  355. package/dist/prosemirror/schema/index.js +3 -0
  356. package/dist/prosemirror/schema/nodes.d.ts +44 -11
  357. package/dist/prosemirror/sectionMarkEdits.d.ts +20 -0
  358. package/dist/prosemirror/sectionMarkEdits.js +59 -0
  359. package/dist/prosemirror/storyListNumbering.d.ts +17 -0
  360. package/dist/prosemirror/storyListNumbering.js +102 -0
  361. package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +59 -0
  362. package/dist/prosemirror/styles/paragraphStyleCascade.js +145 -0
  363. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +21 -2
  364. package/dist/prosemirror/styles/resolvedStyleAttrs.js +38 -1
  365. package/dist/prosemirror/styles/tableStyleRegions.d.ts +31 -0
  366. package/dist/prosemirror/styles/tableStyleRegions.js +55 -0
  367. package/dist/prosemirror/tableCellPaste.d.ts +74 -0
  368. package/dist/prosemirror/tableCellPaste.js +525 -0
  369. package/dist/prosemirror/tableGridMutation.d.ts +87 -2
  370. package/dist/prosemirror/tableGridMutation.js +255 -2
  371. package/dist/prosemirror/tableRunIn.d.ts +51 -0
  372. package/dist/prosemirror/tableRunIn.js +165 -0
  373. package/dist/prosemirror/textInput.js +11 -2
  374. package/dist/prosemirror/trackedRevisionPath.d.ts +17 -0
  375. package/dist/prosemirror/trackedRevisionPath.js +32 -0
  376. package/dist/prosemirror/validation.js +5 -1
  377. package/dist/redline.js +93 -9
  378. package/dist/render-dom/BodySelectionOverlay.d.ts +4 -1
  379. package/dist/render-dom/BodySelectionOverlay.js +3 -2
  380. package/dist/server.d.ts +2 -2
  381. package/dist/utils/findReplace.js +2 -2
  382. package/dist/utils/mergeDocumentContent.js +1 -1
  383. package/dist/utils/noteReferenceLabels.d.ts +36 -0
  384. package/dist/utils/noteReferenceLabels.js +32 -0
  385. package/dist/utils/replaceText.js +1 -1
  386. package/dist/version-comparison.d.ts +1 -0
  387. package/dist/version-comparison.js +1 -0
  388. package/package.json +6 -5
  389. package/dist/internal/headlessRevisionResolution.d.ts +0 -23
@@ -2,6 +2,7 @@ import { isValidHexId } from "../utils/hexId.js";
2
2
  import { attributeRemainder } from "./attributeRemainder.js";
3
3
  import { parseBookmarkEnd as parseBookmarkEnd$1, parseBookmarkStart as parseBookmarkStart$1 } from "./bookmarkParser.js";
4
4
  import { CAPTURE, dispatchChildrenWithContext, ownedElsewhere, transitionalNamespaceOf, withPreservedChildren } from "./containerChildren.js";
5
+ import { resolveDefaultParagraphStyle } from "./defaultParagraphStyle.js";
5
6
  import { parseFieldType } from "./fieldParser.js";
6
7
  import { fieldStateOf, parseFieldState } from "./fieldState.js";
7
8
  import { HYPERLINK_CHILD_HANDLERS, parseHyperlink as parseHyperlink$1, parseHyperlinkShell } from "./hyperlinkParser.js";
@@ -578,8 +579,8 @@ const hasRunPayload = ({ run, runElement, rels, media }) => {
578
579
  * the assembled field, and one that reaches the editor's inline converter on
579
580
  * its own is dropped. So a `w:fldChar` whose field this paragraph never closed,
580
581
  * or one with no `begin` before it, loses the editor round trip — and the
581
- * model holds nothing of its `w:ffData` either, so the save loses a legacy form
582
- * field's name, macros, help text and checkbox state as well.
582
+ * orphan field has no owning `ComplexField` to hold its `w:ffData`, so dropping
583
+ * this run would also lose its name, macros, help text and checkbox state.
583
584
  *
584
585
  * `preservedXml` is the run's own capture member: the editor carries it as an
585
586
  * opaque atom and the serializer replays the source bytes, `w:ffData` included.
@@ -610,9 +611,11 @@ const LEGACY_FORM_CHECKBOX_GLYPHS = {
610
611
  unchecked: "☐"
611
612
  };
612
613
  const LEGACY_FORM_CHECKBOX_INSTRUCTION = "FORMCHECKBOX";
613
- function getLegacyFormCheckboxDisplay(runElement) {
614
- const fieldChar = findChild(runElement, "w", "fldChar");
615
- const fieldData = fieldChar ? findChild(fieldChar, "w", "ffData") : null;
614
+ const beginFieldCharOf = (runElement) => findChildrenByNamespaceUri(runElement, WORDPROCESSINGML_NAMESPACE_URIS, "fldChar").find((fieldChar) => {
615
+ const charType = getAttribute(fieldChar, "w", "fldCharType");
616
+ return charType !== "separate" && charType !== "end";
617
+ });
618
+ function getLegacyFormCheckboxDisplay(fieldData) {
616
619
  const checkBox = fieldData ? findChild(fieldData, "w", "checkBox") : null;
617
620
  if (!checkBox) return;
618
621
  const checked = findChild(checkBox, "w", "checked");
@@ -676,6 +679,30 @@ const FIELD_INLINE_WRAPPER_HANDLERS = {
676
679
  pPr: CAPTURE
677
680
  };
678
681
  /**
682
+ * Whether the walk is currently inside some open field's code region — its
683
+ * own `begin` has been read but not yet its `separate` — at any nesting
684
+ * depth. `codeDepthStack` tracks every open field regardless of whether it
685
+ * assembles into a `ComplexField`, so this answers the question for content,
686
+ * such as a `w:fldSimple`, that a `ComplexField`'s own code/result split
687
+ * cannot carry.
688
+ */
689
+ const isHiddenByOpenFieldCode = (scan) => scan.codeDepthStack.some((pastSeparator) => !pastSeparator);
690
+ /**
691
+ * A run captured for a position this field's `fieldResult` (or `fieldCode`)
692
+ * must hold — the source ordering a save has to reproduce puts it there —
693
+ * whose actual content sits inside a deeper, still-open field's own
694
+ * instruction region and so must show nothing. Every non-`w:rPr` child is
695
+ * captured through `preserveRunChild`, the same verbatim-with-no-text capture
696
+ * an unrecognised run child already gets, rather than kept as the `text`/
697
+ * `instrText` the parse produced — a `w:t` this walk read as authored result
698
+ * text is exactly what must not read back out of `fieldResult`.
699
+ */
700
+ const hiddenRunCaptureOf = (runElement, formatting) => ({
701
+ type: "run",
702
+ content: getChildElements(runElement).filter((child) => getLocalName(child.name) !== "rPr").map((child) => preserveRunChild(child)),
703
+ ...formatting && Object.keys(formatting).length > 0 ? { formatting } : {}
704
+ });
705
+ /**
679
706
  * The container children a complex field's result may hold and still be
680
707
  * assembled into a `ComplexField`: its runs and the zero-width markers read
681
708
  * beside them. Any other child is inline content (a hyperlink, a simple field,
@@ -713,25 +740,31 @@ const isWordprocessingChild = (child) => {
713
740
  };
714
741
  /**
715
742
  * The `w:r` children whose `begin` opens a complex field that this container's
716
- * walk closes.
743
+ * walk closes as its own top-level `ComplexField`.
717
744
  *
718
745
  * A field is assembled from the runs between its `begin` and its `end`, so it
719
746
  * exists only when both are runs of this container with nothing between them
720
747
  * that a `ComplexField` cannot hold. A TOC opened here and closed in a later
721
- * paragraph, a field whose result holds a `w:hyperlink` (a TOC's `\h` entries),
722
- * and an outer field whose result holds a nested field are none of these; their
723
- * runs are ordinary content, read in source order alongside the siblings
724
- * between them. Mirrors the `w:r` handler run by run: a run with a `begin`
725
- * opens a field, and a run with an `end` closes the one open.
748
+ * paragraph, and a field whose result holds a `w:hyperlink` (a TOC's `\h`
749
+ * entries), are neither of those; their runs are ordinary content, read in
750
+ * source order alongside the siblings between them.
751
+ *
752
+ * A `begin`/`end` pair that closes while another `begin` is still open is
753
+ * nested inside that other field's code or result — its own runs stay with
754
+ * the outer field's, carried in `fieldCode`/`fieldResult` rather than
755
+ * assembled into a `ComplexField` of their own, which is why only the
756
+ * outermost pair of a nested run adds its `begin` here. Tracked with a stack
757
+ * rather than one slot so a field nested inside a field nested inside a field
758
+ * closes each level against the right opener instead of the most recent one.
726
759
  */
727
760
  const assembledFieldBeginsOf = (container) => {
728
761
  const assembled = /* @__PURE__ */ new Set();
729
- let open;
762
+ const open = [];
730
763
  for (const child of getChildElements(container)) {
731
764
  const wordprocessing = isWordprocessingChild(child);
732
765
  const localName = getLocalName(child.name);
733
766
  if (!wordprocessing || localName !== "r") {
734
- if (!wordprocessing || !FIELD_TRANSPARENT_CHILDREN.has(localName)) open = void 0;
767
+ if (!wordprocessing || !FIELD_TRANSPARENT_CHILDREN.has(localName)) open.length = 0;
735
768
  continue;
736
769
  }
737
770
  let hasBegin = false;
@@ -742,10 +775,10 @@ const assembledFieldBeginsOf = (container) => {
742
775
  if (charType === "end") hasEnd = true;
743
776
  else if (charType !== "separate") hasBegin = true;
744
777
  }
745
- if (hasBegin) open = child;
746
- if (hasEnd && open !== void 0) {
747
- assembled.add(open);
748
- open = void 0;
778
+ if (hasBegin) open.push(child);
779
+ if (hasEnd && open.length > 0) {
780
+ const closed = open.pop();
781
+ if (closed !== void 0 && open.length === 0) assembled.add(closed);
749
782
  }
750
783
  }
751
784
  return assembled;
@@ -774,7 +807,8 @@ const PARAGRAPH_CONTENT_HANDLERS = {
774
807
  const commentReferenceId = getCommentReferenceId(runElement);
775
808
  let hasFieldBegin = false;
776
809
  let beginFieldState = {};
777
- const beginFallbackDisplay = getLegacyFormCheckboxDisplay(runElement);
810
+ const beginFieldData = findWordprocessingChild(beginFieldCharOf(runElement), "ffData");
811
+ const beginFallbackDisplay = getLegacyFormCheckboxDisplay(beginFieldData);
778
812
  let hasFieldSeparate = false;
779
813
  let hasFieldEnd = false;
780
814
  let endOriginalValue;
@@ -788,6 +822,8 @@ const PARAGRAPH_CONTENT_HANDLERS = {
788
822
  if (content.originalValue !== void 0) endOriginalValue = content.originalValue;
789
823
  }
790
824
  else if (content.type === "instrText") instrText += content.text;
825
+ if (hasFieldBegin) scan.codeDepthStack.push(false);
826
+ if (hasFieldSeparate && scan.codeDepthStack.length > 0) scan.codeDepthStack[scan.codeDepthStack.length - 1] = true;
791
827
  if (hasFieldBegin) {
792
828
  scan.assembledFieldBegins ??= assembledFieldBeginsOf(scan.container);
793
829
  if (!scan.assembledFieldBegins.has(child)) hasFieldBegin = false;
@@ -804,9 +840,13 @@ const PARAGRAPH_CONTENT_HANDLERS = {
804
840
  scan.complexFieldResultRuns = [];
805
841
  scan.complexFieldOpenRuns = [];
806
842
  scan.complexFieldState = beginFieldState;
843
+ scan.complexFieldDataXml = beginFieldData ? captureVerbatimXml(beginFieldData) : void 0;
807
844
  scan.complexFieldFallbackDisplay = beginFallbackDisplay;
808
845
  scan.complexFieldFormatting = run.formatting;
846
+ scan.complexFieldBaseDepth = scan.codeDepthStack.length;
809
847
  }
848
+ const isNestedField = scan.codeDepthStack.length > scan.complexFieldBaseDepth;
849
+ if (hasFieldEnd && scan.codeDepthStack.length > 0) scan.codeDepthStack.pop();
810
850
  if (scan.inComplexField) {
811
851
  scan.complexFieldOpenRuns.push(withOrphanFieldCharsPreserved(run, runElement));
812
852
  if (instrText) scan.complexFieldInstr += instrText;
@@ -815,6 +855,10 @@ const PARAGRAPH_CONTENT_HANDLERS = {
815
855
  const fieldCodeContent = [];
816
856
  for (const content of run.content) {
817
857
  if (content.type === "fieldChar") {
858
+ if (isNestedField) {
859
+ if (inFieldCodeRegion) fieldCodeContent.push(content);
860
+ continue;
861
+ }
818
862
  inFieldCodeRegion = content.charType === "begin";
819
863
  continue;
820
864
  }
@@ -824,11 +868,11 @@ const PARAGRAPH_CONTENT_HANDLERS = {
824
868
  ...run,
825
869
  content: fieldCodeContent
826
870
  });
827
- if (hasFieldSeparate) scan.afterSeparator = true;
871
+ if (hasFieldSeparate && !isNestedField) scan.afterSeparator = true;
828
872
  if (scan.afterSeparator && !hasFieldEnd) {
829
- if (!hasFieldSeparate) scan.complexFieldResultRuns.push(run);
873
+ if (!hasFieldSeparate) scan.complexFieldResultRuns.push(isHiddenByOpenFieldCode(scan) ? hiddenRunCaptureOf(runElement, run.formatting) : run);
830
874
  }
831
- if (hasFieldEnd) {
875
+ if (hasFieldEnd && !isNestedField) {
832
876
  let resultRuns = scan.complexFieldResultRuns;
833
877
  let resultIsFallback = false;
834
878
  if (resultRuns.length === 0 && scan.complexFieldFallbackDisplay !== void 0 && isLegacyFormCheckboxInstruction(scan.complexFieldInstr)) {
@@ -850,6 +894,7 @@ const PARAGRAPH_CONTENT_HANDLERS = {
850
894
  fieldResult: resultRuns,
851
895
  ...scan.complexFieldState
852
896
  };
897
+ if (scan.complexFieldDataXml !== void 0) complexField.formFieldDataXml = scan.complexFieldDataXml;
853
898
  if (resultIsFallback) complexField.fieldResultIsFallback = true;
854
899
  if (scan.complexFieldFormatting) complexField.formatting = scan.complexFieldFormatting;
855
900
  contents.push(complexField);
@@ -865,6 +910,17 @@ const PARAGRAPH_CONTENT_HANDLERS = {
865
910
  type: "commentReference",
866
911
  id: commentReferenceId
867
912
  });
913
+ } else if (isHiddenByOpenFieldCode(scan)) {
914
+ if (hasRunPayload({
915
+ run,
916
+ runElement,
917
+ rels,
918
+ media
919
+ })) contents.push({
920
+ type: "preservedInline",
921
+ xml: captureVerbatimXml(runElement),
922
+ text: ""
923
+ });
868
924
  } else if (hasRunPayload({
869
925
  run,
870
926
  runElement,
@@ -881,8 +937,17 @@ const PARAGRAPH_CONTENT_HANDLERS = {
881
937
  bookmarkEnd: (child, { contents }) => {
882
938
  contents.push(parseBookmarkEnd(child));
883
939
  },
884
- fldSimple: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns }) => {
885
- contents.push(parseSimpleField(child, styles, theme, rels, media, inScopeXmlns, previews));
940
+ fldSimple: (child, { contents, styles, theme, rels, media, previews, inScopeXmlns, trackedContext, scan }) => {
941
+ const fieldElement = trackedContext === "deletion" ? normalizeDeletionContentElement(child) : child;
942
+ if (isHiddenByOpenFieldCode(scan)) {
943
+ contents.push({
944
+ type: "preservedInline",
945
+ xml: captureVerbatimXml(fieldElement),
946
+ text: ""
947
+ });
948
+ return;
949
+ }
950
+ contents.push(parseSimpleField(fieldElement, styles, theme, rels, media, inScopeXmlns, previews));
886
951
  },
887
952
  pPr: PARAGRAPH_PROPERTIES_OWNER,
888
953
  customXml: paragraphInlineWrapper("customXml"),
@@ -1005,10 +1070,13 @@ function parseParagraphContents(paraElement, styles, theme, _numbering, rels, me
1005
1070
  complexFieldOpenRuns: [],
1006
1071
  afterSeparator: false,
1007
1072
  complexFieldState: {},
1073
+ complexFieldDataXml: void 0,
1008
1074
  complexFieldFallbackDisplay: void 0,
1009
1075
  complexFieldFormatting: void 0,
1010
1076
  container: paraElement,
1011
- assembledFieldBegins: void 0
1077
+ assembledFieldBegins: void 0,
1078
+ codeDepthStack: [],
1079
+ complexFieldBaseDepth: 0
1012
1080
  };
1013
1081
  const preserved = dispatchChildrenWithContext({
1014
1082
  element: paraElement,
@@ -1174,7 +1242,8 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
1174
1242
  }
1175
1243
  if (implicitChildLevelAdvances > 0) listRendering.implicitChildLevelAdvances = implicitChildLevelAdvances;
1176
1244
  paragraph.listRendering = listRendering;
1177
- const chainInd = numPrFromStyle ? styleChainInd(paragraph.formatting?.styleId, styles) : {
1245
+ const styleInd = styleChainInd(paragraph.formatting?.styleId ?? (styles ? resolveDefaultParagraphStyle(styles.values())?.styleId : void 0), styles);
1246
+ const chainInd = numPrFromStyle ? styleInd : {
1178
1247
  left: false,
1179
1248
  firstLine: false
1180
1249
  };
@@ -1183,8 +1252,8 @@ function parseParagraph(node, styles, theme, numbering, rels = null, media = nul
1183
1252
  const directInd = pPr ? findChild(pPr, "w", "ind") : null;
1184
1253
  const hasDirectLeft = hasAttributeAnySpelling(directInd, "CT_Ind @left");
1185
1254
  const hasDirectFirstLineOrHanging = parseNumericAttribute(directInd, "w", "firstLine") !== void 0 || parseNumericAttribute(directInd, "w", "hanging") !== void 0;
1186
- if (!hasDirectLeft && !chainInd.left && level.pPr.indentLeft !== void 0) paragraph.formatting.indentLeft = level.pPr.indentLeft;
1187
- if (!hasDirectFirstLineOrHanging && !chainInd.firstLine && numberingLevelHasMarkerSlot(level)) {
1255
+ if (!hasDirectLeft && !chainInd.left && level.pPr.indentLeft !== void 0 && (level.pPr.indentLeft !== 0 || styleInd.left)) paragraph.formatting.indentLeft = level.pPr.indentLeft;
1256
+ if (!hasDirectFirstLineOrHanging && !chainInd.firstLine && numberingLevelHasMarkerSlot(level) && (level.pPr.indentFirstLine !== 0 || styleInd.firstLine)) {
1188
1257
  if (level.pPr.indentFirstLine !== void 0) paragraph.formatting.indentFirstLine = level.pPr.indentFirstLine;
1189
1258
  if (level.pPr.hangingIndent !== void 0) paragraph.formatting.hangingIndent = level.pPr.hangingIndent;
1190
1259
  }
@@ -1,7 +1,7 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  import { ModeledParagraphFormattingEmission } from "../internal/paragraphFormattingSerialization.js";
3
- import { Transaction } from "prosemirror-state";
4
3
  import { Fragment, Mark, Node, NodeType } from "prosemirror-model";
4
+ import { Transaction } from "prosemirror-state";
5
5
  //#region src/docx/paragraphPropertySource.d.ts
6
6
  declare const paragraphPropertySourceEmissionFingerprint: unique symbol;
7
7
  type ParagraphPropertySource = Readonly<{
@@ -97,6 +97,8 @@ type JoinProseParagraphsWithRightPropertySourceOptions = {
97
97
  };
98
98
  /** Join adjacent paragraphs when revision semantics deliberately select the right owner. */
99
99
  declare const joinProseParagraphsWithRightPropertySource: ({ attrs, pos, transaction }: JoinProseParagraphsWithRightPropertySourceOptions) => Transaction;
100
+ /** Record the property owners deliberately selected by a batch of paragraph joins. */
101
+ declare const markParagraphPropertySourceTransfers: (transaction: Transaction, transfers: readonly ParagraphPropertySourceTransfer[]) => void;
100
102
  declare const getExplicitParagraphPropertySourceTransfers: (transaction: Transaction) => readonly ParagraphPropertySourceTransfer[];
101
103
  type RecreateProseNodeOptions = {
102
104
  attrs?: Node["attrs"];
@@ -134,4 +136,4 @@ declare const linkParagraphPropertySourceCandidate: (target: document_d_exports.
134
136
  declare const getParagraphPropertySourceCandidate: (paragraph: document_d_exports.Paragraph) => document_d_exports.Paragraph | undefined;
135
137
  declare const getParagraphPropertySourceTransferId: (paragraph: document_d_exports.Paragraph) => string | undefined;
136
138
  //#endregion
137
- export { DecodedTableCellParagraphSourcePayload, PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceValidationCode, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, TableCellParagraphPropertySourceBinding, TableCellParagraphSourcePayloadErrorClassification, assignDocumentParagraphPropertySourceContract, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
139
+ export { DecodedTableCellParagraphSourcePayload, PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceTransfer, ParagraphPropertySourceValidationCode, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, TableCellParagraphPropertySourceBinding, TableCellParagraphSourcePayloadErrorClassification, assignDocumentParagraphPropertySourceContract, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, markParagraphPropertySourceTransfers, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
@@ -261,6 +261,7 @@ const invalidTableCellParagraphSourcePayload = (classification, path) => {
261
261
  };
262
262
  const tableCellBlockTraversalByType = {
263
263
  blockSdt: "blockSdt",
264
+ blockCustomXml: "blockSdt",
264
265
  bookmarkEnd: "leaf",
265
266
  bookmarkStart: "leaf",
266
267
  paragraph: "paragraph",
@@ -634,6 +635,11 @@ const joinProseParagraphsWithRightPropertySource = ({ attrs, pos, transaction })
634
635
  }]);
635
636
  return transaction;
636
637
  };
638
+ /** Record the property owners deliberately selected by a batch of paragraph joins. */
639
+ const markParagraphPropertySourceTransfers = (transaction, transfers) => {
640
+ if (transfers.length === 0) return;
641
+ transaction.setMeta(paragraphPropertySourceTransfersKey, [...transaction.getMeta(paragraphPropertySourceTransfersKey) ?? [], ...transfers]);
642
+ };
637
643
  const getExplicitParagraphPropertySourceTransfers = (transaction) => transaction.getMeta(paragraphPropertySourceTransfersKey) ?? [];
638
644
  /** Carry a parser-linked paragraph owner across an immutable PM node rebuild. */
639
645
  const copyProseParagraphPropertySource = (target, source) => {
@@ -673,7 +679,9 @@ const proseParagraphAttrsWithoutPropertySource = (attrs) => {
673
679
  /** Replace paragraph markup without losing its private parser-owner link. */
674
680
  const setProseParagraphMarkupWithPropertySource = ({ attrs, ownership, pos, transaction }) => {
675
681
  const source = transaction.doc.nodeAt(pos);
676
- transaction.setNodeMarkup(pos, void 0, attrs);
682
+ if (source) {
683
+ for (const [name, value] of Object.entries(attrs)) if (source.attrs[name] !== value) transaction.setNodeAttribute(pos, name, value);
684
+ } else transaction.setNodeMarkup(pos, void 0, attrs);
677
685
  const target = transaction.doc.nodeAt(pos);
678
686
  if (!source || !target) return;
679
687
  if (ownership === "preserve") {
@@ -703,4 +711,4 @@ const linkParagraphPropertySourceCandidate = (target, source) => {
703
711
  const getParagraphPropertySourceCandidate = (paragraph) => paragraphPropertySourceCandidates.get(paragraph);
704
712
  const getParagraphPropertySourceTransferId = (paragraph) => paragraphPropertySourceTransferIds.get(paragraph);
705
713
  //#endregion
706
- export { PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, assignDocumentParagraphPropertySourceContract, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
714
+ export { PARAGRAPH_PROPERTY_SOURCE_VALIDATION_CODES, PROSE_PARAGRAPH_SOURCE_CONTRACT_ATTR, PROSE_PARAGRAPH_SOURCE_TOKEN_ATTR, ParagraphPropertySourceValidationError, TABLE_CELL_PARAGRAPH_SOURCE_BINDING_ATTR, TABLE_CELL_PARAGRAPH_SOURCE_PAYLOAD_ERROR_CLASSIFICATIONS, assignDocumentParagraphPropertySourceContract, assignParagraphPropertySource, cloneDocumentWithParagraphPropertySources, cloneParagraphWithPropertySource, cloneParagraphWithoutPropertySource, cloneTableCellsWithParagraphPropertyCaptures, copyDocumentParagraphPropertySourceContract, copyDocumentParagraphPropertySources, copyParagraphPropertyCapture, copyParagraphPropertySource, createProseParagraphWithPropertySource, decodeTableCellParagraphSourcePayload, getDocumentParagraphPropertySourceContract, getExplicitParagraphPropertySourceTransfers, getParagraphPropertySource, getParagraphPropertySourceCandidate, getParagraphPropertySourceToken, getParagraphPropertySourceTransferId, getProseDocumentParagraphPropertySourceContract, getProseParagraphPropertySourceToken, isParagraphPropertySourceToken, joinProseParagraphsWithRightPropertySource, linkParagraphPropertySourceCandidate, linkProseParagraphPropertySource, markParagraphPropertySourceTransfers, paragraphPropertySourceBelongsToDocument, paragraphPropertySourceMatchesEmission, paragraphPropertySourceTokenMatchesContract, proseParagraphAttrsWithoutPropertySource, recreateProseNodeWithDetachedParagraphPropertySource, recreateProseNodeWithParagraphPropertySource, restoreTableCellsWithParagraphPropertySources, setProseParagraphMarkupWithPropertySource, transferProseParagraphPropertySource, transportTableCellsWithParagraphPropertySources, visitDocumentStoryParagraphs, visitTableCellParagraphPropertySourceBindings };
@@ -126,6 +126,7 @@ const visitBlockTreeRecords = (blocks, visit) => {
126
126
  }
127
127
  break;
128
128
  case "blockSdt":
129
+ case "blockCustomXml":
129
130
  visitBlocks(block.content);
130
131
  break;
131
132
  case "preservedBlock":
@@ -40,7 +40,10 @@ const PARSE_WARNING_MESSAGES = {
40
40
  [PARSE_WARNING_CODES.outlineDashOutsideEnum]: (warning) => `Kept outline dash${quoted(warning.value)} verbatim${where(warning)}; ST_PresetLineDashVal does not declare it.`,
41
41
  [PARSE_WARNING_CODES.styleSetDuplicateStyleId]: (warning) => `Dropped a style repeating the id${quoted(warning.value)} another style in the set already defines.`,
42
42
  [PARSE_WARNING_CODES.styleSetInitialStyleMissing]: (warning) => `The style set names initial paragraph style${quoted(warning.value)}, which it does not contain; used the set's default instead${where(warning)}.`,
43
- [PARSE_WARNING_CODES.pageBreakProjectionApproximated]: (warning) => `${warning.detail ?? "An explicit page break is laid out approximately"}${where(warning)}.`
43
+ [PARSE_WARNING_CODES.pageBreakProjectionApproximated]: (warning) => `${warning.detail ?? "An explicit page break is laid out approximately"}${where(warning)}.`,
44
+ [PARSE_WARNING_CODES.altChunkUnsupported]: (warning) => `Preserved ${plural(warning.count, "w:altChunk")}; Folio cannot import its external content. Readers show a diagnostic marker.`,
45
+ [PARSE_WARNING_CODES.revisionCarrierOpaque]: (warning) => `Preserved ${plural(warning.count, "block-level tracked-change wrapper")}; Folio cannot interpret its block content, so that content is unavailable to readers or edits.`,
46
+ [PARSE_WARNING_CODES.nestedRowOpaque]: (warning) => `Preserved ${plural(warning.count, "nested table row")} as opaque markup; readers show a diagnostic marker for its content.`
44
47
  };
45
48
  const formatParseWarning = (warning) => PARSE_WARNING_MESSAGES[warning.code](warning);
46
49
  const formatParseWarnings = (warnings) => warnings.map(formatParseWarning);
@@ -1,6 +1,7 @@
1
1
  import { toArrayBuffer } from "../utils/docxInput.js";
2
2
  import { loadFontsWithMapping } from "../utils/fontLoader.js";
3
3
  import { MAX_PACKAGE_TIFF_PIXELS, convertTiffToPngDataUrl, isTiffMimeType } from "../utils/tiffConverter.js";
4
+ import { ALT_CHUNK_PLAIN_TEXT_LIMIT_BYTES, getAltChunkRelationshipId, isAltChunkMarkup } from "./altChunk.js";
4
5
  import { DUPLICATE_COMMENT_ID_WARNING, normalizeCommentIds } from "./commentIdNormalization.js";
5
6
  import { parseComments } from "./commentParser.js";
6
7
  import { DANGLING_COMMENT_REFERENCE_WARNING, UNBALANCED_COMMENT_RANGE_WARNING, normalizeCommentReferences } from "./commentReferenceNormalization.js";
@@ -13,13 +14,14 @@ import { DocxEncryptionError } from "./encryption/errors.js";
13
14
  import { parseFontTable } from "./fontTableParser.js";
14
15
  import { parseEndnotes, parseFootnotes } from "./footnoteParser.js";
15
16
  import { parseFooter, parseHeader } from "./headerFooterParser.js";
16
- import { DANGLING_FOOTER_REFERENCE_WARNING, DANGLING_HEADER_REFERENCE_WARNING, normalizeHeaderFooterReferences } from "./headerFooterReferenceNormalization.js";
17
- import { assignHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint } from "./headerFooterVerbatim.js";
17
+ import { DANGLING_FOOTER_REFERENCE_WARNING, DANGLING_HEADER_REFERENCE_WARNING, assignHeaderFooterRoles, normalizeHeaderFooterReferences } from "./headerFooterReferenceNormalization.js";
18
+ import { assignHeaderFooterVerbatimXml, canReplayHeaderFooterVerbatim, refreshHeaderFooterVerbatimFingerprint } from "./headerFooterVerbatim.js";
18
19
  import { extractMetafileRaster, isMetafileMimeType } from "./metafileRaster.js";
19
20
  import { renderEmfSvg } from "./metafileSvg.js";
20
21
  import { DocxModelValidationError, formatDocumentModelIssues, validateFolioDocumentModel } from "./modelValidation.js";
21
22
  import { parseNumbering } from "./numberingParser.js";
22
23
  import { UNNUMBERED_PARAGRAPH_WARNING, UNNUMBERED_STYLE_WARNING, normalizeNumberingReferences, normalizeStyleNumberingReferences } from "./numberingReferenceNormalization.js";
24
+ import { countOpaqueRevisionWrappers } from "./opaqueCarrier.js";
23
25
  import { assignDocumentParagraphPropertySourceContract } from "./paragraphPropertySource.js";
24
26
  import { createParseWarningCollector } from "./parseContext.js";
25
27
  import { formatParseWarnings } from "./parseWarningMessage.js";
@@ -30,9 +32,10 @@ import { parseSettings } from "./settingsParser.js";
30
32
  import { parseStylesPackage } from "./styleParser.js";
31
33
  import { applyThemeFontLang, parseTheme } from "./themeParser.js";
32
34
  import { UNBALANCED_MOVE_RANGE_WARNING, normalizeTrackedMoveRanges } from "./trackedMoveRangeNormalization.js";
33
- import { getMediaMimeType, mediaToDataUrl, unzipDocx } from "./unzip.js";
35
+ import { getEntryUncompressedSize, getMediaMimeType, mediaToDataUrl, unzipDocx } from "./unzip.js";
36
+ import { getAttribute, getChildElements, getLocalName, parseXmlDocument } from "./xmlParser.js";
34
37
  import { FOLIO_XML_RESOURCE_LIMITS } from "./xmlResourceLimits.js";
35
- import { TaggedError } from "better-result";
38
+ import { TaggedError, panic } from "better-result";
36
39
  import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
37
40
  //#region src/docx/parser.ts
38
41
  /**
@@ -63,6 +66,101 @@ const sha256Hex = async (buffer) => {
63
66
  for (const byte of bytes) digest += byte.toString(16).padStart(2, "0");
64
67
  return digest;
65
68
  };
69
+ const countAltChunks = (blocks) => {
70
+ let count = 0;
71
+ for (const block of blocks) switch (block.type) {
72
+ case "preservedBlock":
73
+ count += isAltChunkMarkup(block.xml) ? 1 : 0;
74
+ break;
75
+ case "table":
76
+ for (const row of block.rows) for (const cell of row.cells) count += countAltChunks(cell.content);
77
+ break;
78
+ case "blockSdt":
79
+ case "blockCustomXml":
80
+ count += countAltChunks(block.content);
81
+ break;
82
+ case "paragraph":
83
+ case "bookmarkStart":
84
+ case "bookmarkEnd": break;
85
+ default: panic(`Unsupported block while counting altChunks: ${JSON.stringify(block)}`);
86
+ }
87
+ return count;
88
+ };
89
+ const ALT_CHUNK_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk";
90
+ const ALT_CHUNK_STRICT_RELATIONSHIP_TYPE = "http://purl.oclc.org/ooxml/officeDocument/relationships/aFChunk";
91
+ const CONTENT_TYPES_NAMESPACE_URI = "http://schemas.openxmlformats.org/package/2006/content-types";
92
+ const contentTypeOf = (contentTypesXml, partPath) => {
93
+ if (!contentTypesXml) return;
94
+ const root = parseXmlDocument(contentTypesXml);
95
+ if (!root || root.namespaceUri !== CONTENT_TYPES_NAMESPACE_URI) return;
96
+ const extension = partPath.slice(partPath.lastIndexOf(".") + 1).toLowerCase();
97
+ let defaultContentType;
98
+ for (const child of getChildElements(root)) {
99
+ if (child.namespaceUri !== CONTENT_TYPES_NAMESPACE_URI) continue;
100
+ const name = getLocalName(child.name);
101
+ const contentType = getAttribute(child, null, "ContentType");
102
+ if (name === "Override" && getAttribute(child, null, "PartName") === `/${partPath}`) return contentType ?? void 0;
103
+ if (name === "Default" && getAttribute(child, null, "Extension")?.toLowerCase() === extension) defaultContentType = contentType ?? void 0;
104
+ }
105
+ return defaultContentType;
106
+ };
107
+ const extractAltChunkPlainText = async (xml, context) => {
108
+ const relationshipId = getAltChunkRelationshipId(xml);
109
+ const relationship = relationshipId === void 0 ? void 0 : context.relationships.get(relationshipId);
110
+ if (!relationship || relationship.targetMode === "External" || relationship.type !== ALT_CHUNK_RELATIONSHIP_TYPE && relationship.type !== ALT_CHUNK_STRICT_RELATIONSHIP_TYPE) return;
111
+ const partPath = resolveRelativePath(context.relationshipsPath, relationship.target);
112
+ if (contentTypeOf(context.raw.contentTypesXml, partPath)?.split(";")[0]?.trim().toLowerCase() !== "text/plain") return;
113
+ const file = context.raw.originalZip.file(partPath);
114
+ if (!file) return;
115
+ const declaredSize = getEntryUncompressedSize(file);
116
+ if (declaredSize === null || declaredSize > context.budget.remainingBytes) return void 0;
117
+ const bytes = await file.async("uint8array");
118
+ if (bytes.byteLength > context.budget.remainingBytes) return;
119
+ context.budget.remainingBytes -= bytes.byteLength;
120
+ try {
121
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
122
+ } catch {
123
+ return;
124
+ }
125
+ };
126
+ const attachAltChunkPlainText = async (blocks, context) => {
127
+ for (const block of blocks) {
128
+ if (block.type === "preservedBlock" && isAltChunkMarkup(block.xml)) {
129
+ const readerText = await extractAltChunkPlainText(block.xml, context);
130
+ if (readerText !== void 0) block.readerText = readerText;
131
+ continue;
132
+ }
133
+ if (block.type === "table") {
134
+ for (const row of block.rows) for (const cell of row.cells) await attachAltChunkPlainText(cell.content, context);
135
+ continue;
136
+ }
137
+ if (block.type === "blockSdt" || block.type === "blockCustomXml") await attachAltChunkPlainText(block.content, context);
138
+ }
139
+ };
140
+ const countOpaqueRevisionCarriers = (blocks) => {
141
+ let count = 0;
142
+ for (const block of blocks) switch (block.type) {
143
+ case "preservedBlock":
144
+ count += countOpaqueRevisionWrappers(block.xml);
145
+ break;
146
+ case "table":
147
+ count += block.preserved?.children?.reduce((total, child) => total + countOpaqueRevisionWrappers(child.xml), 0) ?? 0;
148
+ for (const row of block.rows) {
149
+ count += row.preserved?.children?.reduce((total, child) => total + countOpaqueRevisionWrappers(child.xml), 0) ?? 0;
150
+ for (const cell of row.cells) count += countOpaqueRevisionCarriers(cell.content);
151
+ }
152
+ break;
153
+ case "blockSdt":
154
+ case "blockCustomXml":
155
+ count += countOpaqueRevisionCarriers(block.content);
156
+ break;
157
+ case "paragraph":
158
+ case "bookmarkStart":
159
+ case "bookmarkEnd": break;
160
+ default: panic(`Unsupported block while counting opaque revisions: ${JSON.stringify(block)}`);
161
+ }
162
+ return count;
163
+ };
66
164
  /**
67
165
  * Parse a DOCX file into a complete Document model
68
166
  *
@@ -210,6 +308,11 @@ async function parseDocxWithPreviewBudget(input, options, previewBudget) {
210
308
  code: DANGLING_FOOTER_REFERENCE_WARNING,
211
309
  count: headerFooterReferenceNormalization.removedDanglingFooterReferences
212
310
  });
311
+ assignHeaderFooterRoles({
312
+ documentBody,
313
+ ...headers !== void 0 ? { headers } : {},
314
+ ...footers !== void 0 ? { footers } : {}
315
+ });
213
316
  const numberingReferenceNormalization = normalizeNumberingReferences({
214
317
  documentBody,
215
318
  numbering,
@@ -272,27 +375,77 @@ async function parseDocxWithPreviewBudget(input, options, previewBudget) {
272
375
  } else onProgress("Skipping font loading", 95);
273
376
  onProgress("Assembling document...", 95);
274
377
  const properties = timeStage("coreProperties", () => parseCoreProperties(raw.corePropsXml));
378
+ const pkg = {
379
+ conformanceClass: detectDocxConformanceClass(raw.documentXml),
380
+ document: documentBody,
381
+ settings,
382
+ ...styleDefinitions !== void 0 ? { styles: styleDefinitions } : {},
383
+ theme,
384
+ numbering: numbering.definitions,
385
+ ...fontTable ? { fontTable } : {},
386
+ ...headers !== void 0 ? { headers } : {},
387
+ ...footers !== void 0 ? { footers } : {},
388
+ ...footnotes !== void 0 ? { footnotes } : {},
389
+ ...endnotes !== void 0 ? { endnotes } : {},
390
+ relationships: rels,
391
+ media,
392
+ ...properties !== void 0 ? { properties } : {}
393
+ };
275
394
  const document = {
276
- package: {
277
- conformanceClass: detectDocxConformanceClass(raw.documentXml),
278
- document: documentBody,
279
- settings,
280
- ...styleDefinitions !== void 0 ? { styles: styleDefinitions } : {},
281
- theme,
282
- numbering: numbering.definitions,
283
- ...fontTable ? { fontTable } : {},
284
- ...headers !== void 0 ? { headers } : {},
285
- ...footers !== void 0 ? { footers } : {},
286
- ...footnotes !== void 0 ? { footnotes } : {},
287
- ...endnotes !== void 0 ? { endnotes } : {},
288
- relationships: rels,
289
- media,
290
- ...properties !== void 0 ? { properties } : {}
291
- },
395
+ package: pkg,
292
396
  originalBuffer: raw.originalBuffer,
293
397
  ...templateVariables !== void 0 ? { templateVariables } : {},
294
398
  ...requiredFonts.length > 0 ? { requiredFonts } : {}
295
399
  };
400
+ const altChunkBudget = { remainingBytes: ALT_CHUNK_PLAIN_TEXT_LIMIT_BYTES };
401
+ await attachAltChunkPlainText(pkg.document.content, {
402
+ relationships: rels,
403
+ relationshipsPath: DOCUMENT_RELATIONSHIPS_PATH,
404
+ raw,
405
+ budget: altChunkBudget
406
+ });
407
+ const altChunkContextForPart = (partPath) => {
408
+ const relationshipsPath = getRelationshipsPathForPart(partPath);
409
+ const relationshipsXml = getMapCaseInsensitive(raw.allXml, relationshipsPath);
410
+ return {
411
+ relationships: relationshipsXml ? parseRelationships(relationshipsXml) : /* @__PURE__ */ new Map(),
412
+ relationshipsPath,
413
+ raw,
414
+ budget: altChunkBudget
415
+ };
416
+ };
417
+ for (const [rId, header] of pkg.headers ?? []) {
418
+ const relationship = rels.get(rId);
419
+ if (relationship?.target) {
420
+ const replayable = canReplayHeaderFooterVerbatim(header);
421
+ await attachAltChunkPlainText(header.content, altChunkContextForPart(getRelationshipPartPath(relationship.target)));
422
+ if (replayable) refreshHeaderFooterVerbatimFingerprint(header);
423
+ }
424
+ }
425
+ for (const [rId, footer] of pkg.footers ?? []) {
426
+ const relationship = rels.get(rId);
427
+ if (relationship?.target) {
428
+ const replayable = canReplayHeaderFooterVerbatim(footer);
429
+ await attachAltChunkPlainText(footer.content, altChunkContextForPart(getRelationshipPartPath(relationship.target)));
430
+ if (replayable) refreshHeaderFooterVerbatimFingerprint(footer);
431
+ }
432
+ }
433
+ const footnoteContext = altChunkContextForPart("word/footnotes.xml");
434
+ for (const footnote of pkg.footnotes ?? []) await attachAltChunkPlainText(footnote.content, footnoteContext);
435
+ const endnoteContext = altChunkContextForPart("word/endnotes.xml");
436
+ for (const endnote of pkg.endnotes ?? []) await attachAltChunkPlainText(endnote.content, endnoteContext);
437
+ const altChunkCount = countAltChunks(pkg.document.content) + [...pkg.headers?.values() ?? []].reduce((total, part) => total + countAltChunks(part.content), 0) + [...pkg.footers?.values() ?? []].reduce((total, part) => total + countAltChunks(part.content), 0) + (pkg.footnotes ?? []).reduce((total, part) => total + countAltChunks(part.content), 0) + (pkg.endnotes ?? []).reduce((total, part) => total + countAltChunks(part.content), 0);
438
+ if (altChunkCount > 0) parseContext.warn({
439
+ code: PARSE_WARNING_CODES.altChunkUnsupported,
440
+ element: "w:altChunk",
441
+ count: altChunkCount
442
+ });
443
+ const opaqueRevisionCount = countOpaqueRevisionCarriers(pkg.document.content) + [...pkg.headers?.values() ?? []].reduce((total, part) => total + countOpaqueRevisionCarriers(part.content), 0) + [...pkg.footers?.values() ?? []].reduce((total, part) => total + countOpaqueRevisionCarriers(part.content), 0) + (pkg.footnotes ?? []).reduce((total, part) => total + countOpaqueRevisionCarriers(part.content), 0) + (pkg.endnotes ?? []).reduce((total, part) => total + countOpaqueRevisionCarriers(part.content), 0);
444
+ if (opaqueRevisionCount > 0) parseContext.warn({
445
+ code: PARSE_WARNING_CODES.revisionCarrierOpaque,
446
+ element: "w:ins/w:del/w:moveFrom/w:moveTo",
447
+ count: opaqueRevisionCount
448
+ });
296
449
  assignDocumentParagraphPropertySourceContract(document, await paragraphPropertySourceDigest);
297
450
  previews.enforce(previewBudget);
298
451
  const validation = validateFolioDocumentModel(document);
@@ -585,7 +738,7 @@ function fullParseDocx(buffer, onProgress) {
585
738
  * Faster than full parse when you only need variables
586
739
  */
587
740
  async function getDocxVariables(buffer) {
588
- const raw = await unzipDocx(buffer);
741
+ const raw = await unzipDocx(buffer, {}, { verifyUnreadEntries: false });
589
742
  if (!raw.documentXml) return [];
590
743
  return extractAllTemplateVariables(parseDocumentBody(raw.documentXml).content);
591
744
  }
@@ -593,7 +746,7 @@ async function getDocxVariables(buffer) {
593
746
  * Get document summary without full parsing
594
747
  */
595
748
  async function getDocxSummary(buffer) {
596
- const raw = await unzipDocx(buffer);
749
+ const raw = await unzipDocx(buffer, {}, { verifyUnreadEntries: false });
597
750
  const variables = raw.documentXml ? extractAllTemplateVariables(parseDocumentBody(raw.documentXml).content) : [];
598
751
  return {
599
752
  hasDocument: raw.documentXml !== null,