@arbidocs/blocks 0.5.107 → 0.5.108

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 (341) hide show
  1. package/dist/{ConnectedCallDock-TDYRHPAK.js → ConnectedCallDock-DV4FU376.js} +8 -8
  2. package/dist/{ConnectedCallDock-TDYRHPAK.js.map → ConnectedCallDock-DV4FU376.js.map} +1 -1
  3. package/dist/{ConnectedCallDock-H3WWFGXF.cjs → ConnectedCallDock-EM2VVGZK.cjs} +10 -10
  4. package/dist/{ConnectedCallDock-H3WWFGXF.cjs.map → ConnectedCallDock-EM2VVGZK.cjs.map} +1 -1
  5. package/dist/{ConnectedCallRoom-55O5OUN7.cjs → ConnectedCallRoom-7WEPEWUJ.cjs} +9 -9
  6. package/dist/{ConnectedCallRoom-55O5OUN7.cjs.map → ConnectedCallRoom-7WEPEWUJ.cjs.map} +1 -1
  7. package/dist/{ConnectedCallRoom-Z6F6WCLH.js → ConnectedCallRoom-RYTZP34O.js} +8 -8
  8. package/dist/{ConnectedCallRoom-Z6F6WCLH.js.map → ConnectedCallRoom-RYTZP34O.js.map} +1 -1
  9. package/dist/{ConnectedNativeDocxComparison-NVZRVNOS.js → ConnectedNativeDocxComparison-2NDXXZLQ.js} +15 -15
  10. package/dist/{ConnectedNativeDocxComparison-NVZRVNOS.js.map → ConnectedNativeDocxComparison-2NDXXZLQ.js.map} +1 -1
  11. package/dist/{ConnectedNativeDocxComparison-DGBZJ4XA.cjs → ConnectedNativeDocxComparison-7HOY3AVI.cjs} +16 -16
  12. package/dist/{ConnectedNativeDocxComparison-DGBZJ4XA.cjs.map → ConnectedNativeDocxComparison-7HOY3AVI.cjs.map} +1 -1
  13. package/dist/{ConnectedNativeDocxEditor-R4WINUUB.cjs → ConnectedNativeDocxEditor-CUWDPHXN.cjs} +16 -16
  14. package/dist/{ConnectedNativeDocxEditor-R4WINUUB.cjs.map → ConnectedNativeDocxEditor-CUWDPHXN.cjs.map} +1 -1
  15. package/dist/{ConnectedNativeDocxEditor-RSVBN7DY.js → ConnectedNativeDocxEditor-SPZB6Y27.js} +14 -14
  16. package/dist/{ConnectedNativeDocxEditor-RSVBN7DY.js.map → ConnectedNativeDocxEditor-SPZB6Y27.js.map} +1 -1
  17. package/dist/{ConnectedProductionSetDialog-2DFBXE2X.js → ConnectedProductionSetDialog-N3EDG3SU.js} +4 -4
  18. package/dist/{ConnectedProductionSetDialog-2DFBXE2X.js.map → ConnectedProductionSetDialog-N3EDG3SU.js.map} +1 -1
  19. package/dist/{ConnectedProductionSetDialog-KYDPQ7SG.cjs → ConnectedProductionSetDialog-XAEFEN3N.cjs} +4 -4
  20. package/dist/{ConnectedProductionSetDialog-KYDPQ7SG.cjs.map → ConnectedProductionSetDialog-XAEFEN3N.cjs.map} +1 -1
  21. package/dist/{ConnectedStreamedWordArtifact-HLJ5IIOU.js → ConnectedStreamedWordArtifact-6LTGEAJO.js} +15 -15
  22. package/dist/ConnectedStreamedWordArtifact-6LTGEAJO.js.map +1 -0
  23. package/dist/{ConnectedStreamedWordArtifact-JQ34AOUU.cjs → ConnectedStreamedWordArtifact-HNCRKZTV.cjs} +16 -16
  24. package/dist/ConnectedStreamedWordArtifact-HNCRKZTV.cjs.map +1 -0
  25. package/dist/{DocumentReviewCard-7JSXRJZ2.js → DocumentReviewCard-RJD3CO32.js} +8 -8
  26. package/dist/{DocumentReviewCard-7JSXRJZ2.js.map → DocumentReviewCard-RJD3CO32.js.map} +1 -1
  27. package/dist/{DocumentReviewCard-C4HVT3WM.cjs → DocumentReviewCard-VON7LOOY.cjs} +8 -8
  28. package/dist/{DocumentReviewCard-C4HVT3WM.cjs.map → DocumentReviewCard-VON7LOOY.cjs.map} +1 -1
  29. package/dist/{FilesViewerDialog-IMQTZWKD.js → FilesViewerDialog-7SJGY72Q.js} +21 -21
  30. package/dist/{FilesViewerDialog-IMQTZWKD.js.map → FilesViewerDialog-7SJGY72Q.js.map} +1 -1
  31. package/dist/{FilesViewerDialog-UP7GFHYN.cjs → FilesViewerDialog-VIPTC6OT.cjs} +27 -27
  32. package/dist/{FilesViewerDialog-UP7GFHYN.cjs.map → FilesViewerDialog-VIPTC6OT.cjs.map} +1 -1
  33. package/dist/{RechartsRenderer-GIRCW7DB.cjs → RechartsRenderer-THES2SE5.cjs} +6 -5
  34. package/dist/RechartsRenderer-THES2SE5.cjs.map +1 -0
  35. package/dist/{RechartsRenderer-23OF4H6X.js → RechartsRenderer-XIZLV6GH.js} +6 -5
  36. package/dist/RechartsRenderer-XIZLV6GH.js.map +1 -0
  37. package/dist/{WorkspaceTableView-PJM47B5F.cjs → WorkspaceTableView-FNME7TL6.cjs} +9 -9
  38. package/dist/{WorkspaceTableView-PJM47B5F.cjs.map → WorkspaceTableView-FNME7TL6.cjs.map} +1 -1
  39. package/dist/{WorkspaceTableView-YDA7A4UJ.js → WorkspaceTableView-XQ6J2JKI.js} +7 -7
  40. package/dist/{WorkspaceTableView-YDA7A4UJ.js.map → WorkspaceTableView-XQ6J2JKI.js.map} +1 -1
  41. package/dist/agents/index.cjs +202 -202
  42. package/dist/agents/index.js +8 -8
  43. package/dist/{ai-ADS6YSS2.cjs → ai-3SAMEYBB.cjs} +20 -20
  44. package/dist/ai-3SAMEYBB.cjs.map +1 -0
  45. package/dist/{ai-KHWTGBT5.js → ai-OTQWSYVK.js} +12 -12
  46. package/dist/ai-OTQWSYVK.js.map +1 -0
  47. package/dist/calls/index.cjs +57 -57
  48. package/dist/calls/index.js +9 -9
  49. package/dist/chat/index.cjs +3 -3
  50. package/dist/chat/index.js +3 -3
  51. package/dist/{chunk-O27K7KTZ.cjs → chunk-2TBQBF4Y.cjs} +5 -5
  52. package/dist/{chunk-O27K7KTZ.cjs.map → chunk-2TBQBF4Y.cjs.map} +1 -1
  53. package/dist/{chunk-YJWAGXYM.js → chunk-4ZA2RSQH.js} +3 -3
  54. package/dist/{chunk-YJWAGXYM.js.map → chunk-4ZA2RSQH.js.map} +1 -1
  55. package/dist/{chunk-6A4GNM4T.cjs → chunk-5D2ZINOJ.cjs} +16 -16
  56. package/dist/{chunk-6A4GNM4T.cjs.map → chunk-5D2ZINOJ.cjs.map} +1 -1
  57. package/dist/{chunk-BFVCYBND.cjs → chunk-5HXQOM3I.cjs} +5 -5
  58. package/dist/{chunk-BFVCYBND.cjs.map → chunk-5HXQOM3I.cjs.map} +1 -1
  59. package/dist/{chunk-GSD5U553.cjs → chunk-5KKT65WU.cjs} +3 -3
  60. package/dist/{chunk-GSD5U553.cjs.map → chunk-5KKT65WU.cjs.map} +1 -1
  61. package/dist/{chunk-AVGHTUPE.js → chunk-5PWLXLHY.js} +5 -5
  62. package/dist/chunk-5PWLXLHY.js.map +1 -0
  63. package/dist/{chunk-BBWLFK3C.js → chunk-5XIMUQ63.js} +3 -3
  64. package/dist/{chunk-BBWLFK3C.js.map → chunk-5XIMUQ63.js.map} +1 -1
  65. package/dist/{chunk-AHMRYY7J.cjs → chunk-6DAJXQZZ.cjs} +13 -13
  66. package/dist/{chunk-AHMRYY7J.cjs.map → chunk-6DAJXQZZ.cjs.map} +1 -1
  67. package/dist/{chunk-3PV25ICC.js → chunk-6KKVJ2V6.js} +3 -3
  68. package/dist/{chunk-3PV25ICC.js.map → chunk-6KKVJ2V6.js.map} +1 -1
  69. package/dist/{chunk-OLAYDOPC.js → chunk-6LUHNFEE.js} +6 -6
  70. package/dist/{chunk-OLAYDOPC.js.map → chunk-6LUHNFEE.js.map} +1 -1
  71. package/dist/{chunk-FSXQHEFQ.cjs → chunk-7CDV7Y4U.cjs} +25 -25
  72. package/dist/{chunk-FSXQHEFQ.cjs.map → chunk-7CDV7Y4U.cjs.map} +1 -1
  73. package/dist/{chunk-OAIOOVFN.cjs → chunk-7SJXYEZI.cjs} +36 -36
  74. package/dist/chunk-7SJXYEZI.cjs.map +1 -0
  75. package/dist/{chunk-LFYKB7KF.cjs → chunk-7V6APLF7.cjs} +19 -19
  76. package/dist/{chunk-LFYKB7KF.cjs.map → chunk-7V6APLF7.cjs.map} +1 -1
  77. package/dist/{chunk-4WMGFGYP.cjs → chunk-AJZ66VJC.cjs} +4 -4
  78. package/dist/{chunk-4WMGFGYP.cjs.map → chunk-AJZ66VJC.cjs.map} +1 -1
  79. package/dist/{chunk-KCP42W67.cjs → chunk-ARGQ5YZ5.cjs} +3 -3
  80. package/dist/{chunk-KCP42W67.cjs.map → chunk-ARGQ5YZ5.cjs.map} +1 -1
  81. package/dist/{chunk-BH6IKGZ3.js → chunk-AUAHGQY6.js} +5 -5
  82. package/dist/{chunk-BH6IKGZ3.js.map → chunk-AUAHGQY6.js.map} +1 -1
  83. package/dist/{chunk-KIXFXCHL.js → chunk-CEOCA7ID.js} +3 -3
  84. package/dist/{chunk-KIXFXCHL.js.map → chunk-CEOCA7ID.js.map} +1 -1
  85. package/dist/{chunk-TNKPQ3EF.js → chunk-CIRSOYGK.js} +12 -12
  86. package/dist/{chunk-TNKPQ3EF.js.map → chunk-CIRSOYGK.js.map} +1 -1
  87. package/dist/{chunk-BAUZUIHB.js → chunk-COL2TJGO.js} +83 -83
  88. package/dist/chunk-COL2TJGO.js.map +1 -0
  89. package/dist/{chunk-XHN5KOI2.cjs → chunk-DRLD4P2C.cjs} +8 -8
  90. package/dist/{chunk-XHN5KOI2.cjs.map → chunk-DRLD4P2C.cjs.map} +1 -1
  91. package/dist/{chunk-5AC52BHL.cjs → chunk-DYPFNQTQ.cjs} +140 -140
  92. package/dist/chunk-DYPFNQTQ.cjs.map +1 -0
  93. package/dist/{chunk-SCLGUHLU.cjs → chunk-E7TGSOPR.cjs} +4 -4
  94. package/dist/{chunk-SCLGUHLU.cjs.map → chunk-E7TGSOPR.cjs.map} +1 -1
  95. package/dist/{chunk-CRLFLMTK.cjs → chunk-EOXA4VJH.cjs} +3 -3
  96. package/dist/{chunk-CRLFLMTK.cjs.map → chunk-EOXA4VJH.cjs.map} +1 -1
  97. package/dist/{chunk-DBKZANTC.js → chunk-GA47YVW5.js} +3 -3
  98. package/dist/{chunk-DBKZANTC.js.map → chunk-GA47YVW5.js.map} +1 -1
  99. package/dist/{chunk-RCZRI72J.cjs → chunk-GMODJT4N.cjs} +4 -4
  100. package/dist/{chunk-RCZRI72J.cjs.map → chunk-GMODJT4N.cjs.map} +1 -1
  101. package/dist/{chunk-22KAKJ3W.cjs → chunk-GS5MFUPC.cjs} +4 -4
  102. package/dist/{chunk-22KAKJ3W.cjs.map → chunk-GS5MFUPC.cjs.map} +1 -1
  103. package/dist/{chunk-62OMGQHS.js → chunk-H6W3VXHU.js} +3 -3
  104. package/dist/{chunk-62OMGQHS.js.map → chunk-H6W3VXHU.js.map} +1 -1
  105. package/dist/{chunk-DX3Z2COD.cjs → chunk-HUYKO2ES.cjs} +3 -3
  106. package/dist/{chunk-DX3Z2COD.cjs.map → chunk-HUYKO2ES.cjs.map} +1 -1
  107. package/dist/{chunk-U5F5P4YU.js → chunk-IK234EFX.js} +12 -12
  108. package/dist/{chunk-U5F5P4YU.js.map → chunk-IK234EFX.js.map} +1 -1
  109. package/dist/{chunk-UQ2OBHMV.js → chunk-JUGEFTRC.js} +1010 -1010
  110. package/dist/chunk-JUGEFTRC.js.map +1 -0
  111. package/dist/{chunk-CHQMVIHR.js → chunk-LPGBRMYS.js} +36 -36
  112. package/dist/chunk-LPGBRMYS.js.map +1 -0
  113. package/dist/{chunk-D35EHOK5.cjs → chunk-M23W7IID.cjs} +12 -12
  114. package/dist/chunk-M23W7IID.cjs.map +1 -0
  115. package/dist/{chunk-FPOKWML2.js → chunk-MIVNNQO3.js} +21 -4
  116. package/dist/chunk-MIVNNQO3.js.map +1 -0
  117. package/dist/{chunk-WI3BVKEC.cjs → chunk-MNFI66H5.cjs} +5 -5
  118. package/dist/{chunk-WI3BVKEC.cjs.map → chunk-MNFI66H5.cjs.map} +1 -1
  119. package/dist/{chunk-T5ZMG6MC.js → chunk-NF4M7PUB.js} +3 -3
  120. package/dist/{chunk-T5ZMG6MC.js.map → chunk-NF4M7PUB.js.map} +1 -1
  121. package/dist/{chunk-ZNY5W3VX.js → chunk-NPSFPBIB.js} +3 -3
  122. package/dist/{chunk-ZNY5W3VX.js.map → chunk-NPSFPBIB.js.map} +1 -1
  123. package/dist/{chunk-LYW5A35J.js → chunk-OMIYTUVR.js} +12 -12
  124. package/dist/{chunk-LYW5A35J.js.map → chunk-OMIYTUVR.js.map} +1 -1
  125. package/dist/{chunk-ZMVF7EYJ.cjs → chunk-PBPO54KZ.cjs} +21 -3
  126. package/dist/chunk-PBPO54KZ.cjs.map +1 -0
  127. package/dist/{chunk-7V4OCZS6.cjs → chunk-RA3EGF6K.cjs} +6 -6
  128. package/dist/{chunk-7V4OCZS6.cjs.map → chunk-RA3EGF6K.cjs.map} +1 -1
  129. package/dist/{chunk-PL7O3RJJ.cjs → chunk-RKBAY7GZ.cjs} +3 -3
  130. package/dist/{chunk-PL7O3RJJ.cjs.map → chunk-RKBAY7GZ.cjs.map} +1 -1
  131. package/dist/{chunk-J3E5CSSC.js → chunk-RKFWBIKS.js} +3 -3
  132. package/dist/{chunk-J3E5CSSC.js.map → chunk-RKFWBIKS.js.map} +1 -1
  133. package/dist/{chunk-YLKHTBYA.js → chunk-RRP7MQAO.js} +3 -3
  134. package/dist/{chunk-YLKHTBYA.js.map → chunk-RRP7MQAO.js.map} +1 -1
  135. package/dist/{chunk-U6LQ6Z3P.cjs → chunk-SP3IKIPA.cjs} +6 -6
  136. package/dist/{chunk-U6LQ6Z3P.cjs.map → chunk-SP3IKIPA.cjs.map} +1 -1
  137. package/dist/{chunk-GX75YCWJ.cjs → chunk-SQUOXOY3.cjs} +560 -560
  138. package/dist/chunk-SQUOXOY3.cjs.map +1 -0
  139. package/dist/{chunk-6ZYOUT73.js → chunk-T5LORFHL.js} +7 -7
  140. package/dist/{chunk-6ZYOUT73.js.map → chunk-T5LORFHL.js.map} +1 -1
  141. package/dist/{chunk-45OU2UAA.cjs → chunk-TEMTKBBL.cjs} +10 -10
  142. package/dist/{chunk-45OU2UAA.cjs.map → chunk-TEMTKBBL.cjs.map} +1 -1
  143. package/dist/{chunk-PHDUN4SG.cjs → chunk-THCMGAFX.cjs} +41 -41
  144. package/dist/{chunk-PHDUN4SG.cjs.map → chunk-THCMGAFX.cjs.map} +1 -1
  145. package/dist/{chunk-HTGEAQOA.js → chunk-TOMDMKOD.js} +7 -7
  146. package/dist/{chunk-HTGEAQOA.js.map → chunk-TOMDMKOD.js.map} +1 -1
  147. package/dist/{chunk-WJHRWXWJ.js → chunk-TXIAF4PX.js} +3 -3
  148. package/dist/{chunk-WJHRWXWJ.js.map → chunk-TXIAF4PX.js.map} +1 -1
  149. package/dist/{chunk-6M5NAAWX.js → chunk-UCSEE52D.js} +3 -3
  150. package/dist/{chunk-6M5NAAWX.js.map → chunk-UCSEE52D.js.map} +1 -1
  151. package/dist/{chunk-I7CJDF3V.cjs → chunk-UHMP6S7M.cjs} +104 -103
  152. package/dist/chunk-UHMP6S7M.cjs.map +1 -0
  153. package/dist/{chunk-PGCKTXYH.js → chunk-UHUI6A36.js} +3 -3
  154. package/dist/{chunk-PGCKTXYH.js.map → chunk-UHUI6A36.js.map} +1 -1
  155. package/dist/{chunk-6KQVTMRL.cjs → chunk-UOGXKHTJ.cjs} +3 -3
  156. package/dist/{chunk-6KQVTMRL.cjs.map → chunk-UOGXKHTJ.cjs.map} +1 -1
  157. package/dist/{chunk-7S7YVBFK.js → chunk-VDSDG4FR.js} +3 -3
  158. package/dist/{chunk-7S7YVBFK.js.map → chunk-VDSDG4FR.js.map} +1 -1
  159. package/dist/{chunk-3GFQNJYE.js → chunk-VGWCHX6G.js} +104 -103
  160. package/dist/chunk-VGWCHX6G.js.map +1 -0
  161. package/dist/{chunk-VY3HTT37.js → chunk-VUH547VQ.js} +3 -3
  162. package/dist/{chunk-VY3HTT37.js.map → chunk-VUH547VQ.js.map} +1 -1
  163. package/dist/{chunk-AZCMKGDG.js → chunk-W37PFYFL.js} +4 -4
  164. package/dist/{chunk-AZCMKGDG.js.map → chunk-W37PFYFL.js.map} +1 -1
  165. package/dist/{chunk-JGUM4EXE.cjs → chunk-W3IX3GZS.cjs} +8 -8
  166. package/dist/{chunk-JGUM4EXE.cjs.map → chunk-W3IX3GZS.cjs.map} +1 -1
  167. package/dist/{chunk-UCA4JLLJ.cjs → chunk-X7GT57KW.cjs} +3 -3
  168. package/dist/{chunk-UCA4JLLJ.cjs.map → chunk-X7GT57KW.cjs.map} +1 -1
  169. package/dist/{chunk-IXL2KJOZ.cjs → chunk-XBEGD33U.cjs} +40 -40
  170. package/dist/{chunk-IXL2KJOZ.cjs.map → chunk-XBEGD33U.cjs.map} +1 -1
  171. package/dist/{chunk-FDNIK5YS.cjs → chunk-XBKIFGBB.cjs} +8 -8
  172. package/dist/{chunk-FDNIK5YS.cjs.map → chunk-XBKIFGBB.cjs.map} +1 -1
  173. package/dist/{chunk-HZE5MHQO.js → chunk-XT7HKQ4H.js} +3 -3
  174. package/dist/{chunk-HZE5MHQO.js.map → chunk-XT7HKQ4H.js.map} +1 -1
  175. package/dist/{chunk-M3OK6KGR.js → chunk-ZGQKED5T.js} +3 -3
  176. package/dist/{chunk-M3OK6KGR.js.map → chunk-ZGQKED5T.js.map} +1 -1
  177. package/dist/{chunk-NWBCZ4PA.js → chunk-ZKBYG6MN.js} +4 -4
  178. package/dist/{chunk-NWBCZ4PA.js.map → chunk-ZKBYG6MN.js.map} +1 -1
  179. package/dist/collaboration/index.cjs +1 -1
  180. package/dist/collaboration/index.js +1 -1
  181. package/dist/connect/docx.cjs +19 -19
  182. package/dist/connect/docx.js +15 -15
  183. package/dist/connect/index.cjs +762 -762
  184. package/dist/connect/index.js +63 -63
  185. package/dist/connect/viewer.cjs +14 -14
  186. package/dist/connect/viewer.js +13 -13
  187. package/dist/connection/dashboards/ConnectedDashboardsPage.d.ts +6 -0
  188. package/dist/dashboards/chartModel.d.ts +12 -0
  189. package/dist/dashboards/index.cjs +113 -42
  190. package/dist/dashboards/index.cjs.map +1 -1
  191. package/dist/dashboards/index.js +95 -24
  192. package/dist/dashboards/index.js.map +1 -1
  193. package/dist/embed/index.cjs +29 -29
  194. package/dist/embed/index.js +23 -23
  195. package/dist/facts/index.cjs +43 -43
  196. package/dist/facts/index.js +2 -2
  197. package/dist/files/index.cjs +1 -1
  198. package/dist/files/index.js +1 -1
  199. package/dist/home/index.cjs +31 -31
  200. package/dist/home/index.js +3 -3
  201. package/dist/index.cjs +383 -383
  202. package/dist/index.js +21 -21
  203. package/dist/settings/index.cjs +153 -153
  204. package/dist/settings/index.js +4 -4
  205. package/dist/shell/index.cjs +36 -36
  206. package/dist/shell/index.js +4 -4
  207. package/dist/site/index.cjs +5 -5
  208. package/dist/site/index.js +1 -1
  209. package/dist/studio/index.cjs +19 -19
  210. package/dist/studio/index.js +14 -14
  211. package/dist/styles.css +1 -1
  212. package/dist/workflow-canvas/index.cjs +33 -33
  213. package/dist/workflow-canvas/index.js +22 -22
  214. package/node_modules/@arbidocs/coedit/package.json +2 -2
  215. package/node_modules/@docx-editor.dev/core/dist/automation.cjs +1 -1
  216. package/node_modules/@docx-editor.dev/core/dist/automation.d.ts +60 -13
  217. package/node_modules/@docx-editor.dev/core/dist/automation.js +1 -1
  218. package/node_modules/@docx-editor.dev/core/dist/binding.cjs +1 -1
  219. package/node_modules/@docx-editor.dev/core/dist/binding.d.ts +21 -13
  220. package/node_modules/@docx-editor.dev/core/dist/binding.js +1 -1
  221. package/node_modules/@docx-editor.dev/core/dist/{index-Bsg7oIKP.d.ts → chrome-print-CAs51cpq.d.ts} +31 -21
  222. package/node_modules/@docx-editor.dev/core/dist/{chunk-VDNNLG6X.js → chunk-236O4YQW.js} +1 -1
  223. package/node_modules/@docx-editor.dev/core/dist/chunk-4HENIAFG.js +1 -0
  224. package/node_modules/@docx-editor.dev/core/dist/{chunk-SRPILEWV.cjs → chunk-6JPL6ZAS.cjs} +5 -5
  225. package/node_modules/@docx-editor.dev/core/dist/{chunk-2RC2EPND.js → chunk-6ZQP4HQ7.js} +1 -1
  226. package/node_modules/@docx-editor.dev/core/dist/{chunk-ZUHOMK52.cjs → chunk-7WQ7AAHW.cjs} +1 -1
  227. package/node_modules/@docx-editor.dev/core/dist/{chunk-Z6WBFXJU.js → chunk-BCXH4BXB.js} +3 -3
  228. package/node_modules/@docx-editor.dev/core/dist/{chunk-QMLCVPCD.cjs → chunk-BY2ACZZ6.cjs} +1 -1
  229. package/node_modules/@docx-editor.dev/core/dist/chunk-CAJEXXVG.cjs +4 -0
  230. package/node_modules/@docx-editor.dev/core/dist/chunk-CPWLFPWC.js +30 -0
  231. package/node_modules/@docx-editor.dev/core/dist/{chunk-6APGXLBB.cjs → chunk-D7ZMDMPX.cjs} +2 -2
  232. package/node_modules/@docx-editor.dev/core/dist/chunk-DOHF6FA7.cjs +30 -0
  233. package/node_modules/@docx-editor.dev/core/dist/chunk-DVX32P2P.js +27 -0
  234. package/node_modules/@docx-editor.dev/core/dist/{chunk-6EYYL7FL.js → chunk-E4LOMDNL.js} +1 -1
  235. package/node_modules/@docx-editor.dev/core/dist/chunk-EKLM7NWB.cjs +7 -0
  236. package/node_modules/@docx-editor.dev/core/dist/chunk-G3K63G7P.cjs +27 -0
  237. package/node_modules/@docx-editor.dev/core/dist/{chunk-5CSUYANV.js → chunk-G4HOFIKJ.js} +1 -1
  238. package/node_modules/@docx-editor.dev/core/dist/{chunk-K5U2PLDP.cjs → chunk-JLVBDYVQ.cjs} +1 -1
  239. package/node_modules/@docx-editor.dev/core/dist/chunk-LQX36Z5P.js +7 -0
  240. package/node_modules/@docx-editor.dev/core/dist/{chunk-TSLBZ26X.js → chunk-LSZ6KPKK.js} +1 -1
  241. package/node_modules/@docx-editor.dev/core/dist/{chunk-O2AL2HSJ.cjs → chunk-MM5QBMTE.cjs} +1 -1
  242. package/node_modules/@docx-editor.dev/core/dist/{chunk-ETTO6GK3.js → chunk-OMCG63ZF.js} +1 -1
  243. package/node_modules/@docx-editor.dev/core/dist/chunk-OSFOJTHU.cjs +18 -0
  244. package/node_modules/@docx-editor.dev/core/dist/{chunk-E7BQA6UP.js → chunk-RCLZXP3B.js} +1 -1
  245. package/node_modules/@docx-editor.dev/core/dist/chunk-T6K2QYNZ.cjs +2 -0
  246. package/node_modules/@docx-editor.dev/core/dist/chunk-TRGAVV2Y.js +4 -0
  247. package/node_modules/@docx-editor.dev/core/dist/chunk-U4JZVSOE.js +2 -0
  248. package/node_modules/@docx-editor.dev/core/dist/{chunk-2GO5T2JU.cjs → chunk-UHHYFIDT.cjs} +1 -1
  249. package/node_modules/@docx-editor.dev/core/dist/chunk-V3N4SOAK.cjs +1 -0
  250. package/node_modules/@docx-editor.dev/core/dist/{chunk-6AWEKBLB.cjs → chunk-W35WTWAO.cjs} +1 -1
  251. package/node_modules/@docx-editor.dev/core/dist/chunk-YQ5G6LC7.js +18 -0
  252. package/node_modules/@docx-editor.dev/core/dist/collaboration/replication.cjs +1 -1
  253. package/node_modules/@docx-editor.dev/core/dist/collaboration/replication.d.ts +5 -5
  254. package/node_modules/@docx-editor.dev/core/dist/collaboration/replication.js +1 -1
  255. package/node_modules/@docx-editor.dev/core/dist/collaboration.d.ts +4 -4
  256. package/node_modules/@docx-editor.dev/core/dist/contracts/document.d.ts +3 -3
  257. package/node_modules/@docx-editor.dev/core/dist/contracts/editor.d.ts +9 -10
  258. package/node_modules/@docx-editor.dev/core/dist/contracts/interaction.d.ts +2 -2
  259. package/node_modules/@docx-editor.dev/core/dist/contracts/modules.cjs +1 -1
  260. package/node_modules/@docx-editor.dev/core/dist/contracts/modules.d.ts +33 -9
  261. package/node_modules/@docx-editor.dev/core/dist/contracts/modules.js +1 -1
  262. package/node_modules/@docx-editor.dev/core/dist/contracts/types.d.ts +2 -2
  263. package/node_modules/@docx-editor.dev/core/dist/{custom-node-writes-cvL5rhcD.d.ts → custom-node-writes-Bn6uciLb.d.ts} +2 -2
  264. package/node_modules/@docx-editor.dev/core/dist/diagnostic-context-B8M79cfK.d.ts +30 -0
  265. package/node_modules/@docx-editor.dev/core/dist/diagnostic-hints-BeVjfNOv.d.ts +113 -0
  266. package/node_modules/@docx-editor.dev/core/dist/{document-protection-BAGVGqaP.d.ts → document-protection-CUb55pl_.d.ts} +2 -2
  267. package/node_modules/@docx-editor.dev/core/dist/{editor-Ci7IZGmG.d.ts → editor-CZQZmTIU.d.ts} +386 -9
  268. package/node_modules/@docx-editor.dev/core/dist/{editor-scope-OHPwVQ5l.d.ts → editor-scope-7o9xweiJ.d.ts} +1 -1
  269. package/node_modules/@docx-editor.dev/core/dist/editor.cjs +1 -1
  270. package/node_modules/@docx-editor.dev/core/dist/editor.d.ts +54 -33
  271. package/node_modules/@docx-editor.dev/core/dist/editor.js +1 -1
  272. package/node_modules/@docx-editor.dev/core/dist/export.cjs +2 -2
  273. package/node_modules/@docx-editor.dev/core/dist/export.d.ts +13 -14
  274. package/node_modules/@docx-editor.dev/core/dist/export.js +1 -1
  275. package/node_modules/@docx-editor.dev/core/dist/{font-resolver-BVQB14qT.d.ts → font-resolver-lSBLirLR.d.ts} +3 -3
  276. package/node_modules/@docx-editor.dev/core/dist/{headless-document-view-qH331moE.d.ts → headless-document-view-pp3q7wIh.d.ts} +2 -2
  277. package/node_modules/@docx-editor.dev/core/dist/{image-resources-BN-hUgCn.d.ts → image-resources-tXLQShoC.d.ts} +2 -2
  278. package/node_modules/@docx-editor.dev/core/dist/index.cjs +1 -1
  279. package/node_modules/@docx-editor.dev/core/dist/index.d.ts +65 -20
  280. package/node_modules/@docx-editor.dev/core/dist/index.js +1 -1
  281. package/node_modules/@docx-editor.dev/core/dist/{layout-shaping-BEyuiQOk.d.ts → layout-shaping-BD-dF_rn.d.ts} +1 -1
  282. package/node_modules/@docx-editor.dev/core/dist/layout.cjs +1 -1
  283. package/node_modules/@docx-editor.dev/core/dist/layout.d.ts +17 -20
  284. package/node_modules/@docx-editor.dev/core/dist/layout.js +1 -1
  285. package/node_modules/@docx-editor.dev/core/dist/{note-properties-4Y9o6Gyk.d.ts → note-properties-qQUjO1GQ.d.ts} +3 -3
  286. package/node_modules/@docx-editor.dev/core/dist/{omml-equation-CuzBL5DD.d.ts → omml-equation-BUbU0utM.d.ts} +1 -1
  287. package/node_modules/@docx-editor.dev/core/dist/output.cjs +1 -1
  288. package/node_modules/@docx-editor.dev/core/dist/output.d.ts +8 -9
  289. package/node_modules/@docx-editor.dev/core/dist/output.js +1 -1
  290. package/node_modules/@docx-editor.dev/core/dist/{protocol-Bqk4Izjc.d.ts → protocol-DYzzz2ej.d.ts} +2 -2
  291. package/node_modules/@docx-editor.dev/core/dist/{review-paragraph-order-DT-n6ouC.d.ts → review-paragraph-order-CN_0l2Cb.d.ts} +1 -1
  292. package/node_modules/@docx-editor.dev/core/dist/{semantic-cell-selection-D9D1KSXq.d.ts → semantic-cell-selection-eYag3P47.d.ts} +4 -211
  293. package/node_modules/@docx-editor.dev/core/dist/{semantic-interaction-CIC-PooQ.d.ts → semantic-interaction-kR_QB845.d.ts} +1 -1
  294. package/node_modules/@docx-editor.dev/core/dist/{semantic-paint-BME37OMv.d.ts → semantic-paint-ZayFF3tD.d.ts} +17 -5
  295. package/node_modules/@docx-editor.dev/core/dist/{semantic-record-queries-CBlZqZNa.d.ts → semantic-record-queries-Bsgth6lv.d.ts} +1 -1
  296. package/node_modules/@docx-editor.dev/core/dist/{semantic-records-4B3WwFAi.d.ts → semantic-records-DQmumPgL.d.ts} +1279 -828
  297. package/node_modules/@docx-editor.dev/core/dist/store.cjs +1 -1
  298. package/node_modules/@docx-editor.dev/core/dist/store.d.ts +1466 -1464
  299. package/node_modules/@docx-editor.dev/core/dist/store.js +1 -1
  300. package/node_modules/@docx-editor.dev/core/dist/{tree-package-fragment-BeeKxDw8.d.ts → tree-package-store-CovjNARF.d.ts} +83 -83
  301. package/node_modules/@docx-editor.dev/core/dist/{tree-session-contract-CVbmlMlq.d.ts → tree-session-contract-CZVAGl51.d.ts} +6 -6
  302. package/node_modules/@docx-editor.dev/core/dist/{types-barrel-D3xCgQX6.d.ts → types-barrel-DuC5QBNC.d.ts} +548 -527
  303. package/node_modules/@docx-editor.dev/core/package.json +3 -3
  304. package/node_modules/@docx-editor.dev/react/dist/index.js +3 -3
  305. package/node_modules/@docx-editor.dev/react/dist/index.mjs +3 -3
  306. package/node_modules/@docx-editor.dev/react/package.json +4 -4
  307. package/package.json +8 -8
  308. package/dist/ConnectedStreamedWordArtifact-HLJ5IIOU.js.map +0 -1
  309. package/dist/ConnectedStreamedWordArtifact-JQ34AOUU.cjs.map +0 -1
  310. package/dist/RechartsRenderer-23OF4H6X.js.map +0 -1
  311. package/dist/RechartsRenderer-GIRCW7DB.cjs.map +0 -1
  312. package/dist/ai-ADS6YSS2.cjs.map +0 -1
  313. package/dist/ai-KHWTGBT5.js.map +0 -1
  314. package/dist/chunk-3GFQNJYE.js.map +0 -1
  315. package/dist/chunk-5AC52BHL.cjs.map +0 -1
  316. package/dist/chunk-AVGHTUPE.js.map +0 -1
  317. package/dist/chunk-BAUZUIHB.js.map +0 -1
  318. package/dist/chunk-CHQMVIHR.js.map +0 -1
  319. package/dist/chunk-D35EHOK5.cjs.map +0 -1
  320. package/dist/chunk-FPOKWML2.js.map +0 -1
  321. package/dist/chunk-GX75YCWJ.cjs.map +0 -1
  322. package/dist/chunk-I7CJDF3V.cjs.map +0 -1
  323. package/dist/chunk-OAIOOVFN.cjs.map +0 -1
  324. package/dist/chunk-UQ2OBHMV.js.map +0 -1
  325. package/dist/chunk-ZMVF7EYJ.cjs.map +0 -1
  326. package/node_modules/@docx-editor.dev/core/dist/chunk-4GBTELJV.cjs +0 -28
  327. package/node_modules/@docx-editor.dev/core/dist/chunk-4R3TEXMN.js +0 -18
  328. package/node_modules/@docx-editor.dev/core/dist/chunk-EO4C5QJW.cjs +0 -2
  329. package/node_modules/@docx-editor.dev/core/dist/chunk-FIJZIQXA.cjs +0 -18
  330. package/node_modules/@docx-editor.dev/core/dist/chunk-FRXAOVTB.js +0 -28
  331. package/node_modules/@docx-editor.dev/core/dist/chunk-J6BVWIDB.js +0 -2
  332. package/node_modules/@docx-editor.dev/core/dist/chunk-JGNVNT2A.cjs +0 -2
  333. package/node_modules/@docx-editor.dev/core/dist/chunk-KKIJG3C6.js +0 -2
  334. package/node_modules/@docx-editor.dev/core/dist/chunk-LWDSDCMO.js +0 -27
  335. package/node_modules/@docx-editor.dev/core/dist/chunk-NBCVVZOM.cjs +0 -1
  336. package/node_modules/@docx-editor.dev/core/dist/chunk-O5INAWZQ.js +0 -1
  337. package/node_modules/@docx-editor.dev/core/dist/chunk-RCHS4ZEH.cjs +0 -27
  338. package/node_modules/@docx-editor.dev/core/dist/chunk-VHAVHCQY.js +0 -7
  339. package/node_modules/@docx-editor.dev/core/dist/chunk-VX43VBAX.cjs +0 -7
  340. package/node_modules/@docx-editor.dev/core/dist/review-pane-D9jm8DcY.d.ts +0 -128
  341. package/node_modules/@docx-editor.dev/core/dist/revision-projection-DZ4kKVev.d.ts +0 -242
@@ -12,21 +12,21 @@
12
12
  * @packageDocumentation
13
13
  * @public
14
14
  */
15
- import { e as ResourceLimits } from './image-resources-BN-hUgCn.js';
16
- export { C as CreateImageResourceCacheOptions, D as DEFAULT_IMAGE_RESOURCE_LIMITS, f as DEFAULT_LIMITS, H as HARD_CEILINGS, g as IMAGE_RESOURCE_HARD_CEILINGS, a as ImageDecodePort, I as ImageResourceLimits, h as ImageResourceLookup, b as ImageResourceState, M as MAX_SVG_SNIFF_BYTES, P as PreservedImageMime, R as RenderableImageMime, S as SupportedImageMime, V as ValidatedImageBytesHandle, i as ValidatedRasterHeader, j as createImageResourceCache, k as hasBoundedSvgRoot, l as imageResourceLookupFor, m as liveDrawingReferenceCount, r as resolveImageResourceLimits, n as resolveLimits, s as sniffImageMime, o as validateGifHeader, p as validateJpegHeader, q as validatePngHeader, v as validateRasterHeader } from './image-resources-BN-hUgCn.js';
17
- import { O as OoxmlPart, N as OoxmlNode, aP as OoxmlInvariantResult, aQ as OoxmlInvariantIssue, Z as OoxmlElement, ab as OoxmlParagraphNode, aR as OoxmlFldCharNode, aS as OoxmlFldSimpleNode, aT as OoxmlInstrTextNode, W as TreeDocOp, a8 as TreeOpRejection, aU as TreeOpResult, Q as OoxmlPackage, aV as RelationshipRecord, V as OoxmlGenericElementNode, aW as OoxmlHardBreakNode, aX as OoxmlAttribute, X as OoxmlProperty, f as ReviewRange, R as ReviewModelInput, a as ReviewItem, C as CommentRecord, e as ReviewPosition, aY as CommentThreadState, c as ReviewCommentItem, b as ReviewRevisionItem, aj as DrawingTreeDocOp, ak as ImpactClass, an as ImageWrapTarget } from './types-barrel-D3xCgQX6.js';
18
- export { aZ as ACCEPTED_PARAGRAPH_PROPERTIES, a_ as ACCEPTED_RUN_PROPERTIES, a$ as CONTENT_CONTROL_ID_MAX, b0 as CONTENT_CONTROL_PROPERTY_ORDER, b1 as CommentAnchor, b2 as CommentPosition, b3 as CommitTextFormFieldOp, b4 as ContentControlCheckbox, b5 as ContentControlCheckboxState, b6 as ContentControlDataBinding, b7 as ContentControlDateFormat, b8 as ContentControlEntry, b9 as ContentControlKind, ba as ContentControlLevel, bb as ContentControlListItem, bc as ContentControlLock, bd as ContentControlProperties, be as ContentTypeError, bf as ContentTypeIndex, bg as ContentTypeRecords, bh as DEFAULT_OOXML_PACKAGE_LIMITS, bi as DEFAULT_ZIP_LIMITS, bj as DefaultRecord, bk as DeleteTextOp, aL as DrawingImageEffects, am as DrawingKind, ap as DrawingLocks, ao as DrawingPositionInput, bl as HYPERLINK_RELATIONSHIP_TYPE, bm as HyperlinkKind, bn as HyperlinkTarget, bo as IMAGE_RELATIONSHIP_TYPE, aH as IMAGE_WRAP_TARGETS, bp as ImageRelationshipResolution, bq as IndexResult, br as InsertBuildingBlockOp, bs as InsertTextOp, bt as LegacyCheckboxFieldRange, bu as MAX_CONTENT_CONTROLS_PER_PART, bv as MAX_CONTENT_CONTROL_NESTING, bw as NameRejection, bx as NameResult, by as OFFICE_RELATIONSHIP_NAMESPACE_URI, bz as OOXML_NODE_IDENTITY_RULES, bA as OoxmlBodyNode, bB as OoxmlBookmarkEndNode, bC as OoxmlBookmarkStartNode, bD as OoxmlContentControlCalendarNode, bE as OoxmlContentControlCheckboxNode, bF as OoxmlContentControlCheckedNode, bG as OoxmlContentControlCheckedStateNode, bH as OoxmlContentControlComboBoxNode, $ as OoxmlContentControlContentNode, bI as OoxmlContentControlDataBindingNode, bJ as OoxmlContentControlDateFormatNode, bK as OoxmlContentControlDateNode, bL as OoxmlContentControlDropDownListNode, bM as OoxmlContentControlEndPropertiesNode, bN as OoxmlContentControlLidNode, bO as OoxmlContentControlListItemNode, _ as OoxmlContentControlNode, bP as OoxmlContentControlPropertiesNode, bQ as OoxmlContentControlStoreMappedDataAsNode, bR as OoxmlContentControlTextNode, bS as OoxmlContentControlUncheckedStateNode, ad as OoxmlContinuationSeparatorNode, bT as OoxmlDocumentNode, ae as OoxmlEndnotesNode, bU as OoxmlExternalTarget, af as OoxmlFootnotesNode, bV as OoxmlGenericExtensionAttribute, bW as OoxmlHyperlinkNode, bX as OoxmlInvariantIssueCode, bY as OoxmlKnownNodeAttribute, bZ as OoxmlNamespaceBinding, U as OoxmlNodeId, b_ as OoxmlNodeIdentityRules, ac as OoxmlNoteNode, ag as OoxmlNoteRefNode, ah as OoxmlNoteReferenceNode, a1 as OoxmlPackageLimits, Y as OoxmlPackageRejection, b$ as OoxmlPackageResult, c0 as OoxmlParagraphPropertiesNode, c1 as OoxmlPartMetadata, c2 as OoxmlReadRejection, c3 as OoxmlReadResult, c4 as OoxmlRunNode, c5 as OoxmlRunPropertiesNode, ai as OoxmlSeparatorNode, c6 as OoxmlTabNode, c7 as OoxmlTextElementNode, c8 as OoxmlTextNode, c9 as OoxmlWmlValAttribute, ca as OoxmlXmlSpaceAttribute, cb as OverrideRecord, cc as RelationshipError, cd as RelationshipSetResult, ce as RelationshipTargetResolver, cf as ResolveResult, cg as ResolvedRelationship, d as ReviewCustomItem, g as ReviewRevisionKind, h as RevisionAddress, a2 as RevisionAuthorEntry, a3 as RevisionAuthorResult, a4 as RevisionAuthorSkipReason, a5 as RevisionBatchEntry, a6 as RevisionBatchResult, a7 as RevisionBatchSkipReason, ch as SetLegacyCheckboxOp, ci as SetLegacyDropdownOp, cj as SetTextFormFieldDefaultOp, al as SourceCrop, ck as TABLE_BORDER_STYLES, cl as TabStopWrite, aJ as TableBorderStyle, cm as TargetMode, cn as TextFormFieldOptions, co as TextFormFieldRange, cp as TextFormFieldType, cq as TreeDocOpKind, cr as TreeOpEffect, cs as W15_NAMESPACE_URI, ct as WML_NAMESPACE_URI, cu as XMLNS_NAMESPACE_URI, cv as XML_NAMESPACE_URI, cw as XmlLimits, cx as XmlNode, cy as XmlRejection, cz as XmlResult, cA as ZipLimits, cB as ZipReadResult, cC as ZipRejection, cD as allocateContentControlId, cE as asciiFold, cF as buildContentTypeIndex, cG as buildRelationshipSet, cH as childElements, cI as commentAnchorsOfStory, cJ as commentsOfPart, cK as contentControlContentChildren, cL as contentControlContentNodeOf, cM as contentControlEndPropertiesNodeOf, cN as contentControlLevelOf, cO as contentControlPropertiesNodeOf, cP as contentControlPropertiesOf, cQ as contentControlTextOf, cR as contentControlsIn, cS as detectDuplicateNames, cT as extensionKey, cU as findContentControl, cV as findElement, cW as firstReviewRange, cX as flattenContentControls, cY as hasAnyComment, cZ as hyperlinkAnchorOf, c_ as hyperlinkRelationshipIdOf, c$ as hyperlinkTargetOf, d0 as isContentControlContentNode, d1 as isContentControlNode, d2 as isContentControlWrapper, d3 as isContentRevisionKind, d4 as isHyperlinkNode, d5 as isRangeMarkerKind, d6 as isValidMime, d7 as legacyCheckboxFieldsOf, d8 as lockForbidsEdit, d9 as lockForbidsRemoval, da as normalizePartName, db as orderedContentControlProperties, dc as parseContentControlId, dd as partNameKey, de as planRevisionAuthorChange, df as planRevisionBatch, dg as projectDrawing, dh as readOnOffChild, di as readOoxmlPackage, dj as readOoxmlPart, dk as readXml, dl as readZip, dm as resolveContentControlLock, dn as resolveContentType, dp as resolveImageRelationship, dq as resolveInternalTarget, dr as resolveRelationship, ds as reviewItemKey, dt as reviewItemRanges, du as textContent, dv as textFormFieldsOf, dw as threadStateOfPart, dx as validateExternalTarget, dy as withPart, dz as writeOoxmlPackage, dA as writeZip } from './types-barrel-D3xCgQX6.js';
19
- import { k as FieldResultsMode, e as TreeModelChange, f as TreeDocumentStore, T as TreePackageStore, S as StoryScope } from './tree-package-fragment-BeeKxDw8.js';
20
- export { l as AtomicNoteSpan, C as CascadeDeletedNoteReferencesOptions, D as DEFAULT_MAX_EDITABLE_STORY_PARTS, m as DrawingPropertyIdResult, F as FragmentPasteInput, j as FragmentPasteResult, n as HeaderFooterKind, o as HeaderFooterLifecycleImpact, p as HeaderFooterLifecycleOp, q as HeaderFooterLifecycleRejection, s as HeaderFooterLifecycleResult, H as HeaderFooterParts, b as HeaderFooterSectionResolution, t as HeaderFooterSlotMeta, c as HeaderFooterVariant, u as HistoryCaptureKind, d as HistoryGroup, M as MAX_FRAGMENT_DECODED_BYTES, v as MAX_NOTES_PER_PART, w as MAX_NOTE_REFERENCE_PARTS, x as MAX_NOTE_REFERENCE_SCAN, y as NOTE_ATOM_CHAR, z as NOTE_CONTINUATION_SEPARATOR_ID, B as NOTE_ID_MAX, E as NOTE_ID_MIN, G as NOTE_SEPARATOR_ID, J as NoteDiagnostic, K as NoteDiagnosticCode, N as NoteKind, L as NoteLifecycleImpact, O as NoteLifecycleOp, P as NoteLifecycleOptions, Q as NoteLifecycleRejection, U as NoteLifecycleResult, V as NoteReferenceHit, W as NoteReferenceScanBudget, X as NoteType, Y as PackageTransactResult, Z as RemotePackageAttribution, g as SelectionMark, _ as StoryResolveResult, a as StoryTargetRejection, $ as TreeDocumentStoreOptions, a0 as TreePackageStoreOptions, a1 as TreeStoryRef, h as TreeTransactOptions, a2 as TreeTransactResult, a3 as TreeTransactionContext, a4 as allocateDrawingPropertyId, a5 as allocateNoteId, a6 as applyFragmentPaste, a7 as applyHeaderFooterLifecycleOp, a8 as applyNoteLifecycleOp, a9 as atomicNoteSpansOf, aa as cascadeDeletedNoteReferences, ab as collectNoteReferences, ac as collectPackageNoteReferences, ad as collectSectionPropertyNodes, ae as createNoteReferenceScanBudget, af as customMarkFollows, ag as diagnoseNoteReferences, ah as findNoteById, ai as formatNoteScopeId, aj as isContinuationSeparatorNode, ak as isEndnotesNode, al as isFootnotesNode, am as isHeaderFooterLifecycleOp, an as isNormalNote, ao as isNoteAtomNode, ap as isNoteLifecycleOp, aq as isNoteNode, ar as isNoteRefNode, as as isNoteReferenceNode, at as isSeparatorNode, au as normalNoteIds, av as noteAtomText, aw as noteIdOf, ax as noteKindOf, ay as noteRefKindOf, az as noteReferenceKindOf, aA as noteTypeOf, aB as notesOf, aC as notesPartHasId, aD as observeHistoryGroup, aE as parseNoteId, aF as parseNoteScopeId, r as reportHistoryGroup, aG as resolveHeaderFooterParts, aH as resolveHeaderFooterPartsBySection, aI as resolveHeaderFooterResolutionBySection, aJ as resolveNotesPart, aK as withBinaryPart, aL as withEmbeddedImage, aM as withoutUnreferencedImagePart } from './tree-package-fragment-BeeKxDw8.js';
21
- import { O as OmmlEquationProjection } from './omml-equation-CuzBL5DD.js';
22
- export { D as DEFAULT_OMML_LIMITS, E as EquationExpression, L as LinearMathOmmlResult, a as LinearMathParseResult, b as LinearMathRejection, c as OFFICE_MATH_NAMESPACE_URI, d as OmmlLimits, e as equationExpressionToLinearMath, l as linearMathToOmml, p as parseLinearMath, f as projectOmmlEquation } from './omml-equation-CuzBL5DD.js';
23
- import { I as InsertCustomNodeWrite, C as CustomNodeWriteResult } from './custom-node-writes-cvL5rhcD.js';
24
- export { b as BookmarkAnchor, B as BookmarkIndex, c as CustomNodePayloadRead, d as CustomNodePayloadWrite, a as CustomNodeSweepOutcome, e as CustomNodeSweepResult, f as CustomNodeWriteRejection, D as DocumentTrackingSettings, E as EmbeddedFont, F as FontStyleKey, L as ListKind, M as MAX_CUSTOM_NODE_LABEL_LENGTH, g as MAX_CUSTOM_NODE_PAYLOAD_LENGTH, N as NO_TRACKING_SETTINGS, R as ReadEmbeddedFontsOptions, h as buildBookmarkIndex, i as customNodePayloadsByControl, j as customNodePayloadsOf, k as deobfuscateFont, l as ensureListDefinition, m as ensureNumberingLevel, n as insertCustomNodeWrite, r as readEmbeddedFonts, o as readTrackingSettings, p as removeCustomNodeWrite, s as sweepCustomNodePayloads } from './custom-node-writes-cvL5rhcD.js';
25
- export { c as collectFlowBlocks, a as commentBodyText, b as commentInitials, d as contentControlContentOf, e as deepParagraphOrderOfPart, i as isContentControl, f as isContentControlContent, p as paragraphOrderOfPart, w as walkAllStoryParagraphs, g as walkParagraphInline, h as walkStoryBlocks } from './review-paragraph-order-DT-n6ouC.js';
26
- export { D as DocumentProperties, E as EnsuredHyperlinkRelationship, a as HeadlessDocumentRejection, H as HeadlessDocumentView, b as HeadlessThemeFonts, O as OpenHeadlessDocumentResult, c as authorableHyperlinkTarget, e as ensureHyperlinkRelationship, h as headlessViewOfStore, o as openHeadlessDocument, r as relationshipTargetIn } from './headless-document-view-qH331moE.js';
27
- export { A as AuthoredNoteProperties, D as DEFAULT_ENDNOTE_PROPERTIES, a as DEFAULT_FOOTNOTE_PROPERTIES, E as EndnotePosition, F as FootnotePosition, N as NoteNumRestart, R as ResolvedEndnoteProperties, b as ResolvedFootnoteProperties, c as authoredDocumentEndnoteProperties, d as authoredDocumentFootnoteProperties, e as authoredEndnotePropertiesFromSectPr, f as authoredFootnotePropertiesFromSectPr, i as isLegalEndnotePosition, g as isLegalFootnotePosition, h as isLegalNumRestart, p as parseAuthoredNoteProperties, r as resolveEndnoteProperties, j as resolveFootnoteProperties, s as settingsPartOf } from './note-properties-4Y9o6Gyk.js';
28
- export { a as DocumentProtectionEdit, D as DocumentProtectionState, N as NO_DOCUMENT_PROTECTION, r as readDocumentProtection } from './document-protection-BAGVGqaP.js';
29
- import './editor-scope-OHPwVQ5l.js';
15
+ import { e as ResourceLimits } from './image-resources-tXLQShoC.js';
16
+ export { C as CreateImageResourceCacheOptions, D as DEFAULT_IMAGE_RESOURCE_LIMITS, f as DEFAULT_LIMITS, H as HARD_CEILINGS, g as IMAGE_RESOURCE_HARD_CEILINGS, c as ImageDecodePort, b as ImageResourceLimits, h as ImageResourceLookup, I as ImageResourceState, M as MAX_SVG_SNIFF_BYTES, P as PreservedImageMime, R as RenderableImageMime, S as SupportedImageMime, V as ValidatedImageBytesHandle, i as ValidatedRasterHeader, j as createImageResourceCache, k as hasBoundedSvgRoot, l as imageResourceLookupFor, m as liveDrawingReferenceCount, r as resolveImageResourceLimits, n as resolveLimits, s as sniffImageMime, o as validateGifHeader, p as validateJpegHeader, q as validatePngHeader, v as validateRasterHeader } from './image-resources-tXLQShoC.js';
17
+ import { O as OoxmlPart, N as OoxmlNode, aU as OoxmlInvariantResult, aV as OoxmlInvariantIssue, ak as OoxmlElement, az as OoxmlParagraphNode, aW as OoxmlFldCharNode, aX as OoxmlFldSimpleNode, aY as OoxmlInstrTextNode, ag as TreeDocOp, av as TreeOpRejection, aZ as TreeOpResult, Q as OoxmlPackage, a_ as RelationshipRecord, V as OoxmlGenericElementNode, a$ as OoxmlHardBreakNode, b0 as OoxmlAttribute, ah as OoxmlProperty, au as RevisionSiteRefusal, f as ReviewRange, R as ReviewModelInput, a as ReviewItem, C as CommentRecord, e as ReviewPosition, b1 as CommentThreadState, c as ReviewCommentItem, b as ReviewRevisionItem, ay as DrawingTreeDocOp, aH as ImpactClass, a1 as ImageWrapTarget } from './types-barrel-DuC5QBNC.js';
18
+ export { b2 as ACCEPTED_PARAGRAPH_PROPERTIES, b3 as ACCEPTED_RUN_PROPERTIES, b4 as CONTENT_CONTROL_ID_MAX, b5 as CONTENT_CONTROL_PROPERTY_ORDER, b6 as CommentAnchor, b7 as CommentPosition, b8 as CommitTextFormFieldOp, b9 as ContentControlCheckbox, ba as ContentControlCheckboxState, bb as ContentControlDataBinding, bc as ContentControlDateFormat, bd as ContentControlEntry, be as ContentControlKind, bf as ContentControlLevel, bg as ContentControlListItem, bh as ContentControlLock, bi as ContentControlProperties, bj as ContentTypeError, bk as ContentTypeIndex, bl as ContentTypeRecords, bm as DEFAULT_OOXML_PACKAGE_LIMITS, bn as DEFAULT_ZIP_LIMITS, bo as DefaultRecord, bp as DeleteTextOp, aO as DrawingImageEffects, Y as DrawingKind, Z as DrawingLocks, _ as DrawingPositionInput, bq as HYPERLINK_RELATIONSHIP_TYPE, br as HyperlinkKind, bs as HyperlinkTarget, bt as IMAGE_RELATIONSHIP_TYPE, aK as IMAGE_WRAP_TARGETS, bu as ImageRelationshipResolution, bv as IndexResult, bw as InsertBuildingBlockOp, bx as InsertTextOp, by as LegacyCheckboxFieldRange, bz as MAX_CONTENT_CONTROLS_PER_PART, bA as MAX_CONTENT_CONTROL_NESTING, bB as NameRejection, bC as NameResult, bD as OFFICE_RELATIONSHIP_NAMESPACE_URI, bE as OOXML_NODE_IDENTITY_RULES, bF as OoxmlBodyNode, bG as OoxmlBookmarkEndNode, bH as OoxmlBookmarkStartNode, bI as OoxmlContentControlCalendarNode, bJ as OoxmlContentControlCheckboxNode, bK as OoxmlContentControlCheckedNode, bL as OoxmlContentControlCheckedStateNode, bM as OoxmlContentControlComboBoxNode, am as OoxmlContentControlContentNode, bN as OoxmlContentControlDataBindingNode, bO as OoxmlContentControlDateFormatNode, bP as OoxmlContentControlDateNode, bQ as OoxmlContentControlDropDownListNode, bR as OoxmlContentControlEndPropertiesNode, bS as OoxmlContentControlLidNode, bT as OoxmlContentControlListItemNode, al as OoxmlContentControlNode, bU as OoxmlContentControlPropertiesNode, bV as OoxmlContentControlStoreMappedDataAsNode, bW as OoxmlContentControlTextNode, bX as OoxmlContentControlUncheckedStateNode, aB as OoxmlContinuationSeparatorNode, bY as OoxmlDocumentNode, aC as OoxmlEndnotesNode, bZ as OoxmlExternalTarget, aD as OoxmlFootnotesNode, b_ as OoxmlGenericExtensionAttribute, b$ as OoxmlHyperlinkNode, c0 as OoxmlInvariantIssueCode, c1 as OoxmlKnownNodeAttribute, c2 as OoxmlNamespaceBinding, U as OoxmlNodeId, c3 as OoxmlNodeIdentityRules, aA as OoxmlNoteNode, aE as OoxmlNoteRefNode, aF as OoxmlNoteReferenceNode, ao as OoxmlPackageLimits, aj as OoxmlPackageRejection, ai as OoxmlPackageResult, c4 as OoxmlParagraphPropertiesNode, c5 as OoxmlPartMetadata, c6 as OoxmlReadRejection, c7 as OoxmlReadResult, c8 as OoxmlRunNode, c9 as OoxmlRunPropertiesNode, aG as OoxmlSeparatorNode, ca as OoxmlTabNode, cb as OoxmlTextElementNode, cc as OoxmlTextNode, cd as OoxmlWmlValAttribute, ce as OoxmlXmlSpaceAttribute, cf as OverrideRecord, cg as RelationshipError, ch as RelationshipSetResult, ci as RelationshipTargetResolver, cj as ResolveResult, ck as ResolvedRelationship, d as ReviewCustomItem, g as ReviewRevisionKind, h as RevisionAddress, ap as RevisionAuthorEntry, a8 as RevisionAuthorResult, aq as RevisionAuthorSkipReason, ar as RevisionBatchEntry, a9 as RevisionBatchResult, as as RevisionBatchSkipDetail, at as RevisionBatchSkipReason, cl as SetLegacyCheckboxOp, cm as SetLegacyDropdownOp, cn as SetTextFormFieldDefaultOp, aI as SourceCrop, co as TABLE_BORDER_STYLES, cp as TabStopWrite, aM as TableBorderStyle, cq as TargetMode, aT as TextFormFieldOptions, aS as TextFormFieldRange, cr as TextFormFieldType, cs as TreeDocOpKind, ct as TreeOpEffect, cu as W15_NAMESPACE_URI, cv as WML_NAMESPACE_URI, cw as XMLNS_NAMESPACE_URI, cx as XML_NAMESPACE_URI, cy as XmlLimits, cz as XmlNode, cA as XmlRejection, cB as XmlResult, cC as ZipLimits, cD as ZipReadResult, cE as ZipRejection, cF as allocateContentControlId, cG as asciiFold, cH as buildContentTypeIndex, cI as buildRelationshipSet, cJ as childElements, cK as commentAnchorsOfStory, cL as commentsOfPart, cM as contentControlContentChildren, cN as contentControlContentNodeOf, cO as contentControlEndPropertiesNodeOf, cP as contentControlLevelOf, cQ as contentControlPropertiesNodeOf, cR as contentControlPropertiesOf, cS as contentControlTextOf, cT as contentControlsIn, cU as detectDuplicateNames, cV as extensionKey, cW as findContentControl, cX as findElement, cY as firstReviewRange, cZ as flattenContentControls, c_ as hasAnyComment, c$ as hyperlinkAnchorOf, d0 as hyperlinkRelationshipIdOf, d1 as hyperlinkTargetOf, d2 as isContentControlContentNode, d3 as isContentControlNode, d4 as isContentControlWrapper, d5 as isContentRevisionKind, d6 as isHyperlinkNode, d7 as isRangeMarkerKind, d8 as isValidMime, d9 as legacyCheckboxFieldsOf, da as lockForbidsEdit, db as lockForbidsRemoval, dc as normalizePartName, dd as orderedContentControlProperties, de as parseContentControlId, df as partNameKey, dg as planRevisionAuthorChange, dh as planRevisionBatch, di as projectDrawing, dj as readOnOffChild, dk as readOoxmlPackage, dl as readOoxmlPart, dm as readXml, dn as readZip, dp as resolveContentControlLock, dq as resolveContentType, dr as resolveImageRelationship, ds as resolveInternalTarget, dt as resolveRelationship, du as reviewItemKey, dv as reviewItemRanges, dw as textContent, dx as textFormFieldsOf, dy as threadStateOfPart, dz as validateExternalTarget, dA as withPart, dB as writeOoxmlPackage, dC as writeZip } from './types-barrel-DuC5QBNC.js';
19
+ import { F as FieldResultsMode, e as TreeModelChange, f as TreeDocumentStore, T as TreePackageStore, S as StoryScope } from './tree-package-store-CovjNARF.js';
20
+ export { l as AtomicNoteSpan, C as CascadeDeletedNoteReferencesOptions, D as DEFAULT_MAX_EDITABLE_STORY_PARTS, m as DrawingPropertyIdResult, j as FragmentPasteInput, k as FragmentPasteResult, n as HeaderFooterKind, o as HeaderFooterLifecycleImpact, p as HeaderFooterLifecycleOp, q as HeaderFooterLifecycleRejection, s as HeaderFooterLifecycleResult, H as HeaderFooterParts, b as HeaderFooterSectionResolution, t as HeaderFooterSlotMeta, c as HeaderFooterVariant, u as HistoryCaptureKind, d as HistoryGroup, M as MAX_FRAGMENT_DECODED_BYTES, v as MAX_NOTES_PER_PART, w as MAX_NOTE_REFERENCE_PARTS, x as MAX_NOTE_REFERENCE_SCAN, y as NOTE_ATOM_CHAR, z as NOTE_CONTINUATION_SEPARATOR_ID, B as NOTE_ID_MAX, E as NOTE_ID_MIN, G as NOTE_SEPARATOR_ID, J as NoteDiagnostic, K as NoteDiagnosticCode, N as NoteKind, L as NoteLifecycleImpact, O as NoteLifecycleOp, P as NoteLifecycleOptions, Q as NoteLifecycleRejection, U as NoteLifecycleResult, V as NoteReferenceHit, W as NoteReferenceScanBudget, X as NoteType, Y as PackageTransactResult, Z as RemotePackageAttribution, g as SelectionMark, _ as StoryResolveResult, a as StoryTargetRejection, $ as TreeDocumentStoreOptions, a0 as TreePackageStoreOptions, a1 as TreeStoryRef, h as TreeTransactOptions, a2 as TreeTransactResult, a3 as TreeTransactionContext, a4 as allocateDrawingPropertyId, a5 as allocateNoteId, a6 as applyFragmentPaste, a7 as applyHeaderFooterLifecycleOp, a8 as applyNoteLifecycleOp, a9 as atomicNoteSpansOf, aa as cascadeDeletedNoteReferences, ab as collectNoteReferences, ac as collectPackageNoteReferences, ad as collectSectionPropertyNodes, ae as createNoteReferenceScanBudget, af as customMarkFollows, ag as diagnoseNoteReferences, ah as findNoteById, ai as formatNoteScopeId, aj as isContinuationSeparatorNode, ak as isEndnotesNode, al as isFootnotesNode, am as isHeaderFooterLifecycleOp, an as isNormalNote, ao as isNoteAtomNode, ap as isNoteLifecycleOp, aq as isNoteNode, ar as isNoteRefNode, as as isNoteReferenceNode, at as isSeparatorNode, au as normalNoteIds, av as noteAtomText, aw as noteIdOf, ax as noteKindOf, ay as noteRefKindOf, az as noteReferenceKindOf, aA as noteTypeOf, aB as notesOf, aC as notesPartHasId, aD as observeHistoryGroup, aE as parseNoteId, aF as parseNoteScopeId, r as reportHistoryGroup, aG as resolveHeaderFooterParts, aH as resolveHeaderFooterPartsBySection, aI as resolveHeaderFooterResolutionBySection, aJ as resolveNotesPart, aK as withBinaryPart, aL as withEmbeddedImage, aM as withoutUnreferencedImagePart } from './tree-package-store-CovjNARF.js';
21
+ import { O as OmmlEquationProjection } from './omml-equation-BUbU0utM.js';
22
+ export { D as DEFAULT_OMML_LIMITS, E as EquationExpression, L as LinearMathOmmlResult, a as LinearMathParseResult, b as LinearMathRejection, c as OFFICE_MATH_NAMESPACE_URI, d as OmmlLimits, e as equationExpressionToLinearMath, l as linearMathToOmml, p as parseLinearMath, f as projectOmmlEquation } from './omml-equation-BUbU0utM.js';
23
+ import { I as InsertCustomNodeWrite, C as CustomNodeWriteResult } from './custom-node-writes-Bn6uciLb.js';
24
+ export { b as BookmarkAnchor, B as BookmarkIndex, c as CustomNodePayloadRead, d as CustomNodePayloadWrite, a as CustomNodeSweepOutcome, e as CustomNodeSweepResult, f as CustomNodeWriteRejection, D as DocumentTrackingSettings, E as EmbeddedFont, F as FontStyleKey, L as ListKind, M as MAX_CUSTOM_NODE_LABEL_LENGTH, g as MAX_CUSTOM_NODE_PAYLOAD_LENGTH, N as NO_TRACKING_SETTINGS, R as ReadEmbeddedFontsOptions, h as buildBookmarkIndex, i as customNodePayloadsByControl, j as customNodePayloadsOf, k as deobfuscateFont, l as ensureListDefinition, m as ensureNumberingLevel, n as insertCustomNodeWrite, r as readEmbeddedFonts, o as readTrackingSettings, p as removeCustomNodeWrite, s as sweepCustomNodePayloads } from './custom-node-writes-Bn6uciLb.js';
25
+ export { c as collectFlowBlocks, a as commentBodyText, b as commentInitials, d as contentControlContentOf, e as deepParagraphOrderOfPart, i as isContentControl, f as isContentControlContent, p as paragraphOrderOfPart, w as walkAllStoryParagraphs, g as walkParagraphInline, h as walkStoryBlocks } from './review-paragraph-order-CN_0l2Cb.js';
26
+ export { D as DocumentProperties, E as EnsuredHyperlinkRelationship, a as HeadlessDocumentRejection, H as HeadlessDocumentView, b as HeadlessThemeFonts, O as OpenHeadlessDocumentResult, c as authorableHyperlinkTarget, e as ensureHyperlinkRelationship, h as headlessViewOfStore, o as openHeadlessDocument, r as relationshipTargetIn } from './headless-document-view-pp3q7wIh.js';
27
+ export { A as AuthoredNoteProperties, D as DEFAULT_ENDNOTE_PROPERTIES, b as DEFAULT_FOOTNOTE_PROPERTIES, E as EndnotePosition, F as FootnotePosition, N as NoteNumRestart, a as ResolvedEndnoteProperties, R as ResolvedFootnoteProperties, c as authoredDocumentEndnoteProperties, d as authoredDocumentFootnoteProperties, e as authoredEndnotePropertiesFromSectPr, f as authoredFootnotePropertiesFromSectPr, i as isLegalEndnotePosition, g as isLegalFootnotePosition, h as isLegalNumRestart, p as parseAuthoredNoteProperties, r as resolveEndnoteProperties, j as resolveFootnoteProperties, s as settingsPartOf } from './note-properties-qQUjO1GQ.js';
28
+ export { D as DocumentProtectionEdit, a as DocumentProtectionState, N as NO_DOCUMENT_PROTECTION, r as readDocumentProtection } from './document-protection-CUb55pl_.js';
29
+ import './editor-scope-7o9xweiJ.js';
30
30
 
31
31
  /**
32
32
  * Serialize normalized XML from a canonical part using repository-controlled
@@ -376,1716 +376,1716 @@ declare function paragraphTextOf(part: OoxmlPart, paragraphId: string, options?:
376
376
  declare function applyTreeOp(part: OoxmlPart, op: TreeDocOp, options?: EditOptions): TreeOpResult;
377
377
 
378
378
  /**
379
- * Every kind of thing the registry gives a stable identity to.
379
+ * Keys that must never be assigned from file data.
380
380
  *
381
- * Identity is `(kind, id)` plus version and NEVER registration order, so two bundles contributing
382
- * the same command resolve deterministically regardless of which loaded first.
381
+ * XML attribute names become object keys, and a document controls those names — assigning
382
+ * `__proto__` into an ordinary object is the prototype-pollution hazard this engine audits for.
383
383
  */
384
- declare const ID_KINDS: readonly ['extension', 'capability', 'command', 'query', 'schema', 'dependencyKey', 'runtimePort', 'result', 'origin'];
385
- /** One of {@link ID_KINDS}. */
386
- /** One of {@link ID_KINDS} — which sort of thing an identifier names. */
387
- type IdKind = (typeof ID_KINDS)[number];
384
+ declare const DANGEROUS_KEYS: readonly string[];
385
+ /** A file-derived key that would pollute a prototype. Refused, never sanitized-and-accepted. */
386
+ declare class DangerousKeyError extends Error {
387
+ readonly key: string;
388
+ readonly path: string;
389
+ constructor(key: string, path: string);
390
+ }
391
+ /** Whether a key is one of {@link DANGEROUS_KEYS}. */
392
+ declare function isDangerousKey(key: string): boolean;
393
+ /** A fresh null-prototype record — the only object shape parser intermediates use. */
394
+ declare function nullRecord<T = unknown>(): Record<string, T>;
388
395
  /**
389
- * Whether a string is a well-formed identifier in either accepted grammar.
390
- *
391
- * Reverse-domain (`dev.docx-editor.core.command.insert-text`) or package-owned
392
- * (`@docx-editor.dev/engine-core#command/insert-text`). Ids are opaque once validated.
396
+ * Recursively convert `value` into null-prototype records, rejecting any
397
+ * dangerous object key. Arrays and primitives pass through (arrays rebuilt so no
398
+ * inherited prototype pollution survives). Throws DangerousKeyError on the first
399
+ * unsafe key, naming its path. Cyclic inputs are rejected.
393
400
  */
394
- declare function isValidId(id: string): boolean;
401
+ declare function toSafeRecord(value: unknown, path?: string): unknown;
402
+
403
+ /** Locate `[Content_Types].xml` bytes regardless of zip key spelling. */
404
+ declare function contentTypesPartBytes(pkg: OoxmlPackage): {
405
+ readonly storageKey: string;
406
+ readonly bytes: Uint8Array;
407
+ } | null;
395
408
  /**
396
- * Validate an identifier, throwing when it is malformed.
409
+ * What a package-level invariant walk found wrong.
397
410
  *
398
- * Throws rather than returning: a bad id is an author mistake at registration time, not file
399
- * input, and accepting it would produce a registry whose identities silently collide.
411
+ * Package invariants are cross-PART: a relationship pointing at a part that does not exist, or a
412
+ * part no content-type record covers. Neither is visible from inside a single part's tree.
400
413
  */
401
- declare function assertValidId(id: string, kind?: IdKind): void;
402
- /** A validated (kind, id, version) triple — the registry's unit of identity. */
403
- interface CapabilityId {
404
- readonly kind: IdKind;
405
- readonly id: string;
406
- readonly version: string;
407
- }
408
-
409
- /** A parsed semantic version. Only the three numeric components — no pre-release or build. */
410
- interface SemVer {
411
- readonly major: number;
412
- readonly minor: number;
413
- readonly patch: number;
414
+ type PackageInvariantCode = 'dangling-relationship' | 'missing-content-type'
415
+ /** A part occupies a name OPC reserves for package infrastructure. */
416
+ | 'reserved-part-name'
417
+ /** Two parts whose names differ only by case, which OPC treats as one part. */
418
+ | 'duplicate-part-name'
419
+ /** A part name the OPC screens refuse; `writeZip` would throw on save. */
420
+ | 'unsafe-part-name';
421
+ /** One package invariant violation, located by part name and relationship id. */
422
+ interface PackageInvariantIssue {
423
+ readonly code: PackageInvariantCode;
424
+ /** The part the issue is about: the missing target, or the part with no type. */
425
+ readonly partName: string;
426
+ /** For a dangling relationship, the owner that points at nothing. */
427
+ readonly ownerPart?: string;
414
428
  }
429
+ /** Whether a package satisfies its cross-part invariants, listing every violation otherwise. */
430
+ type PackageInvariantResult = {
431
+ readonly ok: true;
432
+ } | {
433
+ readonly ok: false;
434
+ readonly issues: readonly PackageInvariantIssue[];
435
+ };
436
+ /** Relationship records owned by one part, in authored order. */
437
+ declare function relationshipsOf(pkg: OoxmlPackage, ownerPart: string): readonly RelationshipRecord[];
438
+ /** The content type that resolves for a part name, or null when nothing declares one. */
439
+ declare function resolveContentTypeOf(pkg: OoxmlPackage, partName: string): string | null;
440
+ /** The `.rels` part that owns a part's relationships, by OPC convention. */
441
+ declare function relsPartNameFor(partName: string): string;
415
442
  /**
416
- * Parse a semantic version, rejecting anything the registry's rules do not need.
443
+ * Declare a content type for a part, by upserting an `<Override>` in the content-types tree.
417
444
  *
418
- * Deliberately narrow: an unsupported range form is refused rather than accepted, so a malformed
419
- * range can never masquerade as "compatible".
445
+ * A no-op when the part already resolves to the same type, so repeating a write does not append
446
+ * a duplicate entry. Resolving to a DIFFERENT type replaces the existing Override in place.
447
+ * `forceOverride` writes an explicit Override even when a Default already matches.
420
448
  */
421
- declare function parseSemVer(input: string): SemVer;
422
- /** Order two versions: negative, zero or positive, by major then minor then patch. */
423
- declare function compareSemVer(a: SemVer, b: SemVer): -1 | 0 | 1;
449
+ declare function withContentTypeOverride(pkg: OoxmlPackage, partName: string, contentType: string, options?: {
450
+ readonly forceOverride?: boolean;
451
+ }): OoxmlPackage;
452
+ /** What {@link withoutPart} answers: `ok: false` leaves the package exactly as it was. */
453
+ interface WithoutPartResult {
454
+ readonly pkg: OoxmlPackage;
455
+ readonly ok: boolean;
456
+ }
457
+ /** Add or replace one relationship on a part, returning a new package. */
458
+ declare function withRelationship(pkg: OoxmlPackage, ownerPart: string, type: string, rawTarget: string): {
459
+ readonly pkg: OoxmlPackage;
460
+ readonly relationshipId: string;
461
+ readonly ok: boolean;
462
+ };
424
463
  /**
425
- * Whether `version` satisfies `range`. Supported range grammar:
426
- * - `*` any version
427
- * - `1.2.3` exact
428
- * - `^1.2.3` caret: same major, and >= the floor (major 0 pins the minor)
429
- * - `>=1.2.3 <2.0.0` a single lower (inclusive) + upper (exclusive) bound pair
430
- * Any other shape throws — an unparseable range is a registration error, not a pass.
464
+ * Add a part that does not exist yet, with the content-type override it needs to be openable.
465
+ *
466
+ * Deliberately does NOT create a relationship: a part is reachable because something points at
467
+ * it, and which part points at it is the caller's decision. Creating one here would guess.
431
468
  */
432
- declare function satisfies(version: string, range: string): boolean;
433
-
469
+ declare function withNewPart(pkg: OoxmlPackage, partName: string, root: OoxmlElement, contentType: string): OoxmlPackage;
434
470
  /**
435
- * Why registry resolution failed.
471
+ * The two invariants a package must satisfy before it is published.
436
472
  *
437
- * Every code names a declaration conflict a bundle author can fix — a missing dependency, an
438
- * unsatisfied version range, a duplicate contribution with no replacement policy.
473
+ * Both describe the half-written state that splitting a multi-part write across transactions
474
+ * produces, and both make a package Word refuses to open:
475
+ *
476
+ * - a relationship pointing at a part nobody created;
477
+ * - a part with no content type, which is unopenable even though the XML is well formed.
478
+ *
479
+ * Checked at the commit boundary rather than inside each primitive, for the same reason part
480
+ * validation moved there: a transaction is allowed to pass through an inconsistent intermediate
481
+ * as long as nothing can observe it.
439
482
  */
440
- type RegistryErrorCode = 'invalid-id' | 'invalid-version' | 'duplicate-extension' | 'id-collision' | 'replacement-target-missing' | 'unauthorized-replacement' | 'replacement-version-mismatch' | 'ambiguous-replacement' | 'missing-dependency' | 'dependency-cycle' | 'conflict' | 'missing-port';
483
+ declare function validatePackageInvariants(pkg: OoxmlPackage): PackageInvariantResult;
484
+
441
485
  /**
442
- * A resolution failure naming every responsible party.
486
+ * Whether a string is a valid XML NCName in the strict ASCII profile — a name with no colon.
443
487
  *
444
- * Thrown rather than returned: an unresolvable registry is a build-time composition mistake, and
445
- * an engine running with a half-resolved registry would fail later in ways that do not point back
446
- * to the bundle that caused it.
488
+ * This is the rule for names the engine itself writes or accepts from a caller. Names read
489
+ * from a document use {@link isXmlNCName}, which admits every XML 1.0 name.
447
490
  */
448
- declare class RegistryError extends Error {
449
- readonly code: RegistryErrorCode;
450
- /** Stable identities responsible for the failure (extensions, ids). */
451
- readonly responsible: readonly string[];
452
- constructor(code: RegistryErrorCode, message: string,
453
- /** Stable identities responsible for the failure (extensions, ids). */
454
- responsible?: readonly string[]);
455
- }
456
- /** How a base contribution permits replacement by other bundles. */
457
- type ReplacementPolicy = {
458
- readonly kind: 'none';
459
- } | {
460
- readonly kind: 'single';
461
- } | {
462
- readonly kind: 'priority';
463
- };
464
- /** One thing a bundle contributes: a command, a query, a schema, a port, keyed by `(kind, id)`. */
465
- interface Contribution {
466
- readonly kind: Exclude<IdKind, 'extension' | 'origin' | 'result'>;
467
- readonly id: string;
468
- readonly version: string;
469
- /** If set, this contribution replaces an existing base contribution. */
470
- readonly replaces?: {
471
- readonly targetId: string;
472
- readonly targetRange: string;
473
- readonly priority?: number;
474
- };
475
- /** Policy this contribution exposes to would-be replacers (default `none`). */
476
- readonly replaceable?: ReplacementPolicy;
477
- readonly payload?: unknown;
478
- }
491
+ declare function isValidNCName(name: string): boolean;
492
+ /** A QName is an optional `prefix:` (both NCNames) — never attacker-derived. */
493
+ declare function isValidQName(name: string): boolean;
479
494
  /**
480
- * A unit of engine functionality: its identity, version, dependencies, conflicts, required ports,
481
- * and contributions.
495
+ * Validate a qualified name, throwing when it is malformed.
482
496
  *
483
- * The registry's whole input. Everything a bundle needs and everything it offers is DECLARED, so
484
- * resolution can be deterministic and order-independent.
497
+ * Guards the serializer: an invalid QName written into XML produces a file Word cannot open, so
498
+ * it fails here rather than at save.
485
499
  */
486
- interface FeatureBundle {
487
- readonly id: string;
488
- readonly version: string;
489
- readonly dependencies?: readonly string[];
490
- readonly conflicts?: readonly string[];
491
- readonly requiredPorts?: readonly string[];
492
- readonly contributions: readonly Contribution[];
493
- }
494
- /** The resolved result: every contribution selected, indexed by `(kind, id)`. */
495
- interface ResolvedRegistry {
496
- readonly extensions: ReadonlyMap<string, FeatureBundle>;
497
- readonly contributions: ReadonlyMap<string, Contribution>;
498
- get(kind: Contribution['kind'], id: string): Contribution | undefined;
499
- }
500
- /** How resolution treats optional bundles and replacement policies. */
501
- interface ResolveOptions {
502
- /** Runtime port ids available in this environment (design D9 / task 0.3). */
503
- readonly availablePorts?: readonly string[];
504
- }
500
+ declare function assertValidQName(name: string): void;
505
501
  /**
506
- * Resolve a set of bundles into one registry, or throw.
507
- *
508
- * Deterministic and registration-order independent: selection is by `(kind, id)` plus version,
509
- * and ties break only on declared policy. Array order never decides anything.
510
- *
511
- * @throws RegistryError naming every bundle responsible for the failure.
502
+ * Controlled namespace-prefix allocation: deterministic, collision-free prefixes
503
+ * for namespace URIs. A known URI always yields the same registered prefix; new
504
+ * URIs get a generated `ns{n}` prefix, never one derived from file content.
512
505
  */
513
- declare function resolve(bundles: readonly FeatureBundle[], options?: ResolveOptions): ResolvedRegistry;
506
+ declare class PrefixAllocator {
507
+ private readonly byUri;
508
+ private readonly usedPrefixes;
509
+ private counter;
510
+ constructor(known?: Readonly<Record<string, string>>);
511
+ prefixFor(namespaceUri: string): string;
512
+ /** The declared bindings, for emitting xmlns declarations. */
513
+ bindings(): {
514
+ prefix: string;
515
+ uri: string;
516
+ }[];
517
+ }
514
518
 
515
519
  /**
516
- * Typed-origin domains (design D5 / ADR-S5). `mutation.*` are the canonical
517
- * write origins; `projection` and `awareness` MUST NOT enter history, audit,
518
- * snapshots, or replication.
520
+ * A hyperlink target projected for a RUNTIME sink, or the reason it was withheld.
521
+ *
522
+ * The authored target stays authored — the record layer keeps it verbatim and escapes it into
523
+ * owned OOXML, which is not a runtime sink. Only this allowlist-sanitized projection reaches DOM,
524
+ * CSS, navigation or fetch, so `javascript:`, `data:` and `vbscript:` never leave the boundary.
519
525
  */
520
- declare const ORIGIN_IDS: {
521
- readonly mutationHuman: "dev.docx-editor.core.origin.mutation.human";
522
- readonly mutationAgent: "dev.docx-editor.core.origin.mutation.agent";
523
- readonly mutationRemote: "dev.docx-editor.core.origin.mutation.remote";
524
- readonly mutationUndo: "dev.docx-editor.core.origin.mutation.undo";
525
- readonly mutationRedo: "dev.docx-editor.core.origin.mutation.redo";
526
- readonly mutationMigration: "dev.docx-editor.core.origin.mutation.migration";
527
- readonly mutationRepair: "dev.docx-editor.core.origin.mutation.repair";
528
- readonly mutationServer: "dev.docx-editor.core.origin.mutation.server";
529
- readonly projection: "dev.docx-editor.core.origin.projection";
530
- readonly awareness: "dev.docx-editor.core.origin.awareness";
526
+ type HrefProjection = {
527
+ readonly ok: true;
528
+ readonly href: string;
529
+ } | {
530
+ readonly ok: false;
531
+ readonly inert: true;
531
532
  };
532
- /** Canonical writes carry a mutation origin; these are the undoable-eligibility inputs. */
533
- declare const CANONICAL_MUTATION_ORIGINS: readonly string[];
534
- /** Origins that never enter authored state / history / audit / snapshot / replication. */
535
- declare const NON_CANONICAL_ORIGINS: readonly string[];
536
533
  /**
537
- * Result taxonomy (design D8 / task 7.8). A transport/protocol failure that
538
- * prevents a valid envelope is a typed exception, not a member here.
534
+ * Project a file-derived URL for a DOM/navigation sink. Strips embedded
535
+ * tab/LF/CR (used to smuggle `java\nscript:`), allows relative URLs and the
536
+ * scheme allowlist, and renders everything else inert. Never fetches.
539
537
  */
540
- declare const RESULT_IDS: {
541
- readonly applied: "dev.docx-editor.core.result.applied";
542
- readonly validation: "dev.docx-editor.core.result.validation";
543
- readonly conflict: "dev.docx-editor.core.result.conflict";
544
- readonly resource: "dev.docx-editor.core.result.resource";
545
- readonly authorization: "dev.docx-editor.core.result.authorization";
546
- readonly aborted: "dev.docx-editor.core.result.aborted";
547
- };
548
- /** Runtime ports (extensions-and-runtime-ports spec; design D9). */
549
- declare const RUNTIME_PORT_IDS: {
550
- readonly fonts: "dev.docx-editor.core.port.fonts";
551
- readonly shaping: "dev.docx-editor.core.port.shaping";
552
- readonly images: "dev.docx-editor.core.port.images";
553
- readonly clock: "dev.docx-editor.core.port.clock";
554
- readonly identity: "dev.docx-editor.core.port.identity";
555
- readonly persistence: "dev.docx-editor.core.port.persistence";
556
- readonly transport: "dev.docx-editor.core.port.transport";
557
- readonly scheduling: "dev.docx-editor.core.port.scheduling";
558
- readonly audit: "dev.docx-editor.core.port.audit";
559
- readonly authorization: "dev.docx-editor.core.port.authorization";
560
- readonly resourceAccounting: "dev.docx-editor.core.port.resource-accounting";
561
- readonly cancellation: "dev.docx-editor.core.port.cancellation";
562
- readonly externalResourceConsent: "dev.docx-editor.core.port.external-resource-consent";
563
- };
564
- /** Layout dependency keys (design D6 / task 8.2). */
565
- declare const DEPENDENCY_KEY_IDS: {
566
- readonly style: "dev.docx-editor.core.dep.style";
567
- readonly numbering: "dev.docx-editor.core.dep.numbering";
568
- readonly section: "dev.docx-editor.core.dep.section";
569
- readonly story: "dev.docx-editor.core.dep.story";
570
- readonly font: "dev.docx-editor.core.dep.font";
571
- readonly image: "dev.docx-editor.core.dep.image";
572
- readonly table: "dev.docx-editor.core.dep.table";
573
- readonly field: "dev.docx-editor.core.dep.field";
574
- readonly note: "dev.docx-editor.core.dep.note";
575
- readonly headerFooter: "dev.docx-editor.core.dep.header-footer";
576
- readonly annotation: "dev.docx-editor.core.dep.annotation";
577
- };
578
- /** Every frozen id as a flat list, for the immutability / uniqueness gate. */
579
- declare const ALL_FROZEN_IDS: readonly string[];
580
-
538
+ declare function sanitizeHref(raw: string): HrefProjection;
539
+ /** XML-escape a value for validated serialization back into owned OOXML. */
540
+ declare function escapeXml(value: string): string;
581
541
  /**
582
- * A counter's limit was reached. Carries the label, the limit, and what was attempted.
583
- *
584
- * Thrown at the N → N+1 boundary, so the increment that would have crossed the limit never
585
- * happens rather than being detected afterwards.
542
+ * CSS string-escape a file-derived value (e.g. an `@font-face` family name or an
543
+ * inline style value). Emits `\<hex> ` escapes for quotes, backslash, and
544
+ * controls so the value cannot break out of its CSS string.
586
545
  */
587
- declare class LimitExceededError extends Error {
588
- readonly label: string;
589
- readonly limit: number;
590
- readonly attempted: number;
591
- constructor(label: string, limit: number, attempted: number);
592
- }
546
+ declare function escapeCssString(value: string): string;
547
+ /** Whether a file-derived CSS fragment contains a `url()` or `@import` (must be rejected). */
548
+ declare function containsCssFetch(value: string): boolean;
593
549
  /**
594
- * Overflow-safe counting against a fixed limit.
550
+ * Content that must never execute or auto-resolve: OLE objects, macros, DDE and `INCLUDE*` field
551
+ * instructions.
595
552
  *
596
- * Never silently wraps: it rejects the increment that would cross its limit AND any arithmetic
597
- * that would exceed `Number.MAX_SAFE_INTEGER`. That second guard is the point — a file-supplied
598
- * count must never be trusted into an allocation, and a wrapped counter reads as small.
553
+ * Rendered INERT by default rather than stripped — removing it would be a lossless-preservation
554
+ * failure, so it is carried and never acted on.
599
555
  */
600
- declare class BoundedCounter {
601
- readonly label: string;
602
- readonly limit: number;
603
- private value;
604
- constructor(label: string, limit: number);
605
- get current(): number;
606
- /** Remaining headroom before the limit. */
607
- get remaining(): number;
608
- /**
609
- * Add `n` (default 1). Throws LimitExceededError if the result would exceed the
610
- * limit (so `limit` itself is reachable but `limit + 1` is not) or overflow the
611
- * safe-integer range. On rejection the counter is unchanged.
612
- */
613
- add(n?: number): number;
614
- /** Whether adding `n` would be accepted, without mutating. */
615
- canAdd(n?: number): boolean;
616
- release(n: number): void;
617
- }
618
-
619
- /** A budget was misused: over-carved, over-reserved, or disposed with children outstanding. */
620
- declare class BudgetError extends Error {
621
- constructor(message: string);
556
+ declare const INERT_EXECUTABLE_KINDS: readonly ['field-dde', 'field-include', 'macro', 'activex', 'ole', 'embedded-object', 'executable-relationship'];
557
+ /** One of {@link INERT_EXECUTABLE_KINDS}. */
558
+ /** One of {@link INERT_EXECUTABLE_KINDS} — content carried but never executed. */
559
+ type InertExecutableKind = (typeof INERT_EXECUTABLE_KINDS)[number];
560
+ /** Whether a content kind is one this engine refuses to execute or auto-resolve. */
561
+ declare function isInertExecutable(kind: string): boolean;
562
+ /** Whether a field instruction's leading keyword is safe to evaluate. */
563
+ declare function isEvaluableField(instruction: string): boolean;
564
+ /** One item a scrub pass considers: its kind, and where in the package it sits. */
565
+ interface ContentItem {
566
+ readonly id: string;
567
+ readonly kind: string;
622
568
  }
623
569
  /**
624
- * Capacity claimed BEFORE it is allocated.
570
+ * What an explicit scrub removed.
625
571
  *
626
- * Reserve-then-allocate rather than allocate-then-check: discovering the overrun after the
627
- * allocation has already happened defeats the point of having a budget.
572
+ * A scrub DECLARES ITSELF non-lossless: removing executable content changes the file, which is a
573
+ * choice a caller makes deliberately rather than a default the engine applies.
628
574
  */
629
- interface Reservation {
630
- readonly amount: number;
631
- readonly released: boolean;
632
- release(): void;
575
+ interface ScrubResult {
576
+ readonly kept: readonly ContentItem[];
577
+ readonly removed: readonly ContentItem[];
578
+ /** A scrub that removes anything is non-lossless by definition. */
579
+ readonly nonLossless: boolean;
633
580
  }
581
+ /** Explicit scrub export: remove inert executable classes, report removals. */
582
+ declare function scrubExport(items: readonly ContentItem[]): ScrubResult;
583
+
584
+ /** True for an `m:oMathPara` display equation. */
585
+ declare function isOmmlDisplay(node: OoxmlNode): node is OoxmlGenericElementNode;
586
+ /** True for a paragraph-level equation atom: `m:oMath` or `m:oMathPara`. */
587
+ declare function isOmmlEquationAtom(node: OoxmlNode): node is OoxmlGenericElementNode;
588
+ /** The `m:oMath` equations of a display, or the equation itself for an inline `m:oMath`. */
589
+ declare function equationsOfAtom(node: OoxmlNode): readonly OoxmlGenericElementNode[];
634
590
  /**
635
- * One node in the hierarchical resource budget tree.
636
- *
637
- * An operation owns a root budget; parsers, extensions, workers, layout, transport and output
638
- * carve children from it, so no subsystem can consume more than the operation as a whole allows.
639
- *
640
- * `dispose()` REFUSES while children or reservations are outstanding, then runs registered
641
- * cleanups LIFO — spill files, worker termination — even if one throws. A leaked child budget is a
642
- * leaked worker, so the refusal is the diagnostic.
591
+ * Project a display equation as one layout atom. A display with one equation keeps that
592
+ * equation's projection, so the painted atom names the editable `m:oMath`. Several equations
593
+ * share one row, separated by an em space.
643
594
  */
644
- declare class Budget {
645
- readonly label: string;
646
- readonly capacity: number;
647
- private readonly used;
648
- private readonly children;
649
- private activeReservations;
650
- private readonly cleanups;
651
- private disposed;
652
- private carveAmount;
653
- private parent?;
654
- constructor(label: string, capacity: number);
655
- get inUse(): number;
656
- get available(): number;
657
- get isDisposed(): boolean;
658
- /** Reserve `amount` from this budget. Throws if it would exceed capacity. */
659
- reserve(amount: number): Reservation;
660
- /** Carve a child budget of `capacity` out of this budget's headroom. */
661
- child(label: string, capacity: number): Budget;
662
- /** Register cleanup for a spill file, worker, or queue tied to this budget. */
663
- onRelease(cleanup: () => void): void;
664
- /**
665
- * Release this budget. Refuses while any child budget or reservation is
666
- * outstanding (children must finish first). Runs cleanups LIFO, returns the
667
- * carve-out to the parent, and marks disposed. Cleanup errors are collected and
668
- * rethrown after every cleanup has run.
669
- */
670
- dispose(): void;
671
- private assertLive;
672
- }
673
-
595
+ declare function projectOmmlDisplay(node: OoxmlNode): OmmlEquationProjection | null;
674
596
  /**
675
- * Which side of the point of no return an operation is on.
676
- *
677
- * Canonical publication is that point. Cancelling BEFORE it rolls the whole operation back;
678
- * cancelling after it leaves the commit standing and cancels only derived work — layout, export,
679
- * caches.
597
+ * The physical justification of a paragraph whose only visible content is display math.
598
+ * `m:oMathParaPr/m:jc` sets it; the default `centerGroup` centers the display. Returns null
599
+ * when the paragraph also holds text or other content, which keeps the paragraph `w:jc`.
680
600
  */
681
- type CancellationPhase = 'pre-publication' | 'post-publication';
682
- /** Thrown from a `checkpoint()` when the operation has been cancelled. */
683
- declare class CancellationError extends Error {
684
- /** True when the commit is already published and only derived work is cancelled. */
685
- readonly derivedOnly: boolean;
686
- constructor(
687
- /** True when the commit is already published and only derived work is cancelled. */
688
- derivedOnly: boolean, reason?: string);
601
+ declare function displayMathAlignment(paragraph: {
602
+ readonly children: readonly OoxmlNode[];
603
+ }): 'left' | 'center' | 'right' | null;
604
+ /** Project a paragraph-level equation atom: inline `m:oMath` or display `m:oMathPara`. */
605
+ declare function projectOmmlAtom(node: OoxmlNode): OmmlEquationProjection | null;
606
+
607
+ /** UTF-16 placeholder for a page break in paragraph text projections. */
608
+ declare const PAGE_BREAK_CHAR = "\f";
609
+ /** What a `w:br` breaks. `other` covers values this engine does not model, kept losslessly. */
610
+ type HardBreakKind = 'line' | 'page' | 'column' | 'other';
611
+ /** Read the semantic break kind from a typed `w:br` node. */
612
+ declare function hardBreakKind(node: OoxmlHardBreakNode): HardBreakKind;
613
+ /** Whether a node is a `w:br` with `w:type="page"`. */
614
+ declare function isPageBreakNode(node: OoxmlNode): node is OoxmlHardBreakNode;
615
+ /** Text projection for a `w:br` node — one UTF-16 code unit per break. */
616
+ declare function hardBreakText(node: OoxmlHardBreakNode): string;
617
+ /** Attributes for a newly authored `w:br`. */
618
+ declare function hardBreakAttributes(kind: 'line' | 'page'): OoxmlHardBreakNode['attributes'];
619
+
620
+ /** Parsed TOC instruction. Unknown switches are ignored for generation but left on the wire. */
621
+ interface TocInstruction {
622
+ readonly keyword: 'TOC';
623
+ /** Include hyperlinks (`\\h`). */
624
+ readonly hyperlink: boolean;
625
+ /** Omit page numbers (`\\n`). */
626
+ readonly omitPageNumbers: boolean;
627
+ /** Inclusive 1-based outline levels from `\\o "n-m"`. Defaults 1–9. */
628
+ readonly outlineStart: number;
629
+ readonly outlineEnd: number;
630
+ readonly raw: string;
689
631
  }
632
+ /** Longest TOC field instruction read. Instructions come from a file; the parse is bounded. */
633
+ declare const TOC_MAX_INSTRUCTION_CHARS = 256;
634
+ /** Most entries one generated table of contents may hold. */
635
+ declare const TOC_MAX_ENTRIES = 512;
636
+ /** Most bookmarks minted during one TOC refresh. */
637
+ declare const TOC_MAX_BOOKMARKS_PER_REFRESH = 512;
638
+ /** Deepest nested field instruction followed. Caps recursion on file-supplied structure. */
639
+ declare const TOC_MAX_FIELD_NESTING = 4;
690
640
  /**
691
- * The read side of cancellation, handed to cooperative work.
641
+ * Most layout passes a TOC refresh runs before settling.
692
642
  *
693
- * Cooperative rather than pre-emptive: long work calls `checkpoint()` at declared intervals, which
694
- * is what lets an operation unwind promptly without the engine having to interrupt it mid-mutation.
643
+ * Page numbers change the TOC's own height, which changes page numbers — bounded so a
644
+ * non-converging document stops rather than looping.
695
645
  */
696
- interface CancellationToken {
697
- readonly isCancelled: boolean;
698
- readonly phase: CancellationPhase;
699
- /** True only when cancelled AND the commit is already published. */
700
- readonly derivedOnly: boolean;
701
- /** Throws CancellationError if cancelled; call at declared checkpoint intervals. */
702
- checkpoint(): void;
703
- }
646
+ declare const TOC_MAX_PAGE_PASSES = 3;
704
647
  /**
705
- * The write side of cancellation, and the owner of the phase.
648
+ * Parse a TOC field instruction string.
706
649
  *
707
- * Whoever starts an operation holds this; everything it calls gets only the token.
650
+ * Returns null when the leading keyword is not TOC, the string is over-long, or the
651
+ * outline range is hostile. Does not evaluate or fetch anything.
708
652
  */
709
- declare class CancellationController {
710
- private _cancelled;
711
- private _phase;
712
- private _reason?;
713
- cancel(reason?: string): void;
714
- /** Mark canonical publication — the point of no return. */
715
- markPublished(): void;
716
- get isCancelled(): boolean;
717
- get phase(): CancellationPhase;
718
- get isPublished(): boolean;
719
- /** Cancelled after publication -> full rollback is no longer possible. */
720
- get derivedOnly(): boolean;
721
- get token(): CancellationToken;
722
- }
653
+ declare function parseTocInstruction(raw: string): TocInstruction | null;
723
654
 
724
- /** Injectable time source — the engine never calls Date.now directly (determinism). */
725
- interface ClockPort {
726
- now(): number;
727
- }
728
- /** Stable id minting for sessions, commits, and allocator seeds. */
729
- interface IdentityPort {
730
- newId(): string;
731
- }
732
- /** Cooperative scheduling of deferred work. */
733
- interface SchedulingPort {
734
- schedule(task: () => void): void;
735
- }
736
- /** Redacted observability sink (raw text never enters here — design D5). */
737
- interface AuditPort {
738
- record(entry: {
739
- readonly kind: string;
740
- readonly at: number;
741
- readonly meta?: Record<string, unknown>;
742
- }): void;
743
- }
744
- /** Read/write/export authorization decisions. */
745
- interface AuthorizationPort {
746
- authorize(action: string, subject?: string): boolean;
747
- }
748
- /** Explicit consent gate for any remote/external resource (no zero-click fetch). */
749
- interface ExternalResourceConsentPort {
750
- requestConsent(target: string): boolean;
751
- }
752
- /** Cancellation source for the current operation. */
753
- interface CancellationPort {
754
- readonly token: CancellationToken;
755
- }
756
- /** Where documents are stored and retrieved. Opaque marker until its milestone. */
757
- interface PersistencePort {
758
- readonly kind: 'persistence';
759
- }
760
- /** How the engine talks to a remote peer. Opaque marker until its milestone. */
761
- interface TransportPort {
762
- readonly kind: 'transport';
763
- }
764
- /** Where font bytes come from. Opaque marker until its milestone. */
765
- interface FontPort {
766
- readonly kind: 'font';
767
- }
768
- /** Which shaping backend measures text. Opaque marker until its milestone. */
769
- interface ShapingPort {
770
- readonly kind: 'shaping';
771
- }
772
- /** How image bytes are decoded. Opaque marker until its milestone. */
773
- interface ImagePort {
774
- readonly kind: 'image';
655
+ /** A table of contents found in a document, whether wrapped in an SDT or a bare field. */
656
+ interface DetectedToc {
657
+ /** Enclosing control id when it identifies one TOC, otherwise the begin fldChar id. */
658
+ readonly id: string;
659
+ readonly beginNodeId: string;
660
+ readonly beginParagraphId: string;
661
+ readonly endParagraphId: string;
662
+ readonly resultParagraphIds: readonly string[];
663
+ /** Direct parent whose paragraph children delimit the cached result. */
664
+ readonly containerId: string;
665
+ readonly contentControlId?: string;
666
+ readonly instruction: TocInstruction;
775
667
  }
776
- /** Where resource consumption is reported. Opaque marker until its milestone. */
777
- interface ResourceAccountingPort {
778
- readonly kind: 'resource-accounting';
668
+ /** Discover refreshable body TOCs without evaluating any field instruction. */
669
+ declare function detectBodyTocs(part: OoxmlPart): readonly DetectedToc[];
670
+ /** Locate the table of contents containing a position, or null. */
671
+ declare function findDetectedToc(tocs: readonly DetectedToc[], tocId: string): DetectedToc | null;
672
+
673
+ /** One heading symbol: its `w:font` and `w:char`, as the file wrote them. */
674
+ interface TocSymbol {
675
+ readonly font: string | null;
676
+ readonly char: string;
779
677
  }
678
+
679
+ declare const TWIPS: unique symbol;
680
+ declare const POINTS: unique symbol;
780
681
  /**
781
- * A required port the runtime did not provide.
682
+ * A length in twentieths of a point — OOXML's `ST_TwipsMeasure` / `ST_SignedTwipsMeasure`.
782
683
  *
783
- * Thrown rather than falling back: silently reaching for a browser global when a worker or server
784
- * adapter did not supply a port is exactly the coupling ports exist to prevent.
684
+ * The brand is intersection-typed onto `number`, so a `Twips` value still decays to `number`
685
+ * wherever arithmetic consumes it; only the reverse direction — passing a raw number where
686
+ * `Twips` is declared — is refused.
687
+ *
688
+ * @public
785
689
  */
786
- declare class PortResolutionError extends Error {
787
- readonly portId: string;
788
- constructor(portId: string);
789
- }
690
+ type Twips = number & {
691
+ readonly [TWIPS]: true;
692
+ };
790
693
  /**
791
- * The environment-dependent services an engine instance may reach.
694
+ * A length in typographic points, the unit layout and paint compute in.
792
695
  *
793
- * Everything outside pure computation — the clock, identity minting, scheduling, fonts, images —
794
- * is reached only through here, which is what lets browser, worker and server adapters supply
795
- * only what their runtime actually offers.
696
+ * @public
796
697
  */
797
- declare class PortRegistry {
798
- private readonly ports;
799
- provide(portId: string, port: unknown): this;
800
- has(portId: string): boolean;
801
- /** Resolve a port by id or throw. */
802
- resolve<T>(portId: string): T;
803
- /** Assert every id in `portIds` is present; returns the missing ones (empty if all present). */
804
- missing(portIds: readonly string[]): string[];
805
- /** The provided port ids (for bridging to registry.resolve availablePorts). */
806
- availablePorts(): string[];
807
- clock(): ClockPort;
808
- identity(): IdentityPort;
809
- }
810
- /** Deterministic clock: starts at `start` and advances by `step` each call. */
811
- declare class DeterministicClock implements ClockPort {
812
- private readonly step;
813
- private t;
814
- constructor(start?: number, step?: number);
815
- now(): number;
816
- }
817
- /** Sequential identity for tests and deterministic fixtures. */
818
- declare class SequentialIdentity implements IdentityPort {
819
- private readonly prefix;
820
- private n;
821
- constructor(prefix?: string);
822
- newId(): string;
823
- }
824
-
825
- /** What one operation is started with. Only `ports` is required. */
826
- interface OperationInit {
827
- readonly ports: PortRegistry;
828
- readonly limits?: Partial<ResourceLimits>;
829
- readonly config?: Readonly<Record<string, unknown>>;
830
- /** Root budget capacity in abstract units (default: the byte decompression limit). */
831
- readonly capacity?: number;
832
- /** Operation identity (from IdentityPort in production); defaulted for tests. */
833
- readonly id?: string;
834
- }
698
+ type Points = number & {
699
+ readonly [POINTS]: true;
700
+ };
835
701
  /**
836
- * The frozen environment of one operation: its limits, config, ports, root budget and
837
- * cancellation controller.
702
+ * Twentieths of a point per point.
838
703
  *
839
- * IMMUTABLE for the operation's lifetime, which is what lets cache reuse and replica agreement
840
- * key on it. A new operation always gets a fresh snapshot rather than observing a mutated one.
704
+ * @public
841
705
  */
842
- interface OperationContext {
843
- readonly id: string;
844
- readonly limits: ResourceLimits;
845
- readonly config: Readonly<Record<string, unknown>>;
846
- readonly ports: PortRegistry;
847
- readonly budget: Budget;
848
- readonly cancellation: CancellationController;
849
- }
706
+ declare const TWIPS_PER_POINT = 20;
850
707
  /**
851
- * Begin an operation, capturing its immutable environment snapshot.
708
+ * Assert that a number is a twips measurement.
852
709
  *
853
- * Resolves and freezes limits and configuration, carves the root budget, and creates the
854
- * cancellation controller — everything downstream work needs, fixed for the operation's duration.
710
+ * A compile-time cast, not a validator: bounds, integrality and finiteness stay at the parse
711
+ * boundary that produced the number, exactly where they are enforced today. The cast is the
712
+ * caller's claim about the UNIT, nothing more.
713
+ *
714
+ * @public
855
715
  */
856
- declare function beginOperation(init: OperationInit): OperationContext;
857
- /** Release the operation's root budget (requires every child/reservation released). */
858
- declare function endOperation(ctx: OperationContext): void;
859
-
860
- /** What a limit counts. Typed so a byte cap and a depth cap cannot be compared by accident. */
861
- type LimitUnit = 'bytes' | 'count' | 'depth' | 'ratio' | 'passes';
716
+ declare const twips: (value: number) => Twips;
862
717
  /**
863
- * Where a limit is enforced.
718
+ * Assert that a number is a points measurement. A compile-time cast; see {@link twips}.
864
719
  *
865
- * Declared per limit so enforcement happens at the boundary that can still refuse cheaply — a zip
866
- * cap checked during layout has already let the bomb decompress.
720
+ * @public
867
721
  */
868
- type EnforcementPhase = 'package-read' | 'xml-parse' | 'layout' | 'output';
869
- /** One limit's unit and enforcement phase — the metadata that makes limits testable uniformly. */
870
- interface LimitSpec {
871
- readonly unit: LimitUnit;
872
- readonly phase: EnforcementPhase;
873
- }
874
- /** Unit + enforcement phase for every resource limit. */
875
- declare const LIMIT_SPECS: Readonly<Record<keyof ResourceLimits, LimitSpec>>;
876
- /** Every limit name, for iterating the specs and asserting each has a unit and phase. */
877
- declare const LIMIT_KEYS: (keyof ResourceLimits)[];
878
- /** A phase-scoped overflow-safe counter for one limit. */
879
- declare function makeLimitCounter(limits: ResourceLimits, key: keyof ResourceLimits): BoundedCounter;
722
+ declare const points: (value: number) => Points;
880
723
  /**
881
- * Deterministic memory substitute. Tracks current and peak "allocated" units
882
- * against a hard byte ceiling; `allocate` fails closed (LimitExceededError) past
883
- * the limit. Used in place of process RSS so memory-limit tests are reproducible
884
- * and cancellation/cleanup can be asserted without a real allocator.
724
+ * The one twips-to-points conversion. Exact division; twips are the finer unit.
725
+ *
726
+ * @public
885
727
  */
886
- declare class DeterministicMemoryMeter {
887
- private readonly counter;
888
- private current;
889
- private peak;
890
- constructor(limitBytes: number);
891
- allocate(bytes: number): void;
892
- free(bytes: number): void;
893
- get currentBytes(): number;
894
- get peakBytes(): number;
895
- /** Release everything (cancellation/cleanup path). */
896
- reset(): void;
897
- }
898
- /** Assert the finite-default / hard-ceiling invariant holds for every limit. */
899
- declare function assertLimitInvariants(): void;
900
-
901
- /** Any JSON value. The domain canonicalization and stable hashing operate over. */
902
- type Json = null | boolean | number | string | Json[] | {
903
- [k: string]: Json;
904
- };
728
+ declare const twipsToPoints: (value: Twips) => Points;
905
729
  /**
906
- * Produce a canonical string for `value`, dropping any object key whose name is
907
- * in `ephemera` at any depth. Numbers are emitted losslessly; -0 normalizes to 0;
908
- * non-finite numbers are rejected (they must never enter a comparator input).
730
+ * The one points-to-twips conversion.
731
+ *
732
+ * Rounds to the nearest twip: every OOXML twips measurement is integral, and emitting a
733
+ * fractional twip would write a value no consumer of the file can represent.
734
+ *
735
+ * @public
909
736
  */
910
- declare function canonicalize(value: unknown, ephemera?: ReadonlySet<string>): string;
911
- /** 64-bit FNV-1a over the canonical form, returned as a 16-char hex string. */
912
- declare function stableHash(value: unknown, ephemera?: ReadonlySet<string>): string;
913
-
737
+ declare const pointsToTwips: (value: Points) => Twips;
914
738
  /**
915
- * How one artifact class is compared.
739
+ * Read a twips attribute (`ST_TwipsMeasure`, `ST_SignedTwipsMeasure`, or a `dxa` table width)
740
+ * as a whole, signed number of twips, or `null` when the value is not a measurement.
916
741
  *
917
- * Frozen per artifact: nothing here invents a tolerance for an artifact the spec requires to
918
- * match exactly.
742
+ * The schema allows an integer or a universal measure, but files also carry decimal twips
743
+ * (`4743.74`, `708.0`, `707.9999999999998`). The accepted forms read as follows:
744
+ *
745
+ * - A decimal truncates toward zero: `1443.74` is 1443 and `-720.6` is -720. A leading `+`,
746
+ * leading zeros, a bare fraction (`.5`) and a trailing point (`1440.`) are accepted.
747
+ * - A universal measure (`mm`, `cm`, `in`, `pt`, `pc`, `pi`) converts exactly and then
748
+ * truncates: `1.27cm` is 720 and `0.333in` is 479. Its sign is ignored, so `-0.5in` is 720.
749
+ * - Whitespace, exponents, hexadecimal, uppercase units, and an integer part longer than nine
750
+ * digits are not measurements.
751
+ *
752
+ * The result is NOT bounded. Callers apply their own sign rule and range clamp, because each
753
+ * attribute has a different valid range and a different fallback.
754
+ *
755
+ * @internal
919
756
  */
920
- type ComparatorMode = 'canonical-exact' | 'exact' | 'tolerance' | 'sync-optimization-only';
921
- /** One artifact class's comparison mode and its declared ephemera — fields excluded from equality. */
922
- interface ComparatorDescriptor {
923
- readonly id: string;
924
- readonly mode: ComparatorMode;
925
- /** Object keys excluded from canonical-exact comparison (declared ephemera). */
926
- readonly ephemera: readonly string[];
927
- readonly note: string;
757
+ declare function readTwipsMeasure(raw: string | undefined): number | null;
758
+
759
+ /** Outline heading shape consumed by TOC planning (mirrors DocumentOutlineEntry). */
760
+ interface TocOutlineHeading {
761
+ readonly text: string;
762
+ readonly level: number;
763
+ readonly blockId: string;
928
764
  }
929
- /** The frozen artifact comparator set. */
930
- declare const COMPARATORS: {
931
- readonly authoredState: {
932
- readonly id: "dev.docx-editor.core.comparator.authored-state";
933
- readonly mode: 'canonical-exact';
934
- readonly ephemera: readonly ["revision", "provenance", "producedAt", "commitId"];
935
- readonly note: 'canonical normalized authored records; ephemera excluded';
936
- };
937
- readonly anchor: {
938
- readonly id: "dev.docx-editor.core.comparator.anchor";
939
- readonly mode: 'exact';
940
- readonly ephemera: readonly [];
941
- readonly note: 'internal anchor identity/affinity compares exactly';
942
- };
943
- readonly yjsStateVector: {
944
- readonly id: "dev.docx-editor.core.comparator.yjs-state-vector";
945
- readonly mode: 'sync-optimization-only';
946
- readonly ephemera: readonly [];
947
- readonly note: 'exchange optimization only; never proves update or delete-set coverage';
948
- };
949
- readonly shapedRun: {
950
- readonly id: "dev.docx-editor.core.comparator.shaped-run";
951
- readonly mode: 'exact';
952
- readonly ephemera: readonly [];
953
- readonly note: 'glyph ids, clusters, and fixed-point advances compare exactly';
954
- };
955
- readonly paginationFingerprint: {
956
- readonly id: "dev.docx-editor.core.comparator.pagination-fingerprint";
957
- readonly mode: 'exact';
958
- readonly ephemera: readonly [];
959
- readonly note: 'page/column boundaries, break causes, fixed-point geometry compare exactly';
960
- };
961
- readonly semanticTree: {
962
- readonly id: "dev.docx-editor.core.comparator.semantic-tree";
963
- readonly mode: 'exact';
964
- readonly ephemera: readonly [];
965
- readonly note: 'reading order, roles, headings, alt text compare exactly';
966
- };
967
- readonly hitTest: {
968
- readonly id: "dev.docx-editor.core.comparator.hit-test";
969
- readonly mode: 'exact';
970
- readonly ephemera: readonly [];
971
- readonly note: 'resolved hit target and cluster affinity compare exactly';
972
- };
973
- readonly pdfSemantics: {
974
- readonly id: "dev.docx-editor.core.comparator.pdf-semantics";
975
- readonly mode: 'canonical-exact';
976
- readonly ephemera: readonly ["objectNumber", "producer", "creationDate", "modDate", "subsetTag"];
977
- readonly note: 'canonical semantic PDF objects; container ephemera excluded';
978
- };
979
- readonly rasterCheckpoint: {
980
- readonly id: "dev.docx-editor.core.comparator.raster-checkpoint";
981
- readonly mode: 'tolerance';
982
- readonly ephemera: readonly [];
983
- readonly note: 'documented unavoidable raster comparison; explicit tolerance only';
984
- };
985
- readonly benchmarkEvidence: {
986
- readonly id: "dev.docx-editor.core.comparator.benchmark-evidence";
987
- readonly mode: 'sync-optimization-only';
988
- readonly ephemera: readonly [];
989
- readonly note: 'diagnostic evidence, not an equivalence basis';
990
- };
991
- };
992
- /** Which frozen comparator to use. */
993
- type ComparatorName = keyof typeof COMPARATORS;
994
- /** Whether two artifacts matched, and where they diverged when they did not. */
995
- interface ComparisonResult {
996
- readonly equal: boolean;
997
- /** Canonical forms when unequal (diagnostic). */
998
- readonly left?: string;
999
- readonly right?: string;
765
+
766
+ /** Left-indent step between TOC levels, in twips (matches `scripts/demo-doc/toc-block.xml`). */
767
+ declare const TOC_LEVEL_INDENT_TWIPS: Twips;
768
+ /** Bounded left-indent twips for a TOC entry level (0-based heading depth). */
769
+ declare function tocLeftIndentTwips(level: number): Twips;
770
+ /** One planned TOC entry: its level, its text, and the heading it points at. */
771
+ interface TocEntryPlan {
772
+ readonly level: number;
773
+ readonly text: string;
774
+ readonly headingParagraphId: string;
775
+ readonly bookmarkName: string;
776
+ readonly pageNumberText: string;
777
+ /** The heading's symbols, one per {@link TOC_SYMBOL_MARK} in `text`, in order. */
778
+ readonly symbols?: readonly TocSymbol[];
1000
779
  }
780
+ /** Build one TOC entry paragraph node. */
781
+ declare function buildTocEntryParagraph(mint: () => string, entry: TocEntryPlan, instruction: TocInstruction, paragraphPropertiesTemplate?: OoxmlNode): OoxmlNode;
782
+ /** Build an SDT-wrapped complex TOC field with an already planned cached result. */
783
+ declare function buildTocContentControl(mint: () => string, entries: readonly TocEntryPlan[], instruction: TocInstruction, alias: string): OoxmlNode;
1001
784
  /**
1002
- * Compare two artifacts under a named comparator. `canonical-exact` and `exact`
1003
- * compare canonical forms (exact drops no ephemera). `tolerance` requires an
1004
- * epsilon and compares finite numbers structurally. `sync-optimization-only`
1005
- * throws — such artifacts are never an equivalence basis.
785
+ * Word flattens manual line/tab breaks from a heading into spaces in its TOC cache.
786
+ * Carrying them verbatim makes a short title wrap even when the row has ample room, and the
787
+ * same normalization is what lets a cached row be matched back to the heading it came from.
1006
788
  */
1007
- declare function compareArtifacts(name: ComparatorName, left: unknown, right: unknown, opts?: {
1008
- epsilon?: number;
1009
- }): ComparisonResult;
1010
- /** Fingerprint an artifact under a named comparator's canonicalization policy. */
1011
- declare function fingerprint(name: ComparatorName, value: unknown): string;
1012
-
1013
- /** Whether a recorded conformance step was expected to commit or be refused. */
1014
- type FixtureOutcome = 'applied' | 'aborted' | 'validation' | 'conflict' | 'resource' | 'authorization';
1015
- /** The change one step produced, summarized to what a fixture can compare across runtimes. */
1016
- interface ModelChangeSummary {
1017
- readonly fromRevision: number;
1018
- readonly toRevision: number;
1019
- readonly origin: string;
1020
- readonly dirty: readonly string[];
1021
- readonly dependencyKeys: readonly string[];
1022
- }
1023
- /** Where anchors sat after a step — how a fixture proves positions survived an edit. */
1024
- interface AnchorSnapshot {
1025
- readonly anchorId: string;
1026
- readonly story: string;
1027
- readonly block: string;
1028
- readonly affinity: 'before' | 'after';
1029
- }
1030
- /** What one step must produce: its outcome, its change summary, and its authored-state hash. */
1031
- interface FixtureExpectation {
1032
- readonly outcome: FixtureOutcome;
1033
- /** Present iff outcome === 'applied'; MUST be > baseRevision. */
1034
- readonly committedRevision?: number;
1035
- readonly modelChange?: ModelChangeSummary;
1036
- /** 16-hex authored-state fingerprint (comparator 0.4). */
1037
- readonly authoredStateHash?: string;
1038
- readonly outputHash?: string;
1039
- readonly anchors?: readonly AnchorSnapshot[];
1040
- }
1041
- /** One recorded operation and what it was expected to do. */
1042
- interface FixtureStep {
1043
- readonly baseRevision: number;
1044
- readonly origin: string;
1045
- /** Opaque DocOp payloads (schema owned by section 4). */
1046
- readonly ops: readonly unknown[];
1047
- readonly expect: FixtureExpectation;
1048
- }
1049
- /** Opaque encoded backend bytes (snapshot or replication update). */
1050
- interface EncodedEnvelope {
1051
- readonly kind: 'snapshot' | 'update';
1052
- readonly protocolVersion: number;
1053
- readonly schemaVersion: number;
1054
- readonly documentId: string;
1055
- readonly byteLength: number;
1056
- /** Hex-encoded opaque bytes; length MUST equal byteLength. */
1057
- readonly bytesHex: string;
1058
- }
1059
- /** Which implementation recorded a fixture — local store, Yjs, or a binding. */
1060
- type FixtureSource = {
1061
- readonly kind: 'create';
1062
- } | {
1063
- readonly kind: 'docx';
1064
- readonly sha256: string;
1065
- readonly bytesRef: string;
789
+ declare function tocEntryText(text: string): string;
790
+ /**
791
+ * Plan TOC entries from the outline and existing bookmarks.
792
+ *
793
+ * `actorId` is explicit because this planner runs BEFORE the store transaction, so the
794
+ * ambient transaction actor is not bound. Callers that already have the collaboration
795
+ * identity pass it here. `resolveAllocationActor` still honours a
796
+ * `runWithTransactionActor` wrap when the caller prefers that seam.
797
+ */
798
+ declare function planTocEntries(part: OoxmlPart, outline: readonly TocOutlineHeading[], instruction: TocInstruction, pageNumberByParagraphId: ReadonlyMap<string, string>, excludeParagraphIds: ReadonlySet<string>, actorId?: string): {
799
+ readonly entries: readonly TocEntryPlan[];
800
+ readonly bookmarksToCreate: readonly {
801
+ paragraphId: string;
802
+ name: string;
803
+ }[];
804
+ };
805
+ /** Create bookmarkStart/End pair nodes for insertion at the start of a paragraph. */
806
+ declare function bookmarkPairNodes(mint: () => string, name: string, id: string): {
807
+ readonly start: OoxmlNode;
808
+ readonly end: OoxmlNode;
1066
809
  };
810
+
1067
811
  /**
1068
- * The frozen conformance container: revisions, origins, operations, changes, snapshots and
1069
- * hashes.
812
+ * The heading each cached result row stands for, aligned with `toc.resultParagraphIds`.
1070
813
  *
1071
- * The CONTAINER is what is frozen — field names, origin membership, revision monotonicity, hash
1072
- * format. The op and change payloads travel opaquely, so their schemas can evolve without
1073
- * invalidating every recorded fixture.
814
+ * `null` for a row that names no heading this document still has — a stale row, or the
815
+ * chrome/blank paragraphs a cached result can carry. Callers leave those alone rather than
816
+ * writing another row's number into them.
1074
817
  */
1075
- interface ConformanceFixture {
1076
- readonly formatVersion: 1;
1077
- readonly documentId: string;
1078
- readonly source: FixtureSource;
1079
- readonly steps: readonly FixtureStep[];
1080
- readonly snapshots?: readonly EncodedEnvelope[];
1081
- readonly updates?: readonly EncodedEnvelope[];
1082
- }
1083
- /** Whether a fixture is well-formed, listing every structural violation. */
1084
- interface ValidationResult {
1085
- readonly valid: boolean;
1086
- readonly errors: readonly string[];
1087
- }
1088
- /** Structurally validate a fixture against the frozen format rules. */
1089
- declare function validateFixture(fixture: ConformanceFixture): ValidationResult;
818
+ declare function resolveTocRowHeadings(part: OoxmlPart, toc: DetectedToc, outline: readonly TocOutlineHeading[], excludeParagraphIds: ReadonlySet<string>): readonly (string | null)[];
1090
819
 
1091
- /** The outcome a store reports for one replayed step. */
1092
- interface ReplayOutcome {
1093
- readonly outcome: FixtureOutcome;
1094
- readonly committedRevision?: number;
1095
- /** Canonical authored-state value AFTER the step (hashed via comparator 0.4). */
1096
- readonly authoredState?: unknown;
820
+ /** One paragraph in the index: its node id, its story, and its position. */
821
+ interface ParagraphIndexEntry {
822
+ /** Canonical tree node id — the stable identity operations address. */
823
+ readonly nodeId: string;
824
+ /** Position among the story's paragraphs, in document order. */
825
+ readonly ordinal: number;
826
+ /** Concatenated text content, with tabs and breaks mapped as the model reads them. */
827
+ readonly text: string;
828
+ /** Node ids of the paragraph's runs, in order. */
829
+ readonly runIds: readonly string[];
1097
830
  }
1098
- /** The interface a conformance runtime implements so one fixture can drive every backend. */
1099
- interface ReplayStore {
1100
- /** Initialize from the fixture source; return the initial revision (0 for create). */
1101
- init(fixture: ConformanceFixture): number;
1102
- /** Apply one step and report what happened. */
1103
- applyStep(step: FixtureStep): ReplayOutcome;
831
+ /** One story root — body, a header/footer variant, or a note part. */
832
+ interface StoryIndexEntry {
833
+ /** The part the story lives in. */
834
+ readonly partName: string;
835
+ /** The `w:body` (or story root) node id. */
836
+ readonly rootId: string;
837
+ readonly paragraphs: readonly ParagraphIndexEntry[];
1104
838
  }
1105
- /** What replaying a fixture produced: per-step outcomes and where they diverged. */
1106
- interface ReplayReport {
1107
- readonly ok: boolean;
1108
- readonly mismatches: readonly string[];
839
+ /** One style definition, indexed by the id content references it under. */
840
+ interface StyleIndexEntry {
841
+ readonly styleId: string;
842
+ readonly type: string;
843
+ readonly nodeId: string;
844
+ readonly name: string | null;
845
+ readonly basedOn: string | null;
846
+ /** Whether the part marks this the default style for its type (`w:default="1"`). */
847
+ readonly isDefault: boolean;
1109
848
  }
1110
849
  /**
1111
- * Replay a fixture against a store and check every step's outcome, committed
1112
- * revision, and authored-state fingerprint against the fixture's expectations.
1113
- */
1114
- declare function replayFixture(fixture: ConformanceFixture, store: ReplayStore): ReplayReport;
1115
- /** Hash a store's authored state, so two runtimes replaying one fixture can be compared. */
1116
- declare function hashAuthored(authoredState: unknown): string;
1117
-
1118
- /**
1119
- * Keys that must never be assigned from file data.
850
+ * The derived lookups over a part: paragraphs, stories and styles by id.
1120
851
  *
1121
- * XML attribute names become object keys, and a document controls those names — assigning
1122
- * `__proto__` into an ordinary object is the prototype-pollution hazard this engine audits for.
852
+ * Diff-patched on commit rather than rebuilt — rebuilding every index per keystroke is what made
853
+ * typing scale with document length.
1123
854
  */
1124
- declare const DANGEROUS_KEYS: readonly string[];
1125
- /** A file-derived key that would pollute a prototype. Refused, never sanitized-and-accepted. */
1126
- declare class DangerousKeyError extends Error {
1127
- readonly key: string;
1128
- readonly path: string;
1129
- constructor(key: string, path: string);
855
+ interface OoxmlIndexes {
856
+ /** The tree revision these projections were derived from. */
857
+ readonly revision: number;
858
+ /** Body story first, then any other story parts, keyed by part name. */
859
+ readonly stories: ReadonlyMap<string, StoryIndexEntry>;
860
+ /** Every paragraph across every story, keyed by node id. */
861
+ readonly paragraphs: ReadonlyMap<string, ParagraphIndexEntry>;
862
+ readonly relationships: ReadonlyMap<string, readonly RelationshipRecord[]>;
863
+ readonly styles: ReadonlyMap<string, StyleIndexEntry>;
1130
864
  }
1131
- /** Whether a key is one of {@link DANGEROUS_KEYS}. */
1132
- declare function isDangerousKey(key: string): boolean;
1133
- /** A fresh null-prototype record — the only object shape parser intermediates use. */
1134
- declare function nullRecord<T = unknown>(): Record<string, T>;
865
+ /** Style definitions, read out of the generic `w:styles` tree. */
866
+ declare function indexStyles(part: OoxmlPart | undefined): Map<string, StyleIndexEntry>;
867
+ /** The package's style definitions part, if it has one. */
868
+ declare function stylesPartOf(pkg: OoxmlPackage): OoxmlPart | undefined;
1135
869
  /**
1136
- * Recursively convert `value` into null-prototype records, rejecting any
1137
- * dangerous object key. Arrays and primitives pass through (arrays rebuilt so no
1138
- * inherited prototype pollution survives). Throws DangerousKeyError on the first
1139
- * unsafe key, naming its path. Cyclic inputs are rejected.
870
+ * Derive every index from one canonical package revision.
871
+ *
872
+ * Pure: the same package and revision always produce the same index, which is what makes
873
+ * "rebuild rather than mutate" a safe invalidation strategy.
1140
874
  */
1141
- declare function toSafeRecord(value: unknown, path?: string): unknown;
875
+ declare function deriveOoxmlIndexes(pkg: OoxmlPackage, revision: number): OoxmlIndexes;
1142
876
 
1143
- /** Locate `[Content_Types].xml` bytes regardless of zip key spelling. */
1144
- declare function contentTypesPartBytes(pkg: OoxmlPackage): {
1145
- readonly storageKey: string;
1146
- readonly bytes: Uint8Array;
1147
- } | null;
877
+ /** One paragraph's meaning, independent of how it was spelled in XML. */
878
+ interface ParagraphDigest {
879
+ /** Ordinal identity within its story. Node ids are NOT used: a reopened package
880
+ * legitimately re-derives them, and requiring them to match would test the id scheme
881
+ * rather than the content. */
882
+ readonly ordinal: number;
883
+ /**
884
+ * Where the paragraph SITS: the element path from the story root, so a paragraph that
885
+ * moves out of the table cell it was written in is a difference rather than a paragraph
886
+ * with the same ordinal and the same text.
887
+ */
888
+ readonly path: string;
889
+ /**
890
+ * `w14:paraId`, uppercase-normalized (matching is case-insensitive), or null. This is
891
+ * MANAGED identity — the agent contract anchors on it and comment threading references
892
+ * it — so a serializer silently dropping it must be a digest difference. Other paragraph
893
+ * attributes (`w:rsidR` …) stay deliberately undigested: they are revision noise.
894
+ */
895
+ readonly paraId: string | null;
896
+ /** Text content, including tabs and hard breaks as their characters. */
897
+ readonly text: string;
898
+ /** Accepted paragraph properties, as sorted tokens including nested children. */
899
+ readonly paragraphProperties: readonly string[];
900
+ /** Per-run accepted properties, in run order. */
901
+ readonly runProperties: readonly (readonly string[])[];
902
+ /** Fingerprints of every generic (unknown) subtree, in document order. */
903
+ readonly genericStructure: readonly string[];
904
+ }
905
+ /** One story reduced to its semantic content, ignoring everything a normalized re-emit changes. */
906
+ interface StoryDigest {
907
+ readonly partName: string;
908
+ readonly paragraphs: readonly ParagraphDigest[];
909
+ /**
910
+ * Every block-level element of the part OUTSIDE a paragraph, in document order, as
911
+ * `path name(attributes)` — the tables, rows, cells, sections, content controls and
912
+ * their property children, each at the position that says what contains it.
913
+ *
914
+ * A paragraph's own internals are not here (they are its `ParagraphDigest`), which keeps
915
+ * this list proportional to a document's STRUCTURE rather than its text.
916
+ */
917
+ readonly structure: readonly string[];
918
+ }
1148
919
  /**
1149
- * What a package-level invariant walk found wrong.
920
+ * The whole document's semantic content — one of the D9 losslessness oracles.
1150
921
  *
1151
- * Package invariants are cross-PART: a relationship pointing at a part that does not exist, or a
1152
- * part no content-type record covers. Neither is visible from inside a single part's tree.
922
+ * What a save/reopen round-trip is compared on. Byte identity applies only to non-XML parts;
923
+ * modelled parts re-emit normalized, so equality is asserted HERE rather than on bytes.
1153
924
  */
1154
- type PackageInvariantCode = 'dangling-relationship' | 'missing-content-type'
1155
- /** A part occupies a name OPC reserves for package infrastructure. */
1156
- | 'reserved-part-name'
1157
- /** Two parts whose names differ only by case, which OPC treats as one part. */
1158
- | 'duplicate-part-name'
1159
- /** A part name the OPC screens refuse; `writeZip` would throw on save. */
1160
- | 'unsafe-part-name';
1161
- /** One package invariant violation, located by part name and relationship id. */
1162
- interface PackageInvariantIssue {
1163
- readonly code: PackageInvariantCode;
1164
- /** The part the issue is about: the missing target, or the part with no type. */
1165
- readonly partName: string;
1166
- /** For a dangling relationship, the owner that points at nothing. */
1167
- readonly ownerPart?: string;
925
+ interface SemanticDigest {
926
+ readonly stories: readonly StoryDigest[];
1168
927
  }
1169
- /** Whether a package satisfies its cross-part invariants, listing every violation otherwise. */
1170
- type PackageInvariantResult = {
1171
- readonly ok: true;
1172
- } | {
1173
- readonly ok: false;
1174
- readonly issues: readonly PackageInvariantIssue[];
928
+ /** Where two digests diverge — the diagnostic when a round-trip loses something. */
929
+ type DigestDifference = {
930
+ readonly path: string;
931
+ readonly before: string;
932
+ readonly after: string;
1175
933
  };
1176
- /** Relationship records owned by one part, in authored order. */
1177
- declare function relationshipsOf(pkg: OoxmlPackage, ownerPart: string): readonly RelationshipRecord[];
1178
- /** The content type that resolves for a part name, or null when nothing declares one. */
1179
- declare function resolveContentTypeOf(pkg: OoxmlPackage, partName: string): string | null;
1180
- /** The `.rels` part that owns a part's relationships, by OPC convention. */
1181
- declare function relsPartNameFor(partName: string): string;
934
+ /** Digest one part: its paragraphs, and the structure that holds them. */
935
+ declare function digestPart(part: OoxmlPart): StoryDigest | null;
936
+ /** Digest every part, in the given order. */
937
+ declare function semanticDigest(parts: Iterable<OoxmlPart>): SemanticDigest;
1182
938
  /**
1183
- * Declare a content type for a part, by upserting an `<Override>` in the content-types tree.
939
+ * Every way two digests differ, as readable paths.
1184
940
  *
1185
- * A no-op when the part already resolves to the same type, so repeating a write does not append
1186
- * a duplicate entry. Resolving to a DIFFERENT type replaces the existing Override in place.
1187
- * `forceOverride` writes an explicit Override even when a Default already matches.
941
+ * Returns the differences rather than a boolean because "the round trip lost something" is
942
+ * useless without saying what — the failure this oracle exists to catch is a silent drop,
943
+ * and a bare `false` reproduces the silence.
1188
944
  */
1189
- declare function withContentTypeOverride(pkg: OoxmlPackage, partName: string, contentType: string, options?: {
1190
- readonly forceOverride?: boolean;
1191
- }): OoxmlPackage;
1192
- /** What {@link withoutPart} answers: `ok: false` leaves the package exactly as it was. */
1193
- interface WithoutPartResult {
1194
- readonly pkg: OoxmlPackage;
1195
- readonly ok: boolean;
1196
- }
1197
- /** Add or replace one relationship on a part, returning a new package. */
1198
- declare function withRelationship(pkg: OoxmlPackage, ownerPart: string, type: string, rawTarget: string): {
1199
- readonly pkg: OoxmlPackage;
1200
- readonly relationshipId: string;
1201
- readonly ok: boolean;
1202
- };
945
+ declare function diffSemanticDigests(before: SemanticDigest, after: SemanticDigest): DigestDifference[];
946
+
947
+ /** Valid per MS-DOCX: 8 hex digits, non-zero, below 0x80000000. */
948
+ declare function isValidParaId(value: string): boolean;
949
+ /** The authored `w14:paraId` value of an element, verbatim, or null. */
950
+ declare function paraIdOf(node: OoxmlNode): string | null;
951
+ /** FNV-1a over UTF-16 code units — the deterministic mint every id derivation shares. */
952
+ declare function fnv1a32(value: string): number;
1203
953
  /**
1204
- * Add a part that does not exist yet, with the content-type override it needs to be openable.
954
+ * Deterministic 8-hex mint in (0x00000000, 0x80000000), collision-free against
955
+ * `used` (uppercase hex). Same seed + same used-set → same value, which is what
956
+ * keeps `splitParagraphMany` byte-identical to its equivalent single splits and
957
+ * a reopened save identical to the session that produced it.
958
+ */
959
+ declare function mintParaId(seed: string, used: ReadonlySet<string>): string;
960
+ /** Every valid `w14:paraId` in the tree, uppercased. Memoized per root object. */
961
+ declare function usedParaIds(root: OoxmlElement): ReadonlySet<string>;
962
+ /**
963
+ * The non-empty prefix the part ROOT binds to the w14 namespace, or null.
1205
964
  *
1206
- * Deliberately does NOT create a relationship: a part is reachable because something points at
1207
- * it, and which part points at it is the caller's decision. Creating one here would guess.
965
+ * Minted attributes require an in-scope binding (the invariant validator reports
966
+ * `invalid-qname` otherwise, and the serializer would allocate an `nsN` alias).
967
+ * Only the root binding counts: a binding authored on some descendant does not
968
+ * cover paragraphs elsewhere in the tree.
1208
969
  */
1209
- declare function withNewPart(pkg: OoxmlPackage, partName: string, root: OoxmlElement, contentType: string): OoxmlPackage;
970
+ declare function w14RootPrefix(root: OoxmlElement): string | null;
971
+ /** The minted `[w14:paraId, w14:textId]` pair. `textId` mirrors `paraId`: it has no uniqueness requirement, no consumer reads it, and one allocator is simpler than two — but Word writes both, so we write both. */
972
+ declare function mintedParagraphIdentityAttributes(prefix: string, value: string): readonly OoxmlAttribute[];
1210
973
  /**
1211
- * The two invariants a package must satisfy before it is published.
974
+ * Load-time paragraph-identity normalization for a session's main part.
1212
975
  *
1213
- * Both describe the half-written state that splitting a multi-part write across transactions
1214
- * produces, and both make a package Word refuses to open:
976
+ * Keeps every valid, first-seen paraId verbatim; mints (deterministically, seeded
977
+ * by the paragraph's structural node id) for paragraphs whose id is missing,
978
+ * malformed, zero, out of range, or a duplicate. Adds the root `xmlns` binding
979
+ * the minted attributes need. Returns the INPUT PART REFERENCE when there is
980
+ * nothing to do — a document Word saved yesterday re-serializes byte-identical.
1215
981
  *
1216
- * - a relationship pointing at a part nobody created;
1217
- * - a part with no content type, which is unopenable even though the XML is well formed.
982
+ * Attribute-only rebuilds move no child, so every node keeps its structural-path
983
+ * id; the copy respreads only the ancestors of changed paragraphs.
1218
984
  *
1219
- * Checked at the commit boundary rather than inside each primitive, for the same reason part
1220
- * validation moved there: a transaction is allowed to pass through an inconsistent intermediate
1221
- * as long as nothing can observe it.
985
+ * Fail-open: if the rebuilt part does not validate (a bug, or a pathology the
986
+ * prefix choice could not defuse), the original part is returned — a document
987
+ * must never become unopenable over an identity enhancement.
1222
988
  */
1223
- declare function validatePackageInvariants(pkg: OoxmlPackage): PackageInvariantResult;
989
+ declare function normalizeParagraphIdentity(part: OoxmlPart): OoxmlPart;
990
+
991
+ /** One `w:docPart` of the glossary, with the blocks its body holds. */
992
+ interface BuildingBlock {
993
+ /** `w:docPartPr/w:name`, the identity a control's placeholder and a pick refer to. */
994
+ readonly name: string;
995
+ /** `w:category/w:gallery`, an `ST_DocPartGallery` value such as `docParts`. */
996
+ readonly gallery: string;
997
+ /** `w:category/w:name`; `General` when the block declares none. */
998
+ readonly category: string;
999
+ /** The `w:docPartBody` children: paragraphs, tables and block controls, in order. */
1000
+ readonly blocks: readonly OoxmlNode[];
1001
+ }
1002
+ /** The gallery and category a `w:docPartList` control lists. */
1003
+ interface BuildingBlockGalleryFilter {
1004
+ readonly gallery: string;
1005
+ readonly category: string | null;
1006
+ }
1007
+ /** The glossary part, through the main part's relationship or the conventional name. */
1008
+ declare function glossaryPartOf(pkg: OoxmlPackage): OoxmlPart | null;
1009
+ /** Every named building block of the glossary, in authored order. Empty without a glossary. */
1010
+ declare function buildingBlocksOf(pkg: OoxmlPackage): readonly BuildingBlock[];
1011
+ /** The gallery a `w:docPartList` control lists, or null for any other control. */
1012
+ declare function buildingBlockGalleryOf(control: OoxmlNode): BuildingBlockGalleryFilter | null;
1013
+ /**
1014
+ * The blocks a gallery control offers: same gallery, and the control's category when it names
1015
+ * one. Sorted by category, then name, as Word groups its list.
1016
+ */
1017
+ declare function buildingBlocksForControl(pkg: OoxmlPackage, control: OoxmlNode): readonly BuildingBlock[];
1224
1018
 
1225
1019
  /**
1226
- * Whether a string is a valid XML NCName in the strict ASCII profile — a name with no colon.
1020
+ * Which story a comment deletion or resolution may read markers from.
1227
1021
  *
1228
- * This is the rule for names the engine itself writes or accepts from a caller. Names read
1229
- * from a document use {@link isXmlNCName}, which admits every XML 1.0 name.
1022
+ * `w:id` is not unique across stories: a header and the body can both hold comment 1.
1230
1023
  */
1231
- declare function isValidNCName(name: string): boolean;
1232
- /** A QName is an optional `prefix:` (both NCNames) — never attacker-derived. */
1233
- declare function isValidQName(name: string): boolean;
1024
+ interface CommentDeletionOwner {
1025
+ /** Canonical name of the part holding the story's markers. */
1026
+ readonly storyPartName: string;
1027
+ /**
1028
+ * When the story is one note inside a shared notes part, that note's `w:id`.
1029
+ * Absent means the whole part is the story (body, header, footer).
1030
+ */
1031
+ readonly noteId?: number;
1032
+ }
1033
+
1234
1034
  /**
1235
- * Validate a qualified name, throwing when it is malformed.
1035
+ * Delete a comment thread: that story's markers, and metadata no other story still names.
1236
1036
  *
1237
- * Guards the serializer: an invalid QName written into XML produces a file Word cannot open, so
1238
- * it fails here rather than at save.
1037
+ * `owner` names the story whose markers may be stripped. Omitted, it is the main document
1038
+ * body — never every XML part. A header or note that reused the same `w:id` is a different
1039
+ * remark; pass its part (and `noteId` when the story is one note) to delete that one.
1040
+ *
1041
+ * Returns the package unchanged when the id names no comment, and null when a removal was
1042
+ * refused — a caller inside a transaction rolls back rather than committing a package whose
1043
+ * comment is half gone.
1239
1044
  */
1240
- declare function assertValidQName(name: string): void;
1045
+ declare function deleteCommentThread(pkg: OoxmlPackage, commentId: string, owner?: CommentDeletionOwner): OoxmlPackage | null;
1241
1046
  /**
1242
- * Controlled namespace-prefix allocation: deterministic, collision-free prefixes
1243
- * for namespace URIs. A known URI always yields the same registered prefix; new
1244
- * URIs get a generated `ns{n}` prefix, never one derived from file content.
1047
+ * Delete every comment the edit between `before` and `after` emptied in `owner`'s story.
1048
+ *
1049
+ * `owner` omitted is the main document body, matching {@link deleteCommentThread}.
1050
+ *
1051
+ * THE TEST, exactly, and per story. A comment dies when the words it covered in that story are
1052
+ * gone and nothing in that story still places it. A neighbour that reused the same `w:id` is
1053
+ * judged under its own owner. Notes that vanished (reference cascade) are reaped as their own
1054
+ * stories so a unique id still loses its `comments.xml` body. Remaining-marker overflow
1055
+ * preserves comments/commentEx/commentId metadata rather than deleting records the scan could
1056
+ * not prove unused. Null is reserved for a removal that actually failed.
1245
1057
  */
1246
- declare class PrefixAllocator {
1247
- private readonly byUri;
1248
- private readonly usedPrefixes;
1249
- private counter;
1250
- constructor(known?: Readonly<Record<string, string>>);
1251
- prefixFor(namespaceUri: string): string;
1252
- /** The declared bindings, for emitting xmlns declarations. */
1253
- bindings(): {
1254
- prefix: string;
1255
- uri: string;
1256
- }[];
1058
+ declare function cascadeEmptiedComments(before: OoxmlPackage, after: OoxmlPackage, owner?: CommentDeletionOwner): OoxmlPackage | null;
1059
+
1060
+ /** Presentation settings the document itself states. Absence is the answer, never an error. */
1061
+ interface DocumentViewSettings {
1062
+ /**
1063
+ * `w:doNotShadeFormData` (§17.15.1.49) — do NOT shade legacy form fields.
1064
+ *
1065
+ * Word draws a grey block behind every `w:ffData` field so a reader can find the blanks in a
1066
+ * form. It is on by DEFAULT, and this element is how a document turns it off, so the absent
1067
+ * case means shading. Reading the name as "shade form data" inverts it and blanks the shading
1068
+ * on exactly the documents that asked for it loudest.
1069
+ *
1070
+ * Never printed, by Word or by us: it marks where to type, and a printed form has no blanks
1071
+ * to find.
1072
+ */
1073
+ readonly doNotShadeFormData: boolean;
1257
1074
  }
1075
+ /** The defaults a document with no `settings.xml` gets: everything Word would shade, shaded. */
1076
+ declare const DEFAULT_VIEW_SETTINGS: DocumentViewSettings;
1077
+ /** Read the view settings from a `settings.xml` root, or the defaults when it has none. */
1078
+ declare function readViewSettings(settingsRoot: OoxmlNode | null | undefined): DocumentViewSettings;
1258
1079
 
1080
+ /** How deep transparent block wrappers may nest before the walk stops descending. */
1081
+ declare const MAX_STORY_SDT_NESTING = 32;
1082
+ /** Which kind of story a root is. Layout walks all four the same way. */
1083
+ type OoxmlStoryKind = 'body' | 'header' | 'footer' | 'note';
1084
+ /** One story root and the blocks under it, with transparent block wrappers already flattened. */
1085
+ interface OoxmlStoryRoot {
1086
+ readonly kind: OoxmlStoryKind;
1087
+ /** The `w:body` / `w:hdr` / `w:ftr` / `w:footnote` element that holds the blocks. */
1088
+ readonly root: OoxmlNode;
1089
+ }
1259
1090
  /**
1260
- * A hyperlink target projected for a RUNTIME sink, or the reason it was withheld.
1091
+ * Every story root in a part, in document order.
1261
1092
  *
1262
- * The authored target stays authored — the record layer keeps it verbatim and escapes it into
1263
- * owned OOXML, which is not a runtime sink. Only this allowlist-sanitized projection reaches DOM,
1264
- * CSS, navigation or fetch, so `javascript:`, `data:` and `vbscript:` never leave the boundary.
1265
- */
1266
- type HrefProjection = {
1267
- readonly ok: true;
1268
- readonly href: string;
1269
- } | {
1270
- readonly ok: false;
1271
- readonly inert: true;
1272
- };
1093
+ * Does not descend INTO a story: a story's blocks are the walk below, and a story root never
1094
+ * contains another story root.
1095
+ */
1096
+ declare function storyRootsOf(part: OoxmlPart): readonly OoxmlStoryRoot[];
1273
1097
  /**
1274
- * Project a file-derived URL for a DOM/navigation sink. Strips embedded
1275
- * tab/LF/CR (used to smuggle `java\nscript:`), allows relative URLs and the
1276
- * scheme allowlist, and renders everything else inert. Never fetches.
1098
+ * Whether a part is SHAPED to hold stories — a body, a header, a footer, or a notes part.
1099
+ *
1100
+ * A shape test, deliberately not `storyRootsOf(part).length > 0`. That counts EDITABLE stories,
1101
+ * and a notes part holding nothing but `w:separator` and `w:continuationSeparator` has none —
1102
+ * which is the footnotes part Word writes into every document that ever held a footnote. A
1103
+ * caller asking "should I walk this part at all" that used the editable count skipped it
1104
+ * entirely, and the two callers that ask are a payload sweep and an export strip: both DELETE
1105
+ * what they conclude nothing names.
1277
1106
  */
1278
- declare function sanitizeHref(raw: string): HrefProjection;
1279
- /** XML-escape a value for validated serialization back into owned OOXML. */
1280
- declare function escapeXml(value: string): string;
1107
+ declare function isStoryPart(part: OoxmlPart): boolean;
1108
+ /** The main body story of a part, or null when the part holds none. */
1109
+ declare function bodyStoryRoot(part: OoxmlPart): OoxmlNode | null;
1281
1110
  /**
1282
- * CSS string-escape a file-derived value (e.g. an `@font-face` family name or an
1283
- * inline style value). Emits `\<hex> ` escapes for quotes, backslash, and
1284
- * controls so the value cannot break out of its CSS string.
1111
+ * Every paragraph of one story, in reading order.
1112
+ *
1113
+ * Descends through tables (rows, cells, nested tables), block controls and block custom XML.
1114
+ * The returned nodes are paragraph elements; a caller addresses them by `id`.
1285
1115
  */
1286
- declare function escapeCssString(value: string): string;
1287
- /** Whether a file-derived CSS fragment contains a `url()` or `@import` (must be rejected). */
1288
- declare function containsCssFetch(value: string): boolean;
1116
+ declare function storyParagraphs(root: OoxmlNode): readonly OoxmlNode[];
1289
1117
  /**
1290
- * Content that must never execute or auto-resolve: OLE objects, macros, DDE and `INCLUDE*` field
1291
- * instructions.
1118
+ * The block walk itself, appending into `out`.
1292
1119
  *
1293
- * Rendered INERT by default rather than stripped — removing it would be a lossless-preservation
1294
- * failure, so it is carried and never acted on.
1120
+ * Exported so `allParagraphs` in the binding lane is the same traversal rather than a second
1121
+ * copy of it.
1295
1122
  */
1296
- declare const INERT_EXECUTABLE_KINDS: readonly ['field-dde', 'field-include', 'macro', 'activex', 'ole', 'embedded-object', 'executable-relationship'];
1297
- /** One of {@link INERT_EXECUTABLE_KINDS}. */
1298
- /** One of {@link INERT_EXECUTABLE_KINDS} — content carried but never executed. */
1299
- type InertExecutableKind = (typeof INERT_EXECUTABLE_KINDS)[number];
1300
- /** Whether a content kind is one this engine refuses to execute or auto-resolve. */
1301
- declare function isInertExecutable(kind: string): boolean;
1302
- /** Whether a field instruction's leading keyword is safe to evaluate. */
1303
- declare function isEvaluableField(instruction: string): boolean;
1304
- /** One item a scrub pass considers: its kind, and where in the package it sits. */
1305
- interface ContentItem {
1306
- readonly id: string;
1307
- readonly kind: string;
1123
+ declare function collectStoryParagraphs(children: readonly OoxmlNode[], out: OoxmlNode[], sdtDepth: number): void;
1124
+
1125
+ /** One searchable text-box story and the drawing location that can reveal it. */
1126
+ interface TextboxStoryRoot {
1127
+ /** The `w:txbxContent` story root. */
1128
+ readonly root: OoxmlElement;
1129
+ /** Layout atom id used to select the drawing, including an MC wrapper when present. */
1130
+ readonly drawingNodeId: string;
1131
+ /** Canonical node id of the paragraph that anchors the drawing. */
1132
+ readonly hostParagraphId: string;
1308
1133
  }
1309
1134
  /**
1310
- * What an explicit scrub removed.
1135
+ * List the text-box stories in one part, in document order.
1311
1136
  *
1312
- * A scrub DECLARES ITSELF non-lossless: removing executable content changes the file, which is a
1313
- * choice a caller makes deliberately rather than a default the engine applies.
1137
+ * The bounded walk stops at drawings. It does not project pictures, shape geometry, or story
1138
+ * content. Results are memoized by immutable part-root identity.
1314
1139
  */
1315
- interface ScrubResult {
1316
- readonly kept: readonly ContentItem[];
1317
- readonly removed: readonly ContentItem[];
1318
- /** A scrub that removes anything is non-lossless by definition. */
1319
- readonly nonLossless: boolean;
1320
- }
1321
- /** Explicit scrub export: remove inert executable classes, report removals. */
1322
- declare function scrubExport(items: readonly ContentItem[]): ScrubResult;
1140
+ declare function textboxStoriesInPart(part: OoxmlPart): readonly TextboxStoryRoot[];
1323
1141
 
1324
- /** True for an `m:oMathPara` display equation. */
1325
- declare function isOmmlDisplay(node: OoxmlNode): node is OoxmlGenericElementNode;
1326
- /** True for a paragraph-level equation atom: `m:oMath` or `m:oMathPara`. */
1327
- declare function isOmmlEquationAtom(node: OoxmlNode): node is OoxmlGenericElementNode;
1328
- /** The `m:oMath` equations of a display, or the equation itself for an inline `m:oMath`. */
1329
- declare function equationsOfAtom(node: OoxmlNode): readonly OoxmlGenericElementNode[];
1142
+ /** Relationship from the story to one data part. */
1143
+ declare const CUSTOM_XML_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
1144
+ /** Relationship from a data part to the properties that carry its `ds:itemID`. */
1145
+ declare const CUSTOM_XML_PROPS_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps";
1146
+ /** `itemPropsN.xml` needs an Override; `itemN.xml` rides the package's `xml` default. */
1147
+ declare const CUSTOM_XML_PROPS_TYPE = "application/vnd.openxmlformats-officedocument.customXmlProperties+xml";
1148
+ /** The datastore namespace `ds:datastoreItem` lives in. */
1149
+ declare const DATASTORE_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/customXml";
1150
+ /** A data part located in a package: where it lives, and the GUID an SDT binds to. */
1151
+ interface CustomXmlDataPart {
1152
+ /** Canonical part name, e.g. `/customXml/item1.xml`. */
1153
+ readonly partName: string;
1154
+ /** Part name of its properties, e.g. `/customXml/itemProps1.xml`. */
1155
+ readonly propsPartName: string;
1156
+ /** `ds:itemID`, braced and upper-case, as `w:storeItemID` must spell it. */
1157
+ readonly itemId: string;
1158
+ /** Namespace URI of the payload root, which is what identifies one store among several. */
1159
+ readonly namespaceUri: string;
1160
+ }
1330
1161
  /**
1331
- * Project a display equation as one layout atom. A display with one equation keeps that
1332
- * equation's projection, so the painted atom names the editable `m:oMath`. Several equations
1333
- * share one row, separated by an em space.
1162
+ * A `ds:itemID` derived from the seed rather than drawn at random.
1163
+ *
1164
+ * Exported so a caller that authors a store OUTSIDE a package — a template engine splicing
1165
+ * markup it will assemble into a `.docx` later — mints the id the same way this does, rather
1166
+ * than inventing a second GUID shape Word has to be tolerant of.
1167
+ *
1168
+ * The store is a pure function of what it is asked to write: the same document written twice
1169
+ * has to produce the same bytes, or a save/reopen/save round trip stops being a fixed point
1170
+ * and every digest taken over saved bytes moves. A GUID's job here is uniqueness within one
1171
+ * package, not unguessability, so four FNV-1a passes over a salted seed carry it.
1334
1172
  */
1335
- declare function projectOmmlDisplay(node: OoxmlNode): OmmlEquationProjection | null;
1173
+ declare function datastoreItemIdFor(seed: string): string;
1336
1174
  /**
1337
- * The physical justification of a paragraph whose only visible content is display math.
1338
- * `m:oMathParaPr/m:jc` sets it; the default `centerGroup` centers the display. Returns null
1339
- * when the paragraph also holds text or other content, which keeps the paragraph `w:jc`.
1175
+ * The data parts a story relates to, in relationship order.
1176
+ *
1177
+ * Reads the relationships rather than scanning `/customXml/` by name: a part nothing relates
1178
+ * to is not part of the document, and a package from a hostile sender can hold as many
1179
+ * plausibly-named files as it likes.
1340
1180
  */
1341
- declare function displayMathAlignment(paragraph: {
1342
- readonly children: readonly OoxmlNode[];
1343
- }): 'left' | 'center' | 'right' | null;
1344
- /** Project a paragraph-level equation atom: inline `m:oMath` or display `m:oMathPara`. */
1345
- declare function projectOmmlAtom(node: OoxmlNode): OmmlEquationProjection | null;
1346
-
1347
- /** UTF-16 placeholder for a page break in paragraph text projections. */
1348
- declare const PAGE_BREAK_CHAR = "\f";
1349
- /** What a `w:br` breaks. `other` covers values this engine does not model, kept losslessly. */
1350
- type HardBreakKind = 'line' | 'page' | 'column' | 'other';
1351
- /** Read the semantic break kind from a typed `w:br` node. */
1352
- declare function hardBreakKind(node: OoxmlHardBreakNode): HardBreakKind;
1353
- /** Whether a node is a `w:br` with `w:type="page"`. */
1354
- declare function isPageBreakNode(node: OoxmlNode): node is OoxmlHardBreakNode;
1355
- /** Text projection for a `w:br` node — one UTF-16 code unit per break. */
1356
- declare function hardBreakText(node: OoxmlHardBreakNode): string;
1357
- /** Attributes for a newly authored `w:br`. */
1358
- declare function hardBreakAttributes(kind: 'line' | 'page'): OoxmlHardBreakNode['attributes'];
1359
-
1360
- /** Parsed TOC instruction. Unknown switches are ignored for generation but left on the wire. */
1361
- interface TocInstruction {
1362
- readonly keyword: 'TOC';
1363
- /** Include hyperlinks (`\\h`). */
1364
- readonly hyperlink: boolean;
1365
- /** Omit page numbers (`\\n`). */
1366
- readonly omitPageNumbers: boolean;
1367
- /** Inclusive 1-based outline levels from `\\o "n-m"`. Defaults 1–9. */
1368
- readonly outlineStart: number;
1369
- readonly outlineEnd: number;
1370
- readonly raw: string;
1181
+ declare function customXmlDataParts(pkg: OoxmlPackage, storyPartName: string): CustomXmlDataPart[];
1182
+ /** The data part carrying this namespace, or null when the document has none yet. */
1183
+ declare function findCustomXmlDataPart(pkg: OoxmlPackage, storyPartName: string, namespaceUri: string): CustomXmlDataPart | null;
1184
+ /** What {@link withCustomXmlDataPart} answers. */
1185
+ interface CustomXmlDataPartResult {
1186
+ readonly pkg: OoxmlPackage;
1187
+ /** Null when the part could not be authored; the package then comes back unchanged. */
1188
+ readonly part: CustomXmlDataPart | null;
1371
1189
  }
1372
- /** Longest TOC field instruction read. Instructions come from a file; the parse is bounded. */
1373
- declare const TOC_MAX_INSTRUCTION_CHARS = 256;
1374
- /** Most entries one generated table of contents may hold. */
1375
- declare const TOC_MAX_ENTRIES = 512;
1376
- /** Most bookmarks minted during one TOC refresh. */
1377
- declare const TOC_MAX_BOOKMARKS_PER_REFRESH = 512;
1378
- /** Deepest nested field instruction followed. Caps recursion on file-supplied structure. */
1379
- declare const TOC_MAX_FIELD_NESTING = 4;
1380
1190
  /**
1381
- * Most layout passes a TOC refresh runs before settling.
1191
+ * Ensure the document carries a data part for this namespace, creating it and everything it
1192
+ * needs — properties, both relationships, the properties content type — when it does not.
1382
1193
  *
1383
- * Page numbers change the TOC's own height, which changes page numbers — bounded so a
1384
- * non-converging document stops rather than looping.
1194
+ * Idempotent: a package that already has one for the namespace comes back untouched, so a
1195
+ * second node added to the same store does not author a second store.
1196
+ *
1197
+ * @param storyPartName - Whose relationships the store hangs off. Word enumerates its data
1198
+ * store from the MAIN DOCUMENT part, so a store authored off a header or footer is one Word
1199
+ * never sees.
1385
1200
  */
1386
- declare const TOC_MAX_PAGE_PASSES = 3;
1201
+ declare function withCustomXmlDataPart(pkg: OoxmlPackage, storyPartName: string, namespaceUri: string, rootLocalName: string): CustomXmlDataPartResult;
1387
1202
  /**
1388
- * Parse a TOC field instruction string.
1203
+ * Remove a store from a document: both parts, both relationships, the Override.
1389
1204
  *
1390
- * Returns null when the leading keyword is not TOC, the string is over-long, or the
1391
- * outline range is hostile. Does not evaluate or fetch anything.
1205
+ * PACKAGE ONLY. It does not touch the body, so a `w:sdt` bound to the store keeps its
1206
+ * `w:dataBinding`, its `w:storeItemID` and its `w:tag`, and Word then opens a control bound to
1207
+ * a store that is not there. Stripping those is the export path's job and is not built; this
1208
+ * is the half that removes the payload, which is the half a caller can rely on.
1209
+ *
1210
+ * `ok: false` means nothing was removed and the package is unchanged — most often because an
1211
+ * owner's `.rels` was never parsed into a tree, which {@link withoutPart} refuses to work
1212
+ * around. A caller exporting a document has to treat that as a failure to export rather than
1213
+ * as a document with nothing to strip, or it ships the payload it meant to remove.
1392
1214
  */
1393
- declare function parseTocInstruction(raw: string): TocInstruction | null;
1215
+ declare function withoutCustomXmlDataPart(pkg: OoxmlPackage, storyPartName: string, namespaceUri: string): WithoutPartResult;
1394
1216
 
1395
- /** A table of contents found in a document, whether wrapped in an SDT or a bare field. */
1396
- interface DetectedToc {
1397
- /** Enclosing control id when it identifies one TOC, otherwise the begin fldChar id. */
1217
+ /** One node in a store: its id, the bound text, and the payload beside it. */
1218
+ interface CustomXmlNode {
1398
1219
  readonly id: string;
1399
- readonly beginNodeId: string;
1400
- readonly beginParagraphId: string;
1401
- readonly endParagraphId: string;
1402
- readonly resultParagraphIds: readonly string[];
1403
- /** Direct parent whose paragraph children delimit the cached result. */
1404
- readonly containerId: string;
1405
- readonly contentControlId?: string;
1406
- readonly instruction: TocInstruction;
1407
- }
1408
- /** Discover refreshable body TOCs without evaluating any field instruction. */
1409
- declare function detectBodyTocs(part: OoxmlPart): readonly DetectedToc[];
1410
- /** Locate the table of contents containing a position, or null. */
1411
- declare function findDetectedToc(tocs: readonly DetectedToc[], tocId: string): DetectedToc | null;
1412
-
1413
- /** One heading symbol: its `w:font` and `w:char`, as the file wrote them. */
1414
- interface TocSymbol {
1415
- readonly font: string | null;
1416
- readonly char: string;
1220
+ /** Text a `w:dataBinding` resolves to. Untrusted file input. */
1221
+ readonly label: string;
1222
+ /** Payload as authored, JSON by convention and unparsed here. Untrusted file input. */
1223
+ readonly data: string;
1417
1224
  }
1418
-
1419
- declare const TWIPS: unique symbol;
1420
- declare const POINTS: unique symbol;
1225
+ /** Every node a store holds, in document order. */
1226
+ declare function customXmlNodes(pkg: OoxmlPackage, partName: string): CustomXmlNode[];
1227
+ /** One node by id, or null. */
1228
+ declare function readCustomXmlNode(pkg: OoxmlPackage, partName: string, nodeId: string): CustomXmlNode | null;
1229
+ /**
1230
+ * Write a node, replacing one that already has the id.
1231
+ *
1232
+ * Replace rather than append: a second node with the same id makes the binding xpath ambiguous,
1233
+ * and Word resolves an ambiguous xpath to the first match — so an "update" that appended would
1234
+ * leave the control showing its old text forever.
1235
+ */
1236
+ declare function withCustomXmlNode(pkg: OoxmlPackage, partName: string, node: CustomXmlNode): OoxmlPackage;
1237
+ /** Drop one node by id. A store that never held it comes back unchanged. */
1238
+ declare function withoutCustomXmlNode(pkg: OoxmlPackage, partName: string, nodeId: string): OoxmlPackage;
1239
+ /**
1240
+ * Drop every node no longer referenced, given the ids the document still binds.
1241
+ *
1242
+ * This is the whole deletion story. Deleting a control in THIS editor can remove its node
1243
+ * directly, but a control deleted in Word leaves the node behind — Word has no lifecycle link
1244
+ * between the two and no way to run our code. Reconciling against what the story actually binds
1245
+ * collects both, and is the only thing that can collect the second.
1246
+ *
1247
+ * Takes the referenced ids rather than reading the story itself: the caller already walked it,
1248
+ * and a sweep that guessed at which controls exist would delete a payload on a mistake.
1249
+ */
1250
+ declare function withoutOrphanCustomXmlNodes(pkg: OoxmlPackage, partName: string, referencedIds: ReadonlySet<string>): {
1251
+ readonly pkg: OoxmlPackage;
1252
+ readonly removed: readonly string[];
1253
+ };
1421
1254
  /**
1422
- * A length in twentieths of a point — OOXML's `ST_TwipsMeasure` / `ST_SignedTwipsMeasure`.
1423
- *
1424
- * The brand is intersection-typed onto `number`, so a `Twips` value still decays to `number`
1425
- * wherever arithmetic consumes it; only the reverse direction — passing a raw number where
1426
- * `Twips` is declared — is refused.
1255
+ * The `w:xpath` a binding uses to reach a node's label, or null when the id cannot be addressed.
1427
1256
  *
1428
- * @public
1257
+ * Word needs a prefix for the payload namespace even when the store declares it as a default —
1258
+ * an unprefixed step in an XPath means "no namespace", so `/docxEditor/node` would match
1259
+ * nothing in a namespaced store. The prefix is declared in `w:prefixMappings` beside it.
1429
1260
  */
1430
- type Twips = number & {
1431
- readonly [TWIPS]: true;
1432
- };
1261
+ declare function customXmlLabelXPath(prefix: string, rootLocalName: string, nodeId: string): string | null;
1262
+ /** The `w:prefixMappings` value declaring that prefix, or null when it cannot be written.
1263
+ * The namespace sits inside single quotes inside a double-quoted attribute, so a namespace
1264
+ * carrying either quote character has no representation here. */
1265
+ declare function customXmlPrefixMappings(prefix: string, namespaceUri: string): string | null;
1266
+
1267
+ /** The prefix every binding this library authors declares and quotes. */
1268
+ declare const CUSTOM_NODE_XPATH_PREFIX = "ns0";
1269
+ /** The three attributes a `w:dataBinding` carries. */
1270
+ interface CustomNodeBinding {
1271
+ readonly prefixMappings: string;
1272
+ readonly xpath: string;
1273
+ readonly storeItemId: string;
1274
+ }
1433
1275
  /**
1434
- * A length in typographic points, the unit layout and paint compute in.
1276
+ * The binding for one node in one store, or null when the id cannot be addressed by an XPath.
1435
1277
  *
1436
- * @public
1278
+ * Refuses rather than escapes: XPath 1.0 has no escape for a quote inside a literal, so an id
1279
+ * carrying one could close the predicate and append an expression of the sender's choosing.
1280
+ * The ids are minted by a host, so refusing is honest — see `ADDRESSABLE_ID`.
1437
1281
  */
1438
- type Points = number & {
1439
- readonly [POINTS]: true;
1440
- };
1282
+ declare function customNodeBinding(part: CustomXmlDataPart, rootLocalName: string, nodeId: string): CustomNodeBinding | null;
1441
1283
  /**
1442
- * Twentieths of a point per point.
1284
+ * Every node id the story's controls bind to in one store, in document order.
1443
1285
  *
1444
- * @public
1286
+ * This is the input the orphan sweep takes: a node whose id is not in here is one no control
1287
+ * names, whether it was deleted in this editor or in Word. Reading it from the STORY rather than
1288
+ * from a host's bookkeeping is what makes the two cases one mechanism.
1445
1289
  */
1446
- declare const TWIPS_PER_POINT = 20;
1290
+ declare function boundCustomXmlNodeIds(part: OoxmlPart, storeItemId: string): Set<string>;
1447
1291
  /**
1448
- * Assert that a number is a twips measurement.
1292
+ * Every node id ANY story in the package binds, in one store.
1449
1293
  *
1450
- * A compile-time cast, not a validator: bounds, integrality and finiteness stay at the parse
1451
- * boundary that produced the number, exactly where they are enforced today. The cast is the
1452
- * caller's claim about the UNIT, nothing more.
1294
+ * THE WHOLE PACKAGE, not one story. A payload is reachable from a header as easily as from the
1295
+ * body — Word enumerates its data store from the main part, but nothing stops a control
1296
+ * elsewhere quoting the same `w:storeItemID` — and the two callers that decide what is an orphan
1297
+ * both destroy data when they are wrong. The sweep would collect a payload a header still paints;
1298
+ * the export would strip a store a header still names, which is a document Word offers to repair.
1453
1299
  *
1454
- * @public
1300
+ * Costs one walk per story per store, on open and on export. Neither is a keystroke.
1455
1301
  */
1456
- declare const twips: (value: number) => Twips;
1302
+ declare function boundCustomXmlNodeIdsInPackage(pkg: OoxmlPackage, storeItemId: string): Set<string>;
1303
+ /** The node id one control binds to in the named store, or null when it binds to nothing there. */
1304
+ declare function boundCustomXmlNodeIdOf(control: OoxmlNode, storeItemId: string): string | null;
1305
+
1306
+ /** What happens to one control when the document is exported. */
1307
+ type CustomNodeExportPolicy = 'keep' | 'text' | 'remove';
1308
+ /** How {@link withExportedCustomNodes} decides, and which stores it may tidy afterwards. */
1309
+ interface CustomNodeExportRequest {
1310
+ /** The story whose controls are policed, and whose relationships the stores hang off. */
1311
+ readonly storyPartName: string;
1312
+ /**
1313
+ * Payload namespaces the caller CLAIMS.
1314
+ *
1315
+ * The store cleanup runs only over these. Word's own Cover Page Properties store rides in most
1316
+ * templates, and an export that tidied every customXml part would be deleting from documents it
1317
+ * was only asked to strip its own markup from.
1318
+ */
1319
+ readonly namespaces: readonly string[];
1320
+ /** The fate of a control carrying this `w:tag`. A control with no tag is never touched. */
1321
+ readonly decide: (tag: string) => CustomNodeExportPolicy;
1322
+ }
1457
1323
  /**
1458
- * Assert that a number is a points measurement. A compile-time cast; see {@link twips}.
1324
+ * The export, or the reason there is no export.
1459
1325
  *
1460
- * @public
1326
+ * A refusal answers no package on purpose. "Stripping failed, here is the document anyway" is the
1327
+ * one outcome that must not be possible: a caller would ship the markup it asked to remove and
1328
+ * have been told the export succeeded.
1461
1329
  */
1462
- declare const points: (value: number) => Points;
1330
+ type CustomNodeExportResult = {
1331
+ readonly ok: true;
1332
+ readonly pkg: OoxmlPackage;
1333
+ /** Controls unwrapped (`text`) and controls removed (`remove`). */
1334
+ readonly unwrapped: number;
1335
+ readonly removed: number;
1336
+ } | {
1337
+ readonly ok: false;
1338
+ readonly reason: string;
1339
+ };
1463
1340
  /**
1464
- * The one twips-to-points conversion. Exact division; twips are the finer unit.
1341
+ * Apply the policy, then take the payloads and the stores the policy orphaned.
1465
1342
  *
1466
- * @public
1343
+ * Order matters and is the reverse of the write's. The BODY goes first, so the sweep that follows
1344
+ * sees the controls that actually survive; the stores go last, once nothing binds them. Doing it
1345
+ * the other way would strip a store while a control still quoted its `w:storeItemID`, which is a
1346
+ * document Word opens and offers to repair.
1467
1347
  */
1468
- declare const twipsToPoints: (value: Twips) => Points;
1348
+ declare function withExportedCustomNodes(pkg: OoxmlPackage, request: CustomNodeExportRequest): CustomNodeExportResult;
1349
+
1469
1350
  /**
1470
- * The one points-to-twips conversion.
1471
- *
1472
- * Rounds to the nearest twip: every OOXML twips measurement is integral, and emitting a
1473
- * fractional twip would write a value no consumer of the file can represent.
1351
+ * Every kind of thing the registry gives a stable identity to.
1474
1352
  *
1475
- * @public
1353
+ * Identity is `(kind, id)` plus version and NEVER registration order, so two bundles contributing
1354
+ * the same command resolve deterministically regardless of which loaded first.
1476
1355
  */
1477
- declare const pointsToTwips: (value: Points) => Twips;
1356
+ declare const ID_KINDS: readonly ['extension', 'capability', 'command', 'query', 'schema', 'dependencyKey', 'runtimePort', 'result', 'origin'];
1357
+ /** One of {@link ID_KINDS}. */
1358
+ /** One of {@link ID_KINDS} — which sort of thing an identifier names. */
1359
+ type IdKind = (typeof ID_KINDS)[number];
1478
1360
  /**
1479
- * Read a twips attribute (`ST_TwipsMeasure`, `ST_SignedTwipsMeasure`, or a `dxa` table width)
1480
- * as a whole, signed number of twips, or `null` when the value is not a measurement.
1481
- *
1482
- * The schema allows an integer or a universal measure, but files also carry decimal twips
1483
- * (`4743.74`, `708.0`, `707.9999999999998`). The accepted forms read as follows:
1484
- *
1485
- * - A decimal truncates toward zero: `1443.74` is 1443 and `-720.6` is -720. A leading `+`,
1486
- * leading zeros, a bare fraction (`.5`) and a trailing point (`1440.`) are accepted.
1487
- * - A universal measure (`mm`, `cm`, `in`, `pt`, `pc`, `pi`) converts exactly and then
1488
- * truncates: `1.27cm` is 720 and `0.333in` is 479. Its sign is ignored, so `-0.5in` is 720.
1489
- * - Whitespace, exponents, hexadecimal, uppercase units, and an integer part longer than nine
1490
- * digits are not measurements.
1361
+ * Whether a string is a well-formed identifier in either accepted grammar.
1491
1362
  *
1492
- * The result is NOT bounded. Callers apply their own sign rule and range clamp, because each
1493
- * attribute has a different valid range and a different fallback.
1363
+ * Reverse-domain (`dev.docx-editor.core.command.insert-text`) or package-owned
1364
+ * (`@docx-editor.dev/engine-core#command/insert-text`). Ids are opaque once validated.
1365
+ */
1366
+ declare function isValidId(id: string): boolean;
1367
+ /**
1368
+ * Validate an identifier, throwing when it is malformed.
1494
1369
  *
1495
- * @internal
1370
+ * Throws rather than returning: a bad id is an author mistake at registration time, not file
1371
+ * input, and accepting it would produce a registry whose identities silently collide.
1496
1372
  */
1497
- declare function readTwipsMeasure(raw: string | undefined): number | null;
1498
-
1499
- /** Outline heading shape consumed by TOC planning (mirrors DocumentOutlineEntry). */
1500
- interface TocOutlineHeading {
1501
- readonly text: string;
1502
- readonly level: number;
1503
- readonly blockId: string;
1373
+ declare function assertValidId(id: string, kind?: IdKind): void;
1374
+ /** A validated (kind, id, version) triple — the registry's unit of identity. */
1375
+ interface CapabilityId {
1376
+ readonly kind: IdKind;
1377
+ readonly id: string;
1378
+ readonly version: string;
1504
1379
  }
1505
1380
 
1506
- /** Left-indent step between TOC levels, in twips (matches `scripts/demo-doc/toc-block.xml`). */
1507
- declare const TOC_LEVEL_INDENT_TWIPS: Twips;
1508
- /** Bounded left-indent twips for a TOC entry level (0-based heading depth). */
1509
- declare function tocLeftIndentTwips(level: number): Twips;
1510
- /** One planned TOC entry: its level, its text, and the heading it points at. */
1511
- interface TocEntryPlan {
1512
- readonly level: number;
1513
- readonly text: string;
1514
- readonly headingParagraphId: string;
1515
- readonly bookmarkName: string;
1516
- readonly pageNumberText: string;
1517
- /** The heading's symbols, one per {@link TOC_SYMBOL_MARK} in `text`, in order. */
1518
- readonly symbols?: readonly TocSymbol[];
1381
+ /** A parsed semantic version. Only the three numeric components — no pre-release or build. */
1382
+ interface SemVer {
1383
+ readonly major: number;
1384
+ readonly minor: number;
1385
+ readonly patch: number;
1519
1386
  }
1520
- /** Build one TOC entry paragraph node. */
1521
- declare function buildTocEntryParagraph(mint: () => string, entry: TocEntryPlan, instruction: TocInstruction, paragraphPropertiesTemplate?: OoxmlNode): OoxmlNode;
1522
- /** Build an SDT-wrapped complex TOC field with an already planned cached result. */
1523
- declare function buildTocContentControl(mint: () => string, entries: readonly TocEntryPlan[], instruction: TocInstruction, alias: string): OoxmlNode;
1524
1387
  /**
1525
- * Word flattens manual line/tab breaks from a heading into spaces in its TOC cache.
1526
- * Carrying them verbatim makes a short title wrap even when the row has ample room, and the
1527
- * same normalization is what lets a cached row be matched back to the heading it came from.
1388
+ * Parse a semantic version, rejecting anything the registry's rules do not need.
1389
+ *
1390
+ * Deliberately narrow: an unsupported range form is refused rather than accepted, so a malformed
1391
+ * range can never masquerade as "compatible".
1528
1392
  */
1529
- declare function tocEntryText(text: string): string;
1393
+ declare function parseSemVer(input: string): SemVer;
1394
+ /** Order two versions: negative, zero or positive, by major then minor then patch. */
1395
+ declare function compareSemVer(a: SemVer, b: SemVer): -1 | 0 | 1;
1530
1396
  /**
1531
- * Plan TOC entries from the outline and existing bookmarks.
1397
+ * Whether `version` satisfies `range`. Supported range grammar:
1398
+ * - `*` any version
1399
+ * - `1.2.3` exact
1400
+ * - `^1.2.3` caret: same major, and >= the floor (major 0 pins the minor)
1401
+ * - `>=1.2.3 <2.0.0` a single lower (inclusive) + upper (exclusive) bound pair
1402
+ * Any other shape throws — an unparseable range is a registration error, not a pass.
1403
+ */
1404
+ declare function satisfies(version: string, range: string): boolean;
1405
+
1406
+ /**
1407
+ * Why registry resolution failed.
1532
1408
  *
1533
- * `actorId` is explicit because this planner runs BEFORE the store transaction, so the
1534
- * ambient transaction actor is not bound. Callers that already have the collaboration
1535
- * identity pass it here. `resolveAllocationActor` still honours a
1536
- * `runWithTransactionActor` wrap when the caller prefers that seam.
1409
+ * Every code names a declaration conflict a bundle author can fix — a missing dependency, an
1410
+ * unsatisfied version range, a duplicate contribution with no replacement policy.
1537
1411
  */
1538
- declare function planTocEntries(part: OoxmlPart, outline: readonly TocOutlineHeading[], instruction: TocInstruction, pageNumberByParagraphId: ReadonlyMap<string, string>, excludeParagraphIds: ReadonlySet<string>, actorId?: string): {
1539
- readonly entries: readonly TocEntryPlan[];
1540
- readonly bookmarksToCreate: readonly {
1541
- paragraphId: string;
1542
- name: string;
1543
- }[];
1544
- };
1545
- /** Create bookmarkStart/End pair nodes for insertion at the start of a paragraph. */
1546
- declare function bookmarkPairNodes(mint: () => string, name: string, id: string): {
1547
- readonly start: OoxmlNode;
1548
- readonly end: OoxmlNode;
1412
+ type RegistryErrorCode = 'invalid-id' | 'invalid-version' | 'duplicate-extension' | 'id-collision' | 'replacement-target-missing' | 'unauthorized-replacement' | 'replacement-version-mismatch' | 'ambiguous-replacement' | 'missing-dependency' | 'dependency-cycle' | 'conflict' | 'missing-port';
1413
+ /**
1414
+ * A resolution failure naming every responsible party.
1415
+ *
1416
+ * Thrown rather than returned: an unresolvable registry is a build-time composition mistake, and
1417
+ * an engine running with a half-resolved registry would fail later in ways that do not point back
1418
+ * to the bundle that caused it.
1419
+ */
1420
+ declare class RegistryError extends Error {
1421
+ readonly code: RegistryErrorCode;
1422
+ /** Stable identities responsible for the failure (extensions, ids). */
1423
+ readonly responsible: readonly string[];
1424
+ constructor(code: RegistryErrorCode, message: string,
1425
+ /** Stable identities responsible for the failure (extensions, ids). */
1426
+ responsible?: readonly string[]);
1427
+ }
1428
+ /** How a base contribution permits replacement by other bundles. */
1429
+ type ReplacementPolicy = {
1430
+ readonly kind: 'none';
1431
+ } | {
1432
+ readonly kind: 'single';
1433
+ } | {
1434
+ readonly kind: 'priority';
1549
1435
  };
1550
-
1436
+ /** One thing a bundle contributes: a command, a query, a schema, a port, keyed by `(kind, id)`. */
1437
+ interface Contribution {
1438
+ readonly kind: Exclude<IdKind, 'extension' | 'origin' | 'result'>;
1439
+ readonly id: string;
1440
+ readonly version: string;
1441
+ /** If set, this contribution replaces an existing base contribution. */
1442
+ readonly replaces?: {
1443
+ readonly targetId: string;
1444
+ readonly targetRange: string;
1445
+ readonly priority?: number;
1446
+ };
1447
+ /** Policy this contribution exposes to would-be replacers (default `none`). */
1448
+ readonly replaceable?: ReplacementPolicy;
1449
+ readonly payload?: unknown;
1450
+ }
1551
1451
  /**
1552
- * The heading each cached result row stands for, aligned with `toc.resultParagraphIds`.
1452
+ * A unit of engine functionality: its identity, version, dependencies, conflicts, required ports,
1453
+ * and contributions.
1553
1454
  *
1554
- * `null` for a row that names no heading this document still has — a stale row, or the
1555
- * chrome/blank paragraphs a cached result can carry. Callers leave those alone rather than
1556
- * writing another row's number into them.
1455
+ * The registry's whole input. Everything a bundle needs and everything it offers is DECLARED, so
1456
+ * resolution can be deterministic and order-independent.
1557
1457
  */
1558
- declare function resolveTocRowHeadings(part: OoxmlPart, toc: DetectedToc, outline: readonly TocOutlineHeading[], excludeParagraphIds: ReadonlySet<string>): readonly (string | null)[];
1559
-
1560
- /** One paragraph in the index: its node id, its story, and its position. */
1561
- interface ParagraphIndexEntry {
1562
- /** Canonical tree node id — the stable identity operations address. */
1563
- readonly nodeId: string;
1564
- /** Position among the story's paragraphs, in document order. */
1565
- readonly ordinal: number;
1566
- /** Concatenated text content, with tabs and breaks mapped as the model reads them. */
1567
- readonly text: string;
1568
- /** Node ids of the paragraph's runs, in order. */
1569
- readonly runIds: readonly string[];
1458
+ interface FeatureBundle {
1459
+ readonly id: string;
1460
+ readonly version: string;
1461
+ readonly dependencies?: readonly string[];
1462
+ readonly conflicts?: readonly string[];
1463
+ readonly requiredPorts?: readonly string[];
1464
+ readonly contributions: readonly Contribution[];
1570
1465
  }
1571
- /** One story root — body, a header/footer variant, or a note part. */
1572
- interface StoryIndexEntry {
1573
- /** The part the story lives in. */
1574
- readonly partName: string;
1575
- /** The `w:body` (or story root) node id. */
1576
- readonly rootId: string;
1577
- readonly paragraphs: readonly ParagraphIndexEntry[];
1466
+ /** The resolved result: every contribution selected, indexed by `(kind, id)`. */
1467
+ interface ResolvedRegistry {
1468
+ readonly extensions: ReadonlyMap<string, FeatureBundle>;
1469
+ readonly contributions: ReadonlyMap<string, Contribution>;
1470
+ get(kind: Contribution['kind'], id: string): Contribution | undefined;
1578
1471
  }
1579
- /** One style definition, indexed by the id content references it under. */
1580
- interface StyleIndexEntry {
1581
- readonly styleId: string;
1582
- readonly type: string;
1583
- readonly nodeId: string;
1584
- readonly name: string | null;
1585
- readonly basedOn: string | null;
1586
- /** Whether the part marks this the default style for its type (`w:default="1"`). */
1587
- readonly isDefault: boolean;
1472
+ /** How resolution treats optional bundles and replacement policies. */
1473
+ interface ResolveOptions {
1474
+ /** Runtime port ids available in this environment (design D9 / task 0.3). */
1475
+ readonly availablePorts?: readonly string[];
1588
1476
  }
1589
1477
  /**
1590
- * The derived lookups over a part: paragraphs, stories and styles by id.
1478
+ * Resolve a set of bundles into one registry, or throw.
1591
1479
  *
1592
- * Diff-patched on commit rather than rebuilt — rebuilding every index per keystroke is what made
1593
- * typing scale with document length.
1480
+ * Deterministic and registration-order independent: selection is by `(kind, id)` plus version,
1481
+ * and ties break only on declared policy. Array order never decides anything.
1482
+ *
1483
+ * @throws RegistryError naming every bundle responsible for the failure.
1594
1484
  */
1595
- interface OoxmlIndexes {
1596
- /** The tree revision these projections were derived from. */
1597
- readonly revision: number;
1598
- /** Body story first, then any other story parts, keyed by part name. */
1599
- readonly stories: ReadonlyMap<string, StoryIndexEntry>;
1600
- /** Every paragraph across every story, keyed by node id. */
1601
- readonly paragraphs: ReadonlyMap<string, ParagraphIndexEntry>;
1602
- readonly relationships: ReadonlyMap<string, readonly RelationshipRecord[]>;
1603
- readonly styles: ReadonlyMap<string, StyleIndexEntry>;
1604
- }
1605
- /** Style definitions, read out of the generic `w:styles` tree. */
1606
- declare function indexStyles(part: OoxmlPart | undefined): Map<string, StyleIndexEntry>;
1607
- /** The package's style definitions part, if it has one. */
1608
- declare function stylesPartOf(pkg: OoxmlPackage): OoxmlPart | undefined;
1485
+ declare function resolve(bundles: readonly FeatureBundle[], options?: ResolveOptions): ResolvedRegistry;
1486
+
1609
1487
  /**
1610
- * Derive every index from one canonical package revision.
1611
- *
1612
- * Pure: the same package and revision always produce the same index, which is what makes
1613
- * "rebuild rather than mutate" a safe invalidation strategy.
1488
+ * Typed-origin domains (design D5 / ADR-S5). `mutation.*` are the canonical
1489
+ * write origins; `projection` and `awareness` MUST NOT enter history, audit,
1490
+ * snapshots, or replication.
1614
1491
  */
1615
- declare function deriveOoxmlIndexes(pkg: OoxmlPackage, revision: number): OoxmlIndexes;
1492
+ declare const ORIGIN_IDS: {
1493
+ readonly mutationHuman: "dev.docx-editor.core.origin.mutation.human";
1494
+ readonly mutationAgent: "dev.docx-editor.core.origin.mutation.agent";
1495
+ readonly mutationRemote: "dev.docx-editor.core.origin.mutation.remote";
1496
+ readonly mutationUndo: "dev.docx-editor.core.origin.mutation.undo";
1497
+ readonly mutationRedo: "dev.docx-editor.core.origin.mutation.redo";
1498
+ readonly mutationMigration: "dev.docx-editor.core.origin.mutation.migration";
1499
+ readonly mutationRepair: "dev.docx-editor.core.origin.mutation.repair";
1500
+ readonly mutationServer: "dev.docx-editor.core.origin.mutation.server";
1501
+ readonly projection: "dev.docx-editor.core.origin.projection";
1502
+ readonly awareness: "dev.docx-editor.core.origin.awareness";
1503
+ };
1504
+ /** Canonical writes carry a mutation origin; these are the undoable-eligibility inputs. */
1505
+ declare const CANONICAL_MUTATION_ORIGINS: readonly string[];
1506
+ /** Origins that never enter authored state / history / audit / snapshot / replication. */
1507
+ declare const NON_CANONICAL_ORIGINS: readonly string[];
1508
+ /**
1509
+ * Result taxonomy (design D8 / task 7.8). A transport/protocol failure that
1510
+ * prevents a valid envelope is a typed exception, not a member here.
1511
+ */
1512
+ declare const RESULT_IDS: {
1513
+ readonly applied: "dev.docx-editor.core.result.applied";
1514
+ readonly validation: "dev.docx-editor.core.result.validation";
1515
+ readonly conflict: "dev.docx-editor.core.result.conflict";
1516
+ readonly resource: "dev.docx-editor.core.result.resource";
1517
+ readonly authorization: "dev.docx-editor.core.result.authorization";
1518
+ readonly aborted: "dev.docx-editor.core.result.aborted";
1519
+ };
1520
+ /** Runtime ports (extensions-and-runtime-ports spec; design D9). */
1521
+ declare const RUNTIME_PORT_IDS: {
1522
+ readonly fonts: "dev.docx-editor.core.port.fonts";
1523
+ readonly shaping: "dev.docx-editor.core.port.shaping";
1524
+ readonly images: "dev.docx-editor.core.port.images";
1525
+ readonly clock: "dev.docx-editor.core.port.clock";
1526
+ readonly identity: "dev.docx-editor.core.port.identity";
1527
+ readonly persistence: "dev.docx-editor.core.port.persistence";
1528
+ readonly transport: "dev.docx-editor.core.port.transport";
1529
+ readonly scheduling: "dev.docx-editor.core.port.scheduling";
1530
+ readonly audit: "dev.docx-editor.core.port.audit";
1531
+ readonly authorization: "dev.docx-editor.core.port.authorization";
1532
+ readonly resourceAccounting: "dev.docx-editor.core.port.resource-accounting";
1533
+ readonly cancellation: "dev.docx-editor.core.port.cancellation";
1534
+ readonly externalResourceConsent: "dev.docx-editor.core.port.external-resource-consent";
1535
+ };
1536
+ /** Layout dependency keys (design D6 / task 8.2). */
1537
+ declare const DEPENDENCY_KEY_IDS: {
1538
+ readonly style: "dev.docx-editor.core.dep.style";
1539
+ readonly numbering: "dev.docx-editor.core.dep.numbering";
1540
+ readonly section: "dev.docx-editor.core.dep.section";
1541
+ readonly story: "dev.docx-editor.core.dep.story";
1542
+ readonly font: "dev.docx-editor.core.dep.font";
1543
+ readonly image: "dev.docx-editor.core.dep.image";
1544
+ readonly table: "dev.docx-editor.core.dep.table";
1545
+ readonly field: "dev.docx-editor.core.dep.field";
1546
+ readonly note: "dev.docx-editor.core.dep.note";
1547
+ readonly headerFooter: "dev.docx-editor.core.dep.header-footer";
1548
+ readonly annotation: "dev.docx-editor.core.dep.annotation";
1549
+ };
1550
+ /** Every frozen id as a flat list, for the immutability / uniqueness gate. */
1551
+ declare const ALL_FROZEN_IDS: readonly string[];
1616
1552
 
1617
- /** One paragraph's meaning, independent of how it was spelled in XML. */
1618
- interface ParagraphDigest {
1619
- /** Ordinal identity within its story. Node ids are NOT used: a reopened package
1620
- * legitimately re-derives them, and requiring them to match would test the id scheme
1621
- * rather than the content. */
1622
- readonly ordinal: number;
1623
- /**
1624
- * Where the paragraph SITS: the element path from the story root, so a paragraph that
1625
- * moves out of the table cell it was written in is a difference rather than a paragraph
1626
- * with the same ordinal and the same text.
1627
- */
1628
- readonly path: string;
1629
- /**
1630
- * `w14:paraId`, uppercase-normalized (matching is case-insensitive), or null. This is
1631
- * MANAGED identity — the agent contract anchors on it and comment threading references
1632
- * it — so a serializer silently dropping it must be a digest difference. Other paragraph
1633
- * attributes (`w:rsidR` …) stay deliberately undigested: they are revision noise.
1634
- */
1635
- readonly paraId: string | null;
1636
- /** Text content, including tabs and hard breaks as their characters. */
1637
- readonly text: string;
1638
- /** Accepted paragraph properties, as sorted tokens including nested children. */
1639
- readonly paragraphProperties: readonly string[];
1640
- /** Per-run accepted properties, in run order. */
1641
- readonly runProperties: readonly (readonly string[])[];
1642
- /** Fingerprints of every generic (unknown) subtree, in document order. */
1643
- readonly genericStructure: readonly string[];
1644
- }
1645
- /** One story reduced to its semantic content, ignoring everything a normalized re-emit changes. */
1646
- interface StoryDigest {
1647
- readonly partName: string;
1648
- readonly paragraphs: readonly ParagraphDigest[];
1649
- /**
1650
- * Every block-level element of the part OUTSIDE a paragraph, in document order, as
1651
- * `path name(attributes)` — the tables, rows, cells, sections, content controls and
1652
- * their property children, each at the position that says what contains it.
1653
- *
1654
- * A paragraph's own internals are not here (they are its `ParagraphDigest`), which keeps
1655
- * this list proportional to a document's STRUCTURE rather than its text.
1656
- */
1657
- readonly structure: readonly string[];
1658
- }
1659
1553
  /**
1660
- * The whole document's semantic content — one of the D9 losslessness oracles.
1554
+ * A counter's limit was reached. Carries the label, the limit, and what was attempted.
1661
1555
  *
1662
- * What a save/reopen round-trip is compared on. Byte identity applies only to non-XML parts;
1663
- * modelled parts re-emit normalized, so equality is asserted HERE rather than on bytes.
1556
+ * Thrown at the N → N+1 boundary, so the increment that would have crossed the limit never
1557
+ * happens rather than being detected afterwards.
1664
1558
  */
1665
- interface SemanticDigest {
1666
- readonly stories: readonly StoryDigest[];
1559
+ declare class LimitExceededError extends Error {
1560
+ readonly label: string;
1561
+ readonly limit: number;
1562
+ readonly attempted: number;
1563
+ constructor(label: string, limit: number, attempted: number);
1667
1564
  }
1668
- /** Where two digests diverge — the diagnostic when a round-trip loses something. */
1669
- type DigestDifference = {
1670
- readonly path: string;
1671
- readonly before: string;
1672
- readonly after: string;
1673
- };
1674
- /** Digest one part: its paragraphs, and the structure that holds them. */
1675
- declare function digestPart(part: OoxmlPart): StoryDigest | null;
1676
- /** Digest every part, in the given order. */
1677
- declare function semanticDigest(parts: Iterable<OoxmlPart>): SemanticDigest;
1678
1565
  /**
1679
- * Every way two digests differ, as readable paths.
1566
+ * Overflow-safe counting against a fixed limit.
1680
1567
  *
1681
- * Returns the differences rather than a boolean because "the round trip lost something" is
1682
- * useless without saying what — the failure this oracle exists to catch is a silent drop,
1683
- * and a bare `false` reproduces the silence.
1568
+ * Never silently wraps: it rejects the increment that would cross its limit AND any arithmetic
1569
+ * that would exceed `Number.MAX_SAFE_INTEGER`. That second guard is the point — a file-supplied
1570
+ * count must never be trusted into an allocation, and a wrapped counter reads as small.
1684
1571
  */
1685
- declare function diffSemanticDigests(before: SemanticDigest, after: SemanticDigest): DigestDifference[];
1572
+ declare class BoundedCounter {
1573
+ readonly label: string;
1574
+ readonly limit: number;
1575
+ private value;
1576
+ constructor(label: string, limit: number);
1577
+ get current(): number;
1578
+ /** Remaining headroom before the limit. */
1579
+ get remaining(): number;
1580
+ /**
1581
+ * Add `n` (default 1). Throws LimitExceededError if the result would exceed the
1582
+ * limit (so `limit` itself is reachable but `limit + 1` is not) or overflow the
1583
+ * safe-integer range. On rejection the counter is unchanged.
1584
+ */
1585
+ add(n?: number): number;
1586
+ /** Whether adding `n` would be accepted, without mutating. */
1587
+ canAdd(n?: number): boolean;
1588
+ release(n: number): void;
1589
+ }
1686
1590
 
1687
- /** Valid per MS-DOCX: 8 hex digits, non-zero, below 0x80000000. */
1688
- declare function isValidParaId(value: string): boolean;
1689
- /** The authored `w14:paraId` value of an element, verbatim, or null. */
1690
- declare function paraIdOf(node: OoxmlNode): string | null;
1691
- /** FNV-1a over UTF-16 code units — the deterministic mint every id derivation shares. */
1692
- declare function fnv1a32(value: string): number;
1693
- /**
1694
- * Deterministic 8-hex mint in (0x00000000, 0x80000000), collision-free against
1695
- * `used` (uppercase hex). Same seed + same used-set → same value, which is what
1696
- * keeps `splitParagraphMany` byte-identical to its equivalent single splits and
1697
- * a reopened save identical to the session that produced it.
1698
- */
1699
- declare function mintParaId(seed: string, used: ReadonlySet<string>): string;
1700
- /** Every valid `w14:paraId` in the tree, uppercased. Memoized per root object. */
1701
- declare function usedParaIds(root: OoxmlElement): ReadonlySet<string>;
1591
+ /** A budget was misused: over-carved, over-reserved, or disposed with children outstanding. */
1592
+ declare class BudgetError extends Error {
1593
+ constructor(message: string);
1594
+ }
1702
1595
  /**
1703
- * The non-empty prefix the part ROOT binds to the w14 namespace, or null.
1596
+ * Capacity claimed BEFORE it is allocated.
1704
1597
  *
1705
- * Minted attributes require an in-scope binding (the invariant validator reports
1706
- * `invalid-qname` otherwise, and the serializer would allocate an `nsN` alias).
1707
- * Only the root binding counts: a binding authored on some descendant does not
1708
- * cover paragraphs elsewhere in the tree.
1598
+ * Reserve-then-allocate rather than allocate-then-check: discovering the overrun after the
1599
+ * allocation has already happened defeats the point of having a budget.
1709
1600
  */
1710
- declare function w14RootPrefix(root: OoxmlElement): string | null;
1711
- /** The minted `[w14:paraId, w14:textId]` pair. `textId` mirrors `paraId`: it has no uniqueness requirement, no consumer reads it, and one allocator is simpler than two — but Word writes both, so we write both. */
1712
- declare function mintedParagraphIdentityAttributes(prefix: string, value: string): readonly OoxmlAttribute[];
1601
+ interface Reservation {
1602
+ readonly amount: number;
1603
+ readonly released: boolean;
1604
+ release(): void;
1605
+ }
1713
1606
  /**
1714
- * Load-time paragraph-identity normalization for a session's main part.
1715
- *
1716
- * Keeps every valid, first-seen paraId verbatim; mints (deterministically, seeded
1717
- * by the paragraph's structural node id) for paragraphs whose id is missing,
1718
- * malformed, zero, out of range, or a duplicate. Adds the root `xmlns` binding
1719
- * the minted attributes need. Returns the INPUT PART REFERENCE when there is
1720
- * nothing to do — a document Word saved yesterday re-serializes byte-identical.
1607
+ * One node in the hierarchical resource budget tree.
1721
1608
  *
1722
- * Attribute-only rebuilds move no child, so every node keeps its structural-path
1723
- * id; the copy respreads only the ancestors of changed paragraphs.
1609
+ * An operation owns a root budget; parsers, extensions, workers, layout, transport and output
1610
+ * carve children from it, so no subsystem can consume more than the operation as a whole allows.
1724
1611
  *
1725
- * Fail-open: if the rebuilt part does not validate (a bug, or a pathology the
1726
- * prefix choice could not defuse), the original part is returned — a document
1727
- * must never become unopenable over an identity enhancement.
1612
+ * `dispose()` REFUSES while children or reservations are outstanding, then runs registered
1613
+ * cleanups LIFO — spill files, worker termination — even if one throws. A leaked child budget is a
1614
+ * leaked worker, so the refusal is the diagnostic.
1728
1615
  */
1729
- declare function normalizeParagraphIdentity(part: OoxmlPart): OoxmlPart;
1730
-
1731
- /** One `w:docPart` of the glossary, with the blocks its body holds. */
1732
- interface BuildingBlock {
1733
- /** `w:docPartPr/w:name`, the identity a control's placeholder and a pick refer to. */
1734
- readonly name: string;
1735
- /** `w:category/w:gallery`, an `ST_DocPartGallery` value such as `docParts`. */
1736
- readonly gallery: string;
1737
- /** `w:category/w:name`; `General` when the block declares none. */
1738
- readonly category: string;
1739
- /** The `w:docPartBody` children: paragraphs, tables and block controls, in order. */
1740
- readonly blocks: readonly OoxmlNode[];
1616
+ declare class Budget {
1617
+ readonly label: string;
1618
+ readonly capacity: number;
1619
+ private readonly used;
1620
+ private readonly children;
1621
+ private activeReservations;
1622
+ private readonly cleanups;
1623
+ private disposed;
1624
+ private carveAmount;
1625
+ private parent?;
1626
+ constructor(label: string, capacity: number);
1627
+ get inUse(): number;
1628
+ get available(): number;
1629
+ get isDisposed(): boolean;
1630
+ /** Reserve `amount` from this budget. Throws if it would exceed capacity. */
1631
+ reserve(amount: number): Reservation;
1632
+ /** Carve a child budget of `capacity` out of this budget's headroom. */
1633
+ child(label: string, capacity: number): Budget;
1634
+ /** Register cleanup for a spill file, worker, or queue tied to this budget. */
1635
+ onRelease(cleanup: () => void): void;
1636
+ /**
1637
+ * Release this budget. Refuses while any child budget or reservation is
1638
+ * outstanding (children must finish first). Runs cleanups LIFO, returns the
1639
+ * carve-out to the parent, and marks disposed. Cleanup errors are collected and
1640
+ * rethrown after every cleanup has run.
1641
+ */
1642
+ dispose(): void;
1643
+ private assertLive;
1741
1644
  }
1742
- /** The gallery and category a `w:docPartList` control lists. */
1743
- interface BuildingBlockGalleryFilter {
1744
- readonly gallery: string;
1745
- readonly category: string | null;
1645
+
1646
+ /**
1647
+ * Which side of the point of no return an operation is on.
1648
+ *
1649
+ * Canonical publication is that point. Cancelling BEFORE it rolls the whole operation back;
1650
+ * cancelling after it leaves the commit standing and cancels only derived work — layout, export,
1651
+ * caches.
1652
+ */
1653
+ type CancellationPhase = 'pre-publication' | 'post-publication';
1654
+ /** Thrown from a `checkpoint()` when the operation has been cancelled. */
1655
+ declare class CancellationError extends Error {
1656
+ /** True when the commit is already published and only derived work is cancelled. */
1657
+ readonly derivedOnly: boolean;
1658
+ constructor(
1659
+ /** True when the commit is already published and only derived work is cancelled. */
1660
+ derivedOnly: boolean, reason?: string);
1746
1661
  }
1747
- /** The glossary part, through the main part's relationship or the conventional name. */
1748
- declare function glossaryPartOf(pkg: OoxmlPackage): OoxmlPart | null;
1749
- /** Every named building block of the glossary, in authored order. Empty without a glossary. */
1750
- declare function buildingBlocksOf(pkg: OoxmlPackage): readonly BuildingBlock[];
1751
- /** The gallery a `w:docPartList` control lists, or null for any other control. */
1752
- declare function buildingBlockGalleryOf(control: OoxmlNode): BuildingBlockGalleryFilter | null;
1753
1662
  /**
1754
- * The blocks a gallery control offers: same gallery, and the control's category when it names
1755
- * one. Sorted by category, then name, as Word groups its list.
1663
+ * The read side of cancellation, handed to cooperative work.
1664
+ *
1665
+ * Cooperative rather than pre-emptive: long work calls `checkpoint()` at declared intervals, which
1666
+ * is what lets an operation unwind promptly without the engine having to interrupt it mid-mutation.
1756
1667
  */
1757
- declare function buildingBlocksForControl(pkg: OoxmlPackage, control: OoxmlNode): readonly BuildingBlock[];
1758
-
1668
+ interface CancellationToken {
1669
+ readonly isCancelled: boolean;
1670
+ readonly phase: CancellationPhase;
1671
+ /** True only when cancelled AND the commit is already published. */
1672
+ readonly derivedOnly: boolean;
1673
+ /** Throws CancellationError if cancelled; call at declared checkpoint intervals. */
1674
+ checkpoint(): void;
1675
+ }
1759
1676
  /**
1760
- * Which story a comment deletion or resolution may read markers from.
1677
+ * The write side of cancellation, and the owner of the phase.
1761
1678
  *
1762
- * `w:id` is not unique across stories: a header and the body can both hold comment 1.
1679
+ * Whoever starts an operation holds this; everything it calls gets only the token.
1763
1680
  */
1764
- interface CommentDeletionOwner {
1765
- /** Canonical name of the part holding the story's markers. */
1766
- readonly storyPartName: string;
1767
- /**
1768
- * When the story is one note inside a shared notes part, that note's `w:id`.
1769
- * Absent means the whole part is the story (body, header, footer).
1770
- */
1771
- readonly noteId?: number;
1681
+ declare class CancellationController {
1682
+ private _cancelled;
1683
+ private _phase;
1684
+ private _reason?;
1685
+ cancel(reason?: string): void;
1686
+ /** Mark canonical publication — the point of no return. */
1687
+ markPublished(): void;
1688
+ get isCancelled(): boolean;
1689
+ get phase(): CancellationPhase;
1690
+ get isPublished(): boolean;
1691
+ /** Cancelled after publication -> full rollback is no longer possible. */
1692
+ get derivedOnly(): boolean;
1693
+ get token(): CancellationToken;
1772
1694
  }
1773
1695
 
1696
+ /** Injectable time source — the engine never calls Date.now directly (determinism). */
1697
+ interface ClockPort {
1698
+ now(): number;
1699
+ }
1700
+ /** Stable id minting for sessions, commits, and allocator seeds. */
1701
+ interface IdentityPort {
1702
+ newId(): string;
1703
+ }
1704
+ /** Cooperative scheduling of deferred work. */
1705
+ interface SchedulingPort {
1706
+ schedule(task: () => void): void;
1707
+ }
1708
+ /** Redacted observability sink (raw text never enters here — design D5). */
1709
+ interface AuditPort {
1710
+ record(entry: {
1711
+ readonly kind: string;
1712
+ readonly at: number;
1713
+ readonly meta?: Record<string, unknown>;
1714
+ }): void;
1715
+ }
1716
+ /** Read/write/export authorization decisions. */
1717
+ interface AuthorizationPort {
1718
+ authorize(action: string, subject?: string): boolean;
1719
+ }
1720
+ /** Explicit consent gate for any remote/external resource (no zero-click fetch). */
1721
+ interface ExternalResourceConsentPort {
1722
+ requestConsent(target: string): boolean;
1723
+ }
1724
+ /** Cancellation source for the current operation. */
1725
+ interface CancellationPort {
1726
+ readonly token: CancellationToken;
1727
+ }
1728
+ /** Where documents are stored and retrieved. Opaque marker until its milestone. */
1729
+ interface PersistencePort {
1730
+ readonly kind: 'persistence';
1731
+ }
1732
+ /** How the engine talks to a remote peer. Opaque marker until its milestone. */
1733
+ interface TransportPort {
1734
+ readonly kind: 'transport';
1735
+ }
1736
+ /** Where font bytes come from. Opaque marker until its milestone. */
1737
+ interface FontPort {
1738
+ readonly kind: 'font';
1739
+ }
1740
+ /** Which shaping backend measures text. Opaque marker until its milestone. */
1741
+ interface ShapingPort {
1742
+ readonly kind: 'shaping';
1743
+ }
1744
+ /** How image bytes are decoded. Opaque marker until its milestone. */
1745
+ interface ImagePort {
1746
+ readonly kind: 'image';
1747
+ }
1748
+ /** Where resource consumption is reported. Opaque marker until its milestone. */
1749
+ interface ResourceAccountingPort {
1750
+ readonly kind: 'resource-accounting';
1751
+ }
1774
1752
  /**
1775
- * Delete a comment thread: that story's markers, and metadata no other story still names.
1776
- *
1777
- * `owner` names the story whose markers may be stripped. Omitted, it is the main document
1778
- * body — never every XML part. A header or note that reused the same `w:id` is a different
1779
- * remark; pass its part (and `noteId` when the story is one note) to delete that one.
1753
+ * A required port the runtime did not provide.
1780
1754
  *
1781
- * Returns the package unchanged when the id names no comment, and null when a removal was
1782
- * refused — a caller inside a transaction rolls back rather than committing a package whose
1783
- * comment is half gone.
1755
+ * Thrown rather than falling back: silently reaching for a browser global when a worker or server
1756
+ * adapter did not supply a port is exactly the coupling ports exist to prevent.
1784
1757
  */
1785
- declare function deleteCommentThread(pkg: OoxmlPackage, commentId: string, owner?: CommentDeletionOwner): OoxmlPackage | null;
1758
+ declare class PortResolutionError extends Error {
1759
+ readonly portId: string;
1760
+ constructor(portId: string);
1761
+ }
1786
1762
  /**
1787
- * Delete every comment the edit between `before` and `after` emptied in `owner`'s story.
1788
- *
1789
- * `owner` omitted is the main document body, matching {@link deleteCommentThread}.
1763
+ * The environment-dependent services an engine instance may reach.
1790
1764
  *
1791
- * THE TEST, exactly, and per story. A comment dies when the words it covered in that story are
1792
- * gone and nothing in that story still places it. A neighbour that reused the same `w:id` is
1793
- * judged under its own owner. Notes that vanished (reference cascade) are reaped as their own
1794
- * stories so a unique id still loses its `comments.xml` body. Remaining-marker overflow
1795
- * preserves comments/commentEx/commentId metadata rather than deleting records the scan could
1796
- * not prove unused. Null is reserved for a removal that actually failed.
1765
+ * Everything outside pure computation — the clock, identity minting, scheduling, fonts, images —
1766
+ * is reached only through here, which is what lets browser, worker and server adapters supply
1767
+ * only what their runtime actually offers.
1797
1768
  */
1798
- declare function cascadeEmptiedComments(before: OoxmlPackage, after: OoxmlPackage, owner?: CommentDeletionOwner): OoxmlPackage | null;
1799
-
1800
- /** Presentation settings the document itself states. Absence is the answer, never an error. */
1801
- interface DocumentViewSettings {
1802
- /**
1803
- * `w:doNotShadeFormData` (§17.15.1.49) — do NOT shade legacy form fields.
1804
- *
1805
- * Word draws a grey block behind every `w:ffData` field so a reader can find the blanks in a
1806
- * form. It is on by DEFAULT, and this element is how a document turns it off, so the absent
1807
- * case means shading. Reading the name as "shade form data" inverts it and blanks the shading
1808
- * on exactly the documents that asked for it loudest.
1809
- *
1810
- * Never printed, by Word or by us: it marks where to type, and a printed form has no blanks
1811
- * to find.
1812
- */
1813
- readonly doNotShadeFormData: boolean;
1769
+ declare class PortRegistry {
1770
+ private readonly ports;
1771
+ provide(portId: string, port: unknown): this;
1772
+ has(portId: string): boolean;
1773
+ /** Resolve a port by id or throw. */
1774
+ resolve<T>(portId: string): T;
1775
+ /** Assert every id in `portIds` is present; returns the missing ones (empty if all present). */
1776
+ missing(portIds: readonly string[]): string[];
1777
+ /** The provided port ids (for bridging to registry.resolve availablePorts). */
1778
+ availablePorts(): string[];
1779
+ clock(): ClockPort;
1780
+ identity(): IdentityPort;
1781
+ }
1782
+ /** Deterministic clock: starts at `start` and advances by `step` each call. */
1783
+ declare class DeterministicClock implements ClockPort {
1784
+ private readonly step;
1785
+ private t;
1786
+ constructor(start?: number, step?: number);
1787
+ now(): number;
1788
+ }
1789
+ /** Sequential identity for tests and deterministic fixtures. */
1790
+ declare class SequentialIdentity implements IdentityPort {
1791
+ private readonly prefix;
1792
+ private n;
1793
+ constructor(prefix?: string);
1794
+ newId(): string;
1814
1795
  }
1815
- /** The defaults a document with no `settings.xml` gets: everything Word would shade, shaded. */
1816
- declare const DEFAULT_VIEW_SETTINGS: DocumentViewSettings;
1817
- /** Read the view settings from a `settings.xml` root, or the defaults when it has none. */
1818
- declare function readViewSettings(settingsRoot: OoxmlNode | null | undefined): DocumentViewSettings;
1819
1796
 
1820
- /** How deep transparent block wrappers may nest before the walk stops descending. */
1821
- declare const MAX_STORY_SDT_NESTING = 32;
1822
- /** Which kind of story a root is. Layout walks all four the same way. */
1823
- type OoxmlStoryKind = 'body' | 'header' | 'footer' | 'note';
1824
- /** One story root and the blocks under it, with transparent block wrappers already flattened. */
1825
- interface OoxmlStoryRoot {
1826
- readonly kind: OoxmlStoryKind;
1827
- /** The `w:body` / `w:hdr` / `w:ftr` / `w:footnote` element that holds the blocks. */
1828
- readonly root: OoxmlNode;
1797
+ /** What one operation is started with. Only `ports` is required. */
1798
+ interface OperationInit {
1799
+ readonly ports: PortRegistry;
1800
+ readonly limits?: Partial<ResourceLimits>;
1801
+ readonly config?: Readonly<Record<string, unknown>>;
1802
+ /** Root budget capacity in abstract units (default: the byte decompression limit). */
1803
+ readonly capacity?: number;
1804
+ /** Operation identity (from IdentityPort in production); defaulted for tests. */
1805
+ readonly id?: string;
1829
1806
  }
1830
1807
  /**
1831
- * Every story root in a part, in document order.
1832
- *
1833
- * Does not descend INTO a story: a story's blocks are the walk below, and a story root never
1834
- * contains another story root.
1835
- */
1836
- declare function storyRootsOf(part: OoxmlPart): readonly OoxmlStoryRoot[];
1837
- /**
1838
- * Whether a part is SHAPED to hold stories — a body, a header, a footer, or a notes part.
1808
+ * The frozen environment of one operation: its limits, config, ports, root budget and
1809
+ * cancellation controller.
1839
1810
  *
1840
- * A shape test, deliberately not `storyRootsOf(part).length > 0`. That counts EDITABLE stories,
1841
- * and a notes part holding nothing but `w:separator` and `w:continuationSeparator` has none —
1842
- * which is the footnotes part Word writes into every document that ever held a footnote. A
1843
- * caller asking "should I walk this part at all" that used the editable count skipped it
1844
- * entirely, and the two callers that ask are a payload sweep and an export strip: both DELETE
1845
- * what they conclude nothing names.
1811
+ * IMMUTABLE for the operation's lifetime, which is what lets cache reuse and replica agreement
1812
+ * key on it. A new operation always gets a fresh snapshot rather than observing a mutated one.
1846
1813
  */
1847
- declare function isStoryPart(part: OoxmlPart): boolean;
1848
- /** The main body story of a part, or null when the part holds none. */
1849
- declare function bodyStoryRoot(part: OoxmlPart): OoxmlNode | null;
1814
+ interface OperationContext {
1815
+ readonly id: string;
1816
+ readonly limits: ResourceLimits;
1817
+ readonly config: Readonly<Record<string, unknown>>;
1818
+ readonly ports: PortRegistry;
1819
+ readonly budget: Budget;
1820
+ readonly cancellation: CancellationController;
1821
+ }
1850
1822
  /**
1851
- * Every paragraph of one story, in reading order.
1823
+ * Begin an operation, capturing its immutable environment snapshot.
1852
1824
  *
1853
- * Descends through tables (rows, cells, nested tables), block controls and block custom XML.
1854
- * The returned nodes are paragraph elements; a caller addresses them by `id`.
1825
+ * Resolves and freezes limits and configuration, carves the root budget, and creates the
1826
+ * cancellation controller — everything downstream work needs, fixed for the operation's duration.
1855
1827
  */
1856
- declare function storyParagraphs(root: OoxmlNode): readonly OoxmlNode[];
1828
+ declare function beginOperation(init: OperationInit): OperationContext;
1829
+ /** Release the operation's root budget (requires every child/reservation released). */
1830
+ declare function endOperation(ctx: OperationContext): void;
1831
+
1832
+ /** What a limit counts. Typed so a byte cap and a depth cap cannot be compared by accident. */
1833
+ type LimitUnit = 'bytes' | 'count' | 'depth' | 'ratio' | 'passes';
1857
1834
  /**
1858
- * The block walk itself, appending into `out`.
1835
+ * Where a limit is enforced.
1859
1836
  *
1860
- * Exported so `allParagraphs` in the binding lane is the same traversal rather than a second
1861
- * copy of it.
1837
+ * Declared per limit so enforcement happens at the boundary that can still refuse cheaply — a zip
1838
+ * cap checked during layout has already let the bomb decompress.
1862
1839
  */
1863
- declare function collectStoryParagraphs(children: readonly OoxmlNode[], out: OoxmlNode[], sdtDepth: number): void;
1864
-
1865
- /** One searchable text-box story and the drawing location that can reveal it. */
1866
- interface TextboxStoryRoot {
1867
- /** The `w:txbxContent` story root. */
1868
- readonly root: OoxmlElement;
1869
- /** Layout atom id used to select the drawing, including an MC wrapper when present. */
1870
- readonly drawingNodeId: string;
1871
- /** Canonical node id of the paragraph that anchors the drawing. */
1872
- readonly hostParagraphId: string;
1840
+ type EnforcementPhase = 'package-read' | 'xml-parse' | 'layout' | 'output';
1841
+ /** One limit's unit and enforcement phase — the metadata that makes limits testable uniformly. */
1842
+ interface LimitSpec {
1843
+ readonly unit: LimitUnit;
1844
+ readonly phase: EnforcementPhase;
1873
1845
  }
1846
+ /** Unit + enforcement phase for every resource limit. */
1847
+ declare const LIMIT_SPECS: Readonly<Record<keyof ResourceLimits, LimitSpec>>;
1848
+ /** Every limit name, for iterating the specs and asserting each has a unit and phase. */
1849
+ declare const LIMIT_KEYS: (keyof ResourceLimits)[];
1850
+ /** A phase-scoped overflow-safe counter for one limit. */
1851
+ declare function makeLimitCounter(limits: ResourceLimits, key: keyof ResourceLimits): BoundedCounter;
1874
1852
  /**
1875
- * List the text-box stories in one part, in document order.
1876
- *
1877
- * The bounded walk stops at drawings. It does not project pictures, shape geometry, or story
1878
- * content. Results are memoized by immutable part-root identity.
1853
+ * Deterministic memory substitute. Tracks current and peak "allocated" units
1854
+ * against a hard byte ceiling; `allocate` fails closed (LimitExceededError) past
1855
+ * the limit. Used in place of process RSS so memory-limit tests are reproducible
1856
+ * and cancellation/cleanup can be asserted without a real allocator.
1879
1857
  */
1880
- declare function textboxStoriesInPart(part: OoxmlPart): readonly TextboxStoryRoot[];
1881
-
1882
- /** Relationship from the story to one data part. */
1883
- declare const CUSTOM_XML_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
1884
- /** Relationship from a data part to the properties that carry its `ds:itemID`. */
1885
- declare const CUSTOM_XML_PROPS_REL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps";
1886
- /** `itemPropsN.xml` needs an Override; `itemN.xml` rides the package's `xml` default. */
1887
- declare const CUSTOM_XML_PROPS_TYPE = "application/vnd.openxmlformats-officedocument.customXmlProperties+xml";
1888
- /** The datastore namespace `ds:datastoreItem` lives in. */
1889
- declare const DATASTORE_NAMESPACE_URI = "http://schemas.openxmlformats.org/officeDocument/2006/customXml";
1890
- /** A data part located in a package: where it lives, and the GUID an SDT binds to. */
1891
- interface CustomXmlDataPart {
1892
- /** Canonical part name, e.g. `/customXml/item1.xml`. */
1893
- readonly partName: string;
1894
- /** Part name of its properties, e.g. `/customXml/itemProps1.xml`. */
1895
- readonly propsPartName: string;
1896
- /** `ds:itemID`, braced and upper-case, as `w:storeItemID` must spell it. */
1897
- readonly itemId: string;
1898
- /** Namespace URI of the payload root, which is what identifies one store among several. */
1899
- readonly namespaceUri: string;
1858
+ declare class DeterministicMemoryMeter {
1859
+ private readonly counter;
1860
+ private current;
1861
+ private peak;
1862
+ constructor(limitBytes: number);
1863
+ allocate(bytes: number): void;
1864
+ free(bytes: number): void;
1865
+ get currentBytes(): number;
1866
+ get peakBytes(): number;
1867
+ /** Release everything (cancellation/cleanup path). */
1868
+ reset(): void;
1900
1869
  }
1870
+ /** Assert the finite-default / hard-ceiling invariant holds for every limit. */
1871
+ declare function assertLimitInvariants(): void;
1872
+
1873
+ /** Any JSON value. The domain canonicalization and stable hashing operate over. */
1874
+ type Json = null | boolean | number | string | Json[] | {
1875
+ [k: string]: Json;
1876
+ };
1901
1877
  /**
1902
- * A `ds:itemID` derived from the seed rather than drawn at random.
1903
- *
1904
- * Exported so a caller that authors a store OUTSIDE a package — a template engine splicing
1905
- * markup it will assemble into a `.docx` later — mints the id the same way this does, rather
1906
- * than inventing a second GUID shape Word has to be tolerant of.
1907
- *
1908
- * The store is a pure function of what it is asked to write: the same document written twice
1909
- * has to produce the same bytes, or a save/reopen/save round trip stops being a fixed point
1910
- * and every digest taken over saved bytes moves. A GUID's job here is uniqueness within one
1911
- * package, not unguessability, so four FNV-1a passes over a salted seed carry it.
1878
+ * Produce a canonical string for `value`, dropping any object key whose name is
1879
+ * in `ephemera` at any depth. Numbers are emitted losslessly; -0 normalizes to 0;
1880
+ * non-finite numbers are rejected (they must never enter a comparator input).
1912
1881
  */
1913
- declare function datastoreItemIdFor(seed: string): string;
1882
+ declare function canonicalize(value: unknown, ephemera?: ReadonlySet<string>): string;
1883
+ /** 64-bit FNV-1a over the canonical form, returned as a 16-char hex string. */
1884
+ declare function stableHash(value: unknown, ephemera?: ReadonlySet<string>): string;
1885
+
1914
1886
  /**
1915
- * The data parts a story relates to, in relationship order.
1887
+ * How one artifact class is compared.
1916
1888
  *
1917
- * Reads the relationships rather than scanning `/customXml/` by name: a part nothing relates
1918
- * to is not part of the document, and a package from a hostile sender can hold as many
1919
- * plausibly-named files as it likes.
1889
+ * Frozen per artifact: nothing here invents a tolerance for an artifact the spec requires to
1890
+ * match exactly.
1920
1891
  */
1921
- declare function customXmlDataParts(pkg: OoxmlPackage, storyPartName: string): CustomXmlDataPart[];
1922
- /** The data part carrying this namespace, or null when the document has none yet. */
1923
- declare function findCustomXmlDataPart(pkg: OoxmlPackage, storyPartName: string, namespaceUri: string): CustomXmlDataPart | null;
1924
- /** What {@link withCustomXmlDataPart} answers. */
1925
- interface CustomXmlDataPartResult {
1926
- readonly pkg: OoxmlPackage;
1927
- /** Null when the part could not be authored; the package then comes back unchanged. */
1928
- readonly part: CustomXmlDataPart | null;
1892
+ type ComparatorMode = 'canonical-exact' | 'exact' | 'tolerance' | 'sync-optimization-only';
1893
+ /** One artifact class's comparison mode and its declared ephemera — fields excluded from equality. */
1894
+ interface ComparatorDescriptor {
1895
+ readonly id: string;
1896
+ readonly mode: ComparatorMode;
1897
+ /** Object keys excluded from canonical-exact comparison (declared ephemera). */
1898
+ readonly ephemera: readonly string[];
1899
+ readonly note: string;
1900
+ }
1901
+ /** The frozen artifact comparator set. */
1902
+ declare const COMPARATORS: {
1903
+ readonly authoredState: {
1904
+ readonly id: "dev.docx-editor.core.comparator.authored-state";
1905
+ readonly mode: 'canonical-exact';
1906
+ readonly ephemera: readonly ["revision", "provenance", "producedAt", "commitId"];
1907
+ readonly note: 'canonical normalized authored records; ephemera excluded';
1908
+ };
1909
+ readonly anchor: {
1910
+ readonly id: "dev.docx-editor.core.comparator.anchor";
1911
+ readonly mode: 'exact';
1912
+ readonly ephemera: readonly [];
1913
+ readonly note: 'internal anchor identity/affinity compares exactly';
1914
+ };
1915
+ readonly yjsStateVector: {
1916
+ readonly id: "dev.docx-editor.core.comparator.yjs-state-vector";
1917
+ readonly mode: 'sync-optimization-only';
1918
+ readonly ephemera: readonly [];
1919
+ readonly note: 'exchange optimization only; never proves update or delete-set coverage';
1920
+ };
1921
+ readonly shapedRun: {
1922
+ readonly id: "dev.docx-editor.core.comparator.shaped-run";
1923
+ readonly mode: 'exact';
1924
+ readonly ephemera: readonly [];
1925
+ readonly note: 'glyph ids, clusters, and fixed-point advances compare exactly';
1926
+ };
1927
+ readonly paginationFingerprint: {
1928
+ readonly id: "dev.docx-editor.core.comparator.pagination-fingerprint";
1929
+ readonly mode: 'exact';
1930
+ readonly ephemera: readonly [];
1931
+ readonly note: 'page/column boundaries, break causes, fixed-point geometry compare exactly';
1932
+ };
1933
+ readonly semanticTree: {
1934
+ readonly id: "dev.docx-editor.core.comparator.semantic-tree";
1935
+ readonly mode: 'exact';
1936
+ readonly ephemera: readonly [];
1937
+ readonly note: 'reading order, roles, headings, alt text compare exactly';
1938
+ };
1939
+ readonly hitTest: {
1940
+ readonly id: "dev.docx-editor.core.comparator.hit-test";
1941
+ readonly mode: 'exact';
1942
+ readonly ephemera: readonly [];
1943
+ readonly note: 'resolved hit target and cluster affinity compare exactly';
1944
+ };
1945
+ readonly pdfSemantics: {
1946
+ readonly id: "dev.docx-editor.core.comparator.pdf-semantics";
1947
+ readonly mode: 'canonical-exact';
1948
+ readonly ephemera: readonly ["objectNumber", "producer", "creationDate", "modDate", "subsetTag"];
1949
+ readonly note: 'canonical semantic PDF objects; container ephemera excluded';
1950
+ };
1951
+ readonly rasterCheckpoint: {
1952
+ readonly id: "dev.docx-editor.core.comparator.raster-checkpoint";
1953
+ readonly mode: 'tolerance';
1954
+ readonly ephemera: readonly [];
1955
+ readonly note: 'documented unavoidable raster comparison; explicit tolerance only';
1956
+ };
1957
+ readonly benchmarkEvidence: {
1958
+ readonly id: "dev.docx-editor.core.comparator.benchmark-evidence";
1959
+ readonly mode: 'sync-optimization-only';
1960
+ readonly ephemera: readonly [];
1961
+ readonly note: 'diagnostic evidence, not an equivalence basis';
1962
+ };
1963
+ };
1964
+ /** Which frozen comparator to use. */
1965
+ type ComparatorName = keyof typeof COMPARATORS;
1966
+ /** Whether two artifacts matched, and where they diverged when they did not. */
1967
+ interface ComparisonResult {
1968
+ readonly equal: boolean;
1969
+ /** Canonical forms when unequal (diagnostic). */
1970
+ readonly left?: string;
1971
+ readonly right?: string;
1929
1972
  }
1930
1973
  /**
1931
- * Ensure the document carries a data part for this namespace, creating it and everything it
1932
- * needs — properties, both relationships, the properties content type — when it does not.
1933
- *
1934
- * Idempotent: a package that already has one for the namespace comes back untouched, so a
1935
- * second node added to the same store does not author a second store.
1936
- *
1937
- * @param storyPartName - Whose relationships the store hangs off. Word enumerates its data
1938
- * store from the MAIN DOCUMENT part, so a store authored off a header or footer is one Word
1939
- * never sees.
1940
- */
1941
- declare function withCustomXmlDataPart(pkg: OoxmlPackage, storyPartName: string, namespaceUri: string, rootLocalName: string): CustomXmlDataPartResult;
1942
- /**
1943
- * Remove a store from a document: both parts, both relationships, the Override.
1944
- *
1945
- * PACKAGE ONLY. It does not touch the body, so a `w:sdt` bound to the store keeps its
1946
- * `w:dataBinding`, its `w:storeItemID` and its `w:tag`, and Word then opens a control bound to
1947
- * a store that is not there. Stripping those is the export path's job and is not built; this
1948
- * is the half that removes the payload, which is the half a caller can rely on.
1949
- *
1950
- * `ok: false` means nothing was removed and the package is unchanged — most often because an
1951
- * owner's `.rels` was never parsed into a tree, which {@link withoutPart} refuses to work
1952
- * around. A caller exporting a document has to treat that as a failure to export rather than
1953
- * as a document with nothing to strip, or it ships the payload it meant to remove.
1974
+ * Compare two artifacts under a named comparator. `canonical-exact` and `exact`
1975
+ * compare canonical forms (exact drops no ephemera). `tolerance` requires an
1976
+ * epsilon and compares finite numbers structurally. `sync-optimization-only`
1977
+ * throws — such artifacts are never an equivalence basis.
1954
1978
  */
1955
- declare function withoutCustomXmlDataPart(pkg: OoxmlPackage, storyPartName: string, namespaceUri: string): WithoutPartResult;
1979
+ declare function compareArtifacts(name: ComparatorName, left: unknown, right: unknown, opts?: {
1980
+ epsilon?: number;
1981
+ }): ComparisonResult;
1982
+ /** Fingerprint an artifact under a named comparator's canonicalization policy. */
1983
+ declare function fingerprint(name: ComparatorName, value: unknown): string;
1956
1984
 
1957
- /** One node in a store: its id, the bound text, and the payload beside it. */
1958
- interface CustomXmlNode {
1959
- readonly id: string;
1960
- /** Text a `w:dataBinding` resolves to. Untrusted file input. */
1961
- readonly label: string;
1962
- /** Payload as authored, JSON by convention and unparsed here. Untrusted file input. */
1963
- readonly data: string;
1985
+ /** Whether a recorded conformance step was expected to commit or be refused. */
1986
+ type FixtureOutcome = 'applied' | 'aborted' | 'validation' | 'conflict' | 'resource' | 'authorization';
1987
+ /** The change one step produced, summarized to what a fixture can compare across runtimes. */
1988
+ interface ModelChangeSummary {
1989
+ readonly fromRevision: number;
1990
+ readonly toRevision: number;
1991
+ readonly origin: string;
1992
+ readonly dirty: readonly string[];
1993
+ readonly dependencyKeys: readonly string[];
1964
1994
  }
1965
- /** Every node a store holds, in document order. */
1966
- declare function customXmlNodes(pkg: OoxmlPackage, partName: string): CustomXmlNode[];
1967
- /** One node by id, or null. */
1968
- declare function readCustomXmlNode(pkg: OoxmlPackage, partName: string, nodeId: string): CustomXmlNode | null;
1969
- /**
1970
- * Write a node, replacing one that already has the id.
1971
- *
1972
- * Replace rather than append: a second node with the same id makes the binding xpath ambiguous,
1973
- * and Word resolves an ambiguous xpath to the first match — so an "update" that appended would
1974
- * leave the control showing its old text forever.
1975
- */
1976
- declare function withCustomXmlNode(pkg: OoxmlPackage, partName: string, node: CustomXmlNode): OoxmlPackage;
1977
- /** Drop one node by id. A store that never held it comes back unchanged. */
1978
- declare function withoutCustomXmlNode(pkg: OoxmlPackage, partName: string, nodeId: string): OoxmlPackage;
1979
- /**
1980
- * Drop every node no longer referenced, given the ids the document still binds.
1981
- *
1982
- * This is the whole deletion story. Deleting a control in THIS editor can remove its node
1983
- * directly, but a control deleted in Word leaves the node behind — Word has no lifecycle link
1984
- * between the two and no way to run our code. Reconciling against what the story actually binds
1985
- * collects both, and is the only thing that can collect the second.
1986
- *
1987
- * Takes the referenced ids rather than reading the story itself: the caller already walked it,
1988
- * and a sweep that guessed at which controls exist would delete a payload on a mistake.
1989
- */
1990
- declare function withoutOrphanCustomXmlNodes(pkg: OoxmlPackage, partName: string, referencedIds: ReadonlySet<string>): {
1991
- readonly pkg: OoxmlPackage;
1992
- readonly removed: readonly string[];
1995
+ /** Where anchors sat after a step — how a fixture proves positions survived an edit. */
1996
+ interface AnchorSnapshot {
1997
+ readonly anchorId: string;
1998
+ readonly story: string;
1999
+ readonly block: string;
2000
+ readonly affinity: 'before' | 'after';
2001
+ }
2002
+ /** What one step must produce: its outcome, its change summary, and its authored-state hash. */
2003
+ interface FixtureExpectation {
2004
+ readonly outcome: FixtureOutcome;
2005
+ /** Present iff outcome === 'applied'; MUST be > baseRevision. */
2006
+ readonly committedRevision?: number;
2007
+ readonly modelChange?: ModelChangeSummary;
2008
+ /** 16-hex authored-state fingerprint (comparator 0.4). */
2009
+ readonly authoredStateHash?: string;
2010
+ readonly outputHash?: string;
2011
+ readonly anchors?: readonly AnchorSnapshot[];
2012
+ }
2013
+ /** One recorded operation and what it was expected to do. */
2014
+ interface FixtureStep {
2015
+ readonly baseRevision: number;
2016
+ readonly origin: string;
2017
+ /** Opaque DocOp payloads (schema owned by section 4). */
2018
+ readonly ops: readonly unknown[];
2019
+ readonly expect: FixtureExpectation;
2020
+ }
2021
+ /** Opaque encoded backend bytes (snapshot or replication update). */
2022
+ interface EncodedEnvelope {
2023
+ readonly kind: 'snapshot' | 'update';
2024
+ readonly protocolVersion: number;
2025
+ readonly schemaVersion: number;
2026
+ readonly documentId: string;
2027
+ readonly byteLength: number;
2028
+ /** Hex-encoded opaque bytes; length MUST equal byteLength. */
2029
+ readonly bytesHex: string;
2030
+ }
2031
+ /** Which implementation recorded a fixture — local store, Yjs, or a binding. */
2032
+ type FixtureSource = {
2033
+ readonly kind: 'create';
2034
+ } | {
2035
+ readonly kind: 'docx';
2036
+ readonly sha256: string;
2037
+ readonly bytesRef: string;
1993
2038
  };
1994
2039
  /**
1995
- * The `w:xpath` a binding uses to reach a node's label, or null when the id cannot be addressed.
2040
+ * The frozen conformance container: revisions, origins, operations, changes, snapshots and
2041
+ * hashes.
1996
2042
  *
1997
- * Word needs a prefix for the payload namespace even when the store declares it as a default —
1998
- * an unprefixed step in an XPath means "no namespace", so `/docxEditor/node` would match
1999
- * nothing in a namespaced store. The prefix is declared in `w:prefixMappings` beside it.
2043
+ * The CONTAINER is what is frozen — field names, origin membership, revision monotonicity, hash
2044
+ * format. The op and change payloads travel opaquely, so their schemas can evolve without
2045
+ * invalidating every recorded fixture.
2000
2046
  */
2001
- declare function customXmlLabelXPath(prefix: string, rootLocalName: string, nodeId: string): string | null;
2002
- /** The `w:prefixMappings` value declaring that prefix, or null when it cannot be written.
2003
- * The namespace sits inside single quotes inside a double-quoted attribute, so a namespace
2004
- * carrying either quote character has no representation here. */
2005
- declare function customXmlPrefixMappings(prefix: string, namespaceUri: string): string | null;
2006
-
2007
- /** The prefix every binding this library authors declares and quotes. */
2008
- declare const CUSTOM_NODE_XPATH_PREFIX = "ns0";
2009
- /** The three attributes a `w:dataBinding` carries. */
2010
- interface CustomNodeBinding {
2011
- readonly prefixMappings: string;
2012
- readonly xpath: string;
2013
- readonly storeItemId: string;
2047
+ interface ConformanceFixture {
2048
+ readonly formatVersion: 1;
2049
+ readonly documentId: string;
2050
+ readonly source: FixtureSource;
2051
+ readonly steps: readonly FixtureStep[];
2052
+ readonly snapshots?: readonly EncodedEnvelope[];
2053
+ readonly updates?: readonly EncodedEnvelope[];
2014
2054
  }
2015
- /**
2016
- * The binding for one node in one store, or null when the id cannot be addressed by an XPath.
2017
- *
2018
- * Refuses rather than escapes: XPath 1.0 has no escape for a quote inside a literal, so an id
2019
- * carrying one could close the predicate and append an expression of the sender's choosing.
2020
- * The ids are minted by a host, so refusing is honest — see `ADDRESSABLE_ID`.
2021
- */
2022
- declare function customNodeBinding(part: CustomXmlDataPart, rootLocalName: string, nodeId: string): CustomNodeBinding | null;
2023
- /**
2024
- * Every node id the story's controls bind to in one store, in document order.
2025
- *
2026
- * This is the input the orphan sweep takes: a node whose id is not in here is one no control
2027
- * names, whether it was deleted in this editor or in Word. Reading it from the STORY rather than
2028
- * from a host's bookkeeping is what makes the two cases one mechanism.
2029
- */
2030
- declare function boundCustomXmlNodeIds(part: OoxmlPart, storeItemId: string): Set<string>;
2031
- /**
2032
- * Every node id ANY story in the package binds, in one store.
2033
- *
2034
- * THE WHOLE PACKAGE, not one story. A payload is reachable from a header as easily as from the
2035
- * body — Word enumerates its data store from the main part, but nothing stops a control
2036
- * elsewhere quoting the same `w:storeItemID` — and the two callers that decide what is an orphan
2037
- * both destroy data when they are wrong. The sweep would collect a payload a header still paints;
2038
- * the export would strip a store a header still names, which is a document Word offers to repair.
2039
- *
2040
- * Costs one walk per story per store, on open and on export. Neither is a keystroke.
2041
- */
2042
- declare function boundCustomXmlNodeIdsInPackage(pkg: OoxmlPackage, storeItemId: string): Set<string>;
2043
- /** The node id one control binds to in the named store, or null when it binds to nothing there. */
2044
- declare function boundCustomXmlNodeIdOf(control: OoxmlNode, storeItemId: string): string | null;
2055
+ /** Whether a fixture is well-formed, listing every structural violation. */
2056
+ interface ValidationResult {
2057
+ readonly valid: boolean;
2058
+ readonly errors: readonly string[];
2059
+ }
2060
+ /** Structurally validate a fixture against the frozen format rules. */
2061
+ declare function validateFixture(fixture: ConformanceFixture): ValidationResult;
2045
2062
 
2046
- /** What happens to one control when the document is exported. */
2047
- type CustomNodeExportPolicy = 'keep' | 'text' | 'remove';
2048
- /** How {@link withExportedCustomNodes} decides, and which stores it may tidy afterwards. */
2049
- interface CustomNodeExportRequest {
2050
- /** The story whose controls are policed, and whose relationships the stores hang off. */
2051
- readonly storyPartName: string;
2052
- /**
2053
- * Payload namespaces the caller CLAIMS.
2054
- *
2055
- * The store cleanup runs only over these. Word's own Cover Page Properties store rides in most
2056
- * templates, and an export that tidied every customXml part would be deleting from documents it
2057
- * was only asked to strip its own markup from.
2058
- */
2059
- readonly namespaces: readonly string[];
2060
- /** The fate of a control carrying this `w:tag`. A control with no tag is never touched. */
2061
- readonly decide: (tag: string) => CustomNodeExportPolicy;
2063
+ /** The outcome a store reports for one replayed step. */
2064
+ interface ReplayOutcome {
2065
+ readonly outcome: FixtureOutcome;
2066
+ readonly committedRevision?: number;
2067
+ /** Canonical authored-state value AFTER the step (hashed via comparator 0.4). */
2068
+ readonly authoredState?: unknown;
2069
+ }
2070
+ /** The interface a conformance runtime implements so one fixture can drive every backend. */
2071
+ interface ReplayStore {
2072
+ /** Initialize from the fixture source; return the initial revision (0 for create). */
2073
+ init(fixture: ConformanceFixture): number;
2074
+ /** Apply one step and report what happened. */
2075
+ applyStep(step: FixtureStep): ReplayOutcome;
2076
+ }
2077
+ /** What replaying a fixture produced: per-step outcomes and where they diverged. */
2078
+ interface ReplayReport {
2079
+ readonly ok: boolean;
2080
+ readonly mismatches: readonly string[];
2062
2081
  }
2063
2082
  /**
2064
- * The export, or the reason there is no export.
2065
- *
2066
- * A refusal answers no package on purpose. "Stripping failed, here is the document anyway" is the
2067
- * one outcome that must not be possible: a caller would ship the markup it asked to remove and
2068
- * have been told the export succeeded.
2069
- */
2070
- type CustomNodeExportResult = {
2071
- readonly ok: true;
2072
- readonly pkg: OoxmlPackage;
2073
- /** Controls unwrapped (`text`) and controls removed (`remove`). */
2074
- readonly unwrapped: number;
2075
- readonly removed: number;
2076
- } | {
2077
- readonly ok: false;
2078
- readonly reason: string;
2079
- };
2080
- /**
2081
- * Apply the policy, then take the payloads and the stores the policy orphaned.
2082
- *
2083
- * Order matters and is the reverse of the write's. The BODY goes first, so the sweep that follows
2084
- * sees the controls that actually survive; the stores go last, once nothing binds them. Doing it
2085
- * the other way would strip a store while a control still quoted its `w:storeItemID`, which is a
2086
- * document Word opens and offers to repair.
2083
+ * Replay a fixture against a store and check every step's outcome, committed
2084
+ * revision, and authored-state fingerprint against the fixture's expectations.
2087
2085
  */
2088
- declare function withExportedCustomNodes(pkg: OoxmlPackage, request: CustomNodeExportRequest): CustomNodeExportResult;
2086
+ declare function replayFixture(fixture: ConformanceFixture, store: ReplayStore): ReplayReport;
2087
+ /** Hash a store's authored state, so two runtimes replaying one fixture can be compared. */
2088
+ declare function hashAuthored(authoredState: unknown): string;
2089
2089
 
2090
2090
  /**
2091
2091
  * WHERE a copy reaches, computed by the editing surface against the published layout with
@@ -2484,6 +2484,8 @@ interface RevisionSite {
2484
2484
  readonly parent: OoxmlElement | null;
2485
2485
  /** True when this site cannot be resolved and the whole op must refuse. */
2486
2486
  readonly refused: boolean;
2487
+ /** Why, when `refused` is true. */
2488
+ readonly refusal?: RevisionSiteRefusal;
2487
2489
  /** True for `w:pPr/w:rPr/w:ins|w:del` — the paragraph MARK, not content. */
2488
2490
  readonly paragraphMark: boolean;
2489
2491
  /** True for a supported property-history wrapper. */
@@ -2702,5 +2704,5 @@ declare function sectionProtectsForms(part: OoxmlPart, nodeId: string): boolean;
2702
2704
  /** Every {@link TreeDocOpKind}, for validation and exhaustiveness checks. */
2703
2705
  declare const TREE_DOC_OP_KINDS: readonly ["replaceStoryBlocks", "insertText", "deleteText", "setParagraphMarkRevision", "proposeParagraphMerge", "insertCommentMarker", "acceptRevision", "rejectRevision", "acceptAllRevisions", "rejectAllRevisions", "setRevisionAttribution", "insertTab", "insertHardBreak", "insertPageBreak", "insertPageField", "setFieldCode", "setListLevel", "setListNumbering", "setParagraphTabStops", "setParagraphMarkProperties", "splitParagraph", "splitParagraphMany", "joinParagraphs", "setRunProperties", "setParagraphProperties", "setSectionProperties", "setSectionMark", "insertHyperlink", "setHyperlinkTarget", "removeHyperlink", "setMathEquation", "removeMathEquation", "setContentControlValue", "removeContentControl", "insertInlineContentControl", "addRepeatingSectionItem", "removeRepeatingSectionItem", "deleteBlock", "insertTable", "insertTableRow", "deleteTableRow", "insertTableColumn", "deleteTableColumn", "setTableColumnWidths", "setTableRightEdgeWidth", "setTableRowHeight", "setTableProperties", "authorTable", "setTableCellBorders", "setTableCellFill", "setTableCellVerticalAlignment", "createHeaderFooter", "deleteHeaderFooter", "linkToPrevious", "unlinkFromPrevious", "setSectionFurnitureOptions", "setDocumentProtection", "insertNote", "deleteNote", "convertNote", "convertAllNotes", "setNoteProperties", "setContentControlProperties", "insertContentControl", "insertFragment", "insertDrawing", "replaceDrawingResource", "deleteDrawing", "resizeDrawing", "cropDrawing", "positionDrawing", "setDrawingWrap", "setDrawingMetadata", "setDrawingLocks", "transformDrawing", "insertToc", "replaceTocResult", "rewriteTocPageNumbers", "refreshFieldResults", "setTextFormFieldDefault", "commitTextFormField", "setLegacyCheckbox", "setLegacyDropdown", "insertBuildingBlock"];
2704
2706
 
2705
- export { ALL_FROZEN_IDS, AUTHORABLE_PARAGRAPH_PROPERTIES, AUTHORABLE_RUN_PROPERTIES, BoundedCounter, Budget, BudgetError, CANONICAL_MUTATION_ORIGINS, COMPARATORS, CUSTOM_NODE_XPATH_PREFIX, CUSTOM_XML_PROPS_REL, CUSTOM_XML_PROPS_TYPE, CUSTOM_XML_REL, CancellationController, CancellationError, CommentRecord, CommentThreadState, CustomNodeWriteResult, DANGEROUS_KEYS, DATASTORE_NAMESPACE_URI, DEFAULT_FORMATTING_DISPLAY_MODE, DEFAULT_VIEW_SETTINGS, DEPENDENCY_KEY_IDS, DangerousKeyError, DeterministicClock, DeterministicMemoryMeter, DrawingTreeDocOp, FIELD_ATOM_CHAR, FieldResultsMode, ID_KINDS, INERT_EXECUTABLE_KINDS, ImageWrapTarget, ImpactClass, InsertCustomNodeWrite, LIMIT_KEYS, LIMIT_SPECS, LimitExceededError, MAX_STORY_SDT_NESTING, NON_CANONICAL_ORIGINS, ORIGIN_IDS, OmmlEquationProjection, OoxmlAttribute, OoxmlElement, OoxmlFldCharNode, OoxmlFldSimpleNode, OoxmlGenericElementNode, OoxmlHardBreakNode, OoxmlInstrTextNode, OoxmlInvariantIssue, OoxmlInvariantResult, OoxmlNode, OoxmlPackage, OoxmlParagraphNode, OoxmlPart, OoxmlProperty, PAGE_BREAK_CHAR, PortRegistry, PortResolutionError, PrefixAllocator, RESULT_IDS, RUNTIME_PORT_IDS, RegistryError, RelationshipRecord, ResourceLimits, ReviewCommentItem, ReviewItem, ReviewModelInput, ReviewPosition, ReviewRange, ReviewRevisionItem, SEARCH_MATCH_LIMIT, SEARCH_QUERY_MAX, SequentialIdentity, StoryScope, TOC_LEVEL_INDENT_TWIPS, TOC_MAX_BOOKMARKS_PER_REFRESH, TOC_MAX_ENTRIES, TOC_MAX_FIELD_NESTING, TOC_MAX_INSTRUCTION_CHARS, TOC_MAX_PAGE_PASSES, TREE_DOC_OP_KINDS, TWIPS_PER_POINT, TreeDocOp, TreeDocumentStore, TreeModelChange, TreeOpRejection, TreeOpResult, TreePackageStore, addComment, addPackageComment, applyEdits, applyTreeOp, assertLimitInvariants, assertValidId, assertValidQName, atomicFieldSpansOf, authoredProperties, beginOperation, bodyStoryRoot, bookmarkPairNodes, boundCustomXmlNodeIdOf, boundCustomXmlNodeIds, boundCustomXmlNodeIdsInPackage, buildTocContentControl, buildTocEntryParagraph, buildingBlockGalleryOf, buildingBlocksForControl, buildingBlocksOf, canonicalOoxmlFingerprint, canonicalize, cascadeEmptiedComments, collectNodeIds, collectReviewItems, collectRevisionSites, collectStoryParagraphs, commentItemsOf, commentPartNameOf, commentsExtendedPartNameOf, compareArtifacts, compareSemVer, containsCssFetch, contentTypesPartBytes, createNodeIdAllocator, customNodeBinding, customXmlDataParts, customXmlLabelXPath, customXmlNodes, customXmlPrefixMappings, datastoreItemIdFor, deleteCommentThread, deletePackageComments, deriveOoxmlIndexes, detectBodyTocs, diffSemanticDigests, digestPart, directParagraphMarkProperties, directParagraphProperties, displayMathAlignment, drawingOpImpact, endOperation, equationsOfAtom, escapeCssString, escapeXml, extractFragmentPackage, fieldAtomText, fieldOnOffAttribute, findCustomXmlDataPart, findDetectedToc, findNode, findOccurrences, fingerprint, fldCharType, fldSimpleInstr, fnv1a32, foldCase, formatOwnedRunIds, formattableRanges, formsProtectionEnabled, glossaryPartOf, hardBreakAttributes, hardBreakKind, hardBreakText, hasCommentPart, hasLegacyFormFieldData, hasNode, hashAuthored, indexStyles, inlineControlEndingAt, inlineControlStartingAt, insertChildren, insertPackageCustomNode, instrTextValue, isAuthorableRunProperty, isDangerousKey, isDrawingTreeDocOp, isEvaluableField, isFieldChrome, isFldChar, isFldCharNode, isFldSimple, isFldSimpleNode, isInertExecutable, isInstrText, isInstrTextNode, isLegalFldCharType, isOmmlDisplay, isOmmlEquationAtom, isPageBreakNode, isSearchableQuery, isStoryPart, isValidId, isValidNCName, isValidParaId, isValidQName, isWholeWord, linkRevisionReplies, locateSites, makeLimitCounter, materializeGlossaryPlaceholders, mergeFragmentIntoPackage, mergedFontProperty, mergedMultiSettingProperty, mergedParagraphMarkProperties, mergedProperties, mintParaId, mintedParagraphIdentityAttributes, nextCommentId, normalizeParagraphIdentity, nullRecord, ooxmlTreesEqual, paraIdOf, paragraphOffsetIndex, paragraphTextOf, parentNodeOf, parseSemVer, parseTocInstruction, planTocEntries, points, pointsToTwips, projectOmmlAtom, projectOmmlDisplay, propertyContainer, readCustomXmlNode, readTwipsMeasure, readViewSettings, relationshipsOf, relsPartNameFor, removeNode, removePackageCustomNode, replaceChildren, replaceNode, replayFixture, resolve, resolveContentTypeOf, resolveTocRowHeadings, revisionItemsOf, runAddressRanges, runPropertyEdits, runsCovering, sanitizeHref, satisfies, scrubExport, sectionProtectsForms, segmentsOf, semanticDigest, serializeOoxmlPart, setCommentResolved, setPackageCommentResolved, stableHash, storyParagraphs, storyRootsOf, stylesPartOf, textboxStoriesInPart, toSafeRecord, tocEntryText, tocLeftIndentTwips, twips, twipsToPoints, usedParaIds, validateDrawingOp, validateFixture, validateOoxmlPart, validatePackageInvariants, validateTreeOp, w14RootPrefix, withContentTypeOverride, withCustomXmlDataPart, withCustomXmlNode, withExportedCustomNodes, withNewPart, withRelationship, withoutCustomXmlDataPart, withoutCustomXmlNode, withoutOrphanCustomXmlNodes, wrapTargetToAnchorSpec };
2707
+ export { ALL_FROZEN_IDS, AUTHORABLE_PARAGRAPH_PROPERTIES, AUTHORABLE_RUN_PROPERTIES, BoundedCounter, Budget, BudgetError, CANONICAL_MUTATION_ORIGINS, COMPARATORS, CUSTOM_NODE_XPATH_PREFIX, CUSTOM_XML_PROPS_REL, CUSTOM_XML_PROPS_TYPE, CUSTOM_XML_REL, CancellationController, CancellationError, CommentRecord, CommentThreadState, CustomNodeWriteResult, DANGEROUS_KEYS, DATASTORE_NAMESPACE_URI, DEFAULT_FORMATTING_DISPLAY_MODE, DEFAULT_VIEW_SETTINGS, DEPENDENCY_KEY_IDS, DangerousKeyError, DeterministicClock, DeterministicMemoryMeter, DrawingTreeDocOp, FIELD_ATOM_CHAR, FieldResultsMode, ID_KINDS, INERT_EXECUTABLE_KINDS, ImageWrapTarget, ImpactClass, InsertCustomNodeWrite, LIMIT_KEYS, LIMIT_SPECS, LimitExceededError, MAX_STORY_SDT_NESTING, NON_CANONICAL_ORIGINS, ORIGIN_IDS, OmmlEquationProjection, OoxmlAttribute, OoxmlElement, OoxmlFldCharNode, OoxmlFldSimpleNode, OoxmlGenericElementNode, OoxmlHardBreakNode, OoxmlInstrTextNode, OoxmlInvariantIssue, OoxmlInvariantResult, OoxmlNode, OoxmlPackage, OoxmlParagraphNode, OoxmlPart, OoxmlProperty, PAGE_BREAK_CHAR, PortRegistry, PortResolutionError, PrefixAllocator, RESULT_IDS, RUNTIME_PORT_IDS, RegistryError, RelationshipRecord, ResourceLimits, ReviewCommentItem, ReviewItem, ReviewModelInput, ReviewPosition, ReviewRange, ReviewRevisionItem, RevisionSiteRefusal, SEARCH_MATCH_LIMIT, SEARCH_QUERY_MAX, SequentialIdentity, StoryScope, TOC_LEVEL_INDENT_TWIPS, TOC_MAX_BOOKMARKS_PER_REFRESH, TOC_MAX_ENTRIES, TOC_MAX_FIELD_NESTING, TOC_MAX_INSTRUCTION_CHARS, TOC_MAX_PAGE_PASSES, TREE_DOC_OP_KINDS, TWIPS_PER_POINT, TreeDocOp, TreeDocumentStore, TreeModelChange, TreeOpRejection, TreeOpResult, TreePackageStore, addComment, addPackageComment, applyEdits, applyTreeOp, assertLimitInvariants, assertValidId, assertValidQName, atomicFieldSpansOf, authoredProperties, beginOperation, bodyStoryRoot, bookmarkPairNodes, boundCustomXmlNodeIdOf, boundCustomXmlNodeIds, boundCustomXmlNodeIdsInPackage, buildTocContentControl, buildTocEntryParagraph, buildingBlockGalleryOf, buildingBlocksForControl, buildingBlocksOf, canonicalOoxmlFingerprint, canonicalize, cascadeEmptiedComments, collectNodeIds, collectReviewItems, collectRevisionSites, collectStoryParagraphs, commentItemsOf, commentPartNameOf, commentsExtendedPartNameOf, compareArtifacts, compareSemVer, containsCssFetch, contentTypesPartBytes, createNodeIdAllocator, customNodeBinding, customXmlDataParts, customXmlLabelXPath, customXmlNodes, customXmlPrefixMappings, datastoreItemIdFor, deleteCommentThread, deletePackageComments, deriveOoxmlIndexes, detectBodyTocs, diffSemanticDigests, digestPart, directParagraphMarkProperties, directParagraphProperties, displayMathAlignment, drawingOpImpact, endOperation, equationsOfAtom, escapeCssString, escapeXml, extractFragmentPackage, fieldAtomText, fieldOnOffAttribute, findCustomXmlDataPart, findDetectedToc, findNode, findOccurrences, fingerprint, fldCharType, fldSimpleInstr, fnv1a32, foldCase, formatOwnedRunIds, formattableRanges, formsProtectionEnabled, glossaryPartOf, hardBreakAttributes, hardBreakKind, hardBreakText, hasCommentPart, hasLegacyFormFieldData, hasNode, hashAuthored, indexStyles, inlineControlEndingAt, inlineControlStartingAt, insertChildren, insertPackageCustomNode, instrTextValue, isAuthorableRunProperty, isDangerousKey, isDrawingTreeDocOp, isEvaluableField, isFieldChrome, isFldChar, isFldCharNode, isFldSimple, isFldSimpleNode, isInertExecutable, isInstrText, isInstrTextNode, isLegalFldCharType, isOmmlDisplay, isOmmlEquationAtom, isPageBreakNode, isSearchableQuery, isStoryPart, isValidId, isValidNCName, isValidParaId, isValidQName, isWholeWord, linkRevisionReplies, locateSites, makeLimitCounter, materializeGlossaryPlaceholders, mergeFragmentIntoPackage, mergedFontProperty, mergedMultiSettingProperty, mergedParagraphMarkProperties, mergedProperties, mintParaId, mintedParagraphIdentityAttributes, nextCommentId, normalizeParagraphIdentity, nullRecord, ooxmlTreesEqual, paraIdOf, paragraphOffsetIndex, paragraphTextOf, parentNodeOf, parseSemVer, parseTocInstruction, planTocEntries, points, pointsToTwips, projectOmmlAtom, projectOmmlDisplay, propertyContainer, readCustomXmlNode, readTwipsMeasure, readViewSettings, relationshipsOf, relsPartNameFor, removeNode, removePackageCustomNode, replaceChildren, replaceNode, replayFixture, resolve, resolveContentTypeOf, resolveTocRowHeadings, revisionItemsOf, runAddressRanges, runPropertyEdits, runsCovering, sanitizeHref, satisfies, scrubExport, sectionProtectsForms, segmentsOf, semanticDigest, serializeOoxmlPart, setCommentResolved, setPackageCommentResolved, stableHash, storyParagraphs, storyRootsOf, stylesPartOf, textboxStoriesInPart, toSafeRecord, tocEntryText, tocLeftIndentTwips, twips, twipsToPoints, usedParaIds, validateDrawingOp, validateFixture, validateOoxmlPart, validatePackageInvariants, validateTreeOp, w14RootPrefix, withContentTypeOverride, withCustomXmlDataPart, withCustomXmlNode, withExportedCustomNodes, withNewPart, withRelationship, withoutCustomXmlDataPart, withoutCustomXmlNode, withoutOrphanCustomXmlNodes, wrapTargetToAnchorSpec };
2706
2708
  export type { AddCommentRequest, AddCommentResult, AnchorSnapshot, AtomicFieldSpan, AuditPort, AuthorizationPort, BuildingBlock, BuildingBlockGalleryFilter, CancellationPhase, CancellationPort, CancellationToken, CapabilityId, ClockPort, CommentAnchorRequest, CommentDeletionOwner, ComparatorDescriptor, ComparatorMode, ComparatorName, ComparisonResult, ConformanceFixture, ContentItem, Contribution, CustomNodeBinding, CustomNodeExportPolicy, CustomNodeExportRequest, CustomNodeExportResult, CustomXmlDataPart, CustomXmlDataPartResult, CustomXmlNode, DetectedToc, DigestDifference, DocumentViewSettings, EditOptions, EncodedEnvelope, EnforcementPhase, ExternalResourceConsentPort, FeatureBundle, FixtureExpectation, FixtureOutcome, FixtureSource, FixtureStep, FldCharType, FontPort, FormattingDisplayMode, FormattingRevisionAuthorFilter, FragmentCoverage, FragmentExtractRejection, FragmentExtractResult, FragmentMergeRejection, FragmentMergeResult, HardBreakKind, HrefProjection, IdKind, IdentityPort, ImagePort, InertExecutableKind, InlineControlSpan, Json, LimitSpec, LimitUnit, LinkableReviewItem, ModelChangeSummary, OffsetSpan, OoxmlEditResult, OoxmlIndexes, OoxmlStoryKind, OoxmlStoryRoot, OperationContext, OperationInit, PackageCommentDelete, PackageInvariantCode, PackageInvariantIssue, PackageInvariantResult, ParagraphDigest, ParagraphIndexEntry, ParagraphOffsetIndex, PersistencePort, Points, RegistryErrorCode, ReplacementPolicy, ReplayOutcome, ReplayReport, ReplayStore, Reservation, ResolveOptions, ResolvedRegistry, ResourceAccountingPort, RunPropertyEdit, SchedulingPort, ScrubResult, Segment, SemVer, SemanticDigest, SetCommentResolvedResult, ShapingPort, StoryDigest, StoryIndexEntry, StyleIndexEntry, TextMatchOptions, TextOccurrence, TextOccurrences, TextboxStoryRoot, TocEntryPlan, TocInstruction, TocOutlineHeading, TransactionRevisionIds, TransportPort, Twips, ValidationResult };