@cj-tech-master/excelts 9.5.4 → 9.5.5

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 (767) hide show
  1. package/dist/browser/modules/archive/compression/streaming-compress.browser.js +29 -0
  2. package/dist/browser/modules/archive/compression/streaming-compress.js +9 -0
  3. package/dist/browser/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  4. package/dist/browser/modules/archive/fs/archive-file.d.ts +8 -5
  5. package/dist/browser/modules/archive/fs/archive-file.js +78 -16
  6. package/dist/browser/modules/archive/unzip/stream.browser.js +43 -2
  7. package/dist/browser/modules/excel/chart/chart-ex-builder.js +7 -2
  8. package/dist/browser/modules/excel/chart/chart-ex-renderer.js +4 -9
  9. package/dist/browser/modules/excel/chart/chart-ex-types.d.ts +0 -12
  10. package/dist/browser/modules/excel/chart/chart.d.ts +1 -5
  11. package/dist/browser/modules/excel/chart/chart.js +1 -7
  12. package/dist/browser/modules/excel/chart/types.d.ts +0 -6
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +25 -1
  14. package/dist/browser/modules/excel/stream/workbook-reader.js +9 -0
  15. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +228 -13
  17. package/dist/browser/modules/excel/utils/string-buf.d.ts +5 -26
  18. package/dist/browser/modules/excel/utils/string-buf.js +4 -81
  19. package/dist/browser/modules/excel/workbook.browser.js +135 -25
  20. package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  21. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
  22. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +32 -8
  23. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +10 -2
  24. package/dist/browser/modules/excel/xlsx/xlsx.js +9 -1
  25. package/dist/browser/modules/pdf/excel-bridge.d.ts +30 -1
  26. package/dist/browser/modules/pdf/excel-bridge.js +32 -0
  27. package/dist/browser/modules/pdf/font/metrics.d.ts +3 -52
  28. package/dist/browser/modules/pdf/font/metrics.js +3 -237
  29. package/dist/browser/modules/pdf/index.d.ts +1 -1
  30. package/dist/browser/modules/pdf/index.js +1 -1
  31. package/dist/browser/modules/pdf/render-layout-to-pdf.d.ts +66 -0
  32. package/dist/browser/modules/pdf/render-layout-to-pdf.js +647 -0
  33. package/dist/browser/modules/pdf/word-bridge.d.ts +80 -12
  34. package/dist/browser/modules/pdf/word-bridge.js +122 -274
  35. package/dist/browser/modules/stream/index.base.d.ts +2 -0
  36. package/dist/browser/modules/stream/index.base.js +2 -1
  37. package/dist/browser/modules/stream/internal/sink-adapter.d.ts +65 -0
  38. package/dist/browser/modules/stream/internal/sink-adapter.js +198 -0
  39. package/dist/browser/modules/stream/pull-stream.d.ts +19 -2
  40. package/dist/browser/modules/stream/pull-stream.js +51 -5
  41. package/dist/browser/modules/stream/types.d.ts +13 -1
  42. package/dist/browser/modules/word/advanced/diff.d.ts +61 -0
  43. package/dist/browser/modules/word/advanced/diff.js +167 -0
  44. package/dist/browser/modules/word/advanced/drawing-shapes.d.ts +269 -0
  45. package/dist/browser/modules/word/advanced/drawing-shapes.js +268 -0
  46. package/dist/browser/modules/word/advanced/field-engine.d.ts +43 -0
  47. package/dist/browser/modules/word/advanced/field-engine.js +1225 -0
  48. package/dist/browser/modules/word/advanced/glossary.d.ts +86 -0
  49. package/dist/browser/modules/word/advanced/glossary.js +79 -0
  50. package/dist/browser/modules/word/advanced/math-convert.d.ts +30 -0
  51. package/dist/browser/modules/word/advanced/math-convert.js +595 -0
  52. package/dist/browser/modules/word/advanced/ole-objects.d.ts +115 -0
  53. package/dist/browser/modules/word/advanced/ole-objects.js +271 -0
  54. package/dist/browser/modules/word/advanced/style-map.d.ts +105 -0
  55. package/dist/browser/modules/word/advanced/style-map.js +322 -0
  56. package/dist/browser/modules/word/advanced/validation.d.ts +56 -0
  57. package/dist/browser/modules/word/advanced/validation.js +1065 -0
  58. package/dist/browser/modules/word/advanced/vba-project.d.ts +91 -0
  59. package/dist/browser/modules/word/advanced/vba-project.js +265 -0
  60. package/dist/browser/modules/word/bridge/excel-bridge.d.ts +127 -0
  61. package/dist/browser/modules/word/bridge/excel-bridge.js +980 -0
  62. package/dist/browser/modules/word/builder/document-handle.d.ts +151 -0
  63. package/dist/browser/modules/word/builder/document-handle.js +664 -0
  64. package/dist/browser/modules/word/builder/paragraph-builders.d.ts +61 -0
  65. package/dist/browser/modules/word/builder/paragraph-builders.js +90 -0
  66. package/dist/browser/modules/word/builder/run-builders.d.ts +374 -0
  67. package/dist/browser/modules/word/builder/run-builders.js +600 -0
  68. package/dist/browser/modules/word/builder/table-builders.d.ts +23 -0
  69. package/dist/browser/modules/word/builder/table-builders.js +45 -0
  70. package/dist/browser/modules/word/constants.d.ts +39 -1
  71. package/dist/browser/modules/word/constants.js +109 -1
  72. package/dist/browser/modules/word/convert/conversion-ir.d.ts +210 -0
  73. package/dist/browser/modules/word/convert/conversion-ir.js +31 -0
  74. package/dist/browser/modules/word/convert/docx-to-semantic.d.ts +39 -0
  75. package/dist/browser/modules/word/convert/docx-to-semantic.js +499 -0
  76. package/dist/browser/modules/word/convert/flat-opc.d.ts +44 -0
  77. package/dist/browser/modules/word/convert/flat-opc.js +385 -0
  78. package/dist/browser/modules/word/convert/html/html-import.d.ts +50 -0
  79. package/dist/browser/modules/word/convert/html/html-import.js +1907 -0
  80. package/dist/{types/modules/word → browser/modules/word/convert/html}/html-renderer.d.ts +14 -1
  81. package/dist/{esm/modules/word → browser/modules/word/convert/html}/html-renderer.js +420 -69
  82. package/dist/browser/modules/word/convert/html/html.d.ts +15 -0
  83. package/dist/browser/modules/word/convert/html/html.js +15 -0
  84. package/dist/browser/modules/word/convert/markdown/markdown-import.d.ts +68 -0
  85. package/dist/browser/modules/word/convert/markdown/markdown-import.js +1325 -0
  86. package/dist/browser/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
  87. package/dist/browser/modules/word/convert/markdown/markdown-renderer.js +634 -0
  88. package/dist/browser/modules/word/convert/markdown/markdown.d.ts +15 -0
  89. package/dist/browser/modules/word/convert/markdown/markdown.js +15 -0
  90. package/dist/browser/modules/word/convert/odt/odt.d.ts +41 -0
  91. package/dist/browser/modules/word/convert/odt/odt.js +1932 -0
  92. package/dist/browser/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
  93. package/dist/browser/modules/word/core/color-utils.js +43 -0
  94. package/dist/browser/modules/word/core/internal-utils.d.ts +90 -0
  95. package/dist/browser/modules/word/core/internal-utils.js +209 -0
  96. package/dist/browser/modules/word/core/mapper.d.ts +44 -0
  97. package/dist/browser/modules/word/core/mapper.js +427 -0
  98. package/dist/browser/modules/word/core/opc-paths.d.ts +33 -0
  99. package/dist/browser/modules/word/core/opc-paths.js +48 -0
  100. package/dist/browser/modules/word/core/text-utils.d.ts +38 -0
  101. package/dist/browser/modules/word/core/text-utils.js +202 -0
  102. package/dist/browser/modules/word/core/walker.d.ts +119 -0
  103. package/dist/browser/modules/word/core/walker.js +570 -0
  104. package/dist/browser/modules/word/crypto.d.ts +14 -9
  105. package/dist/browser/modules/word/crypto.js +13 -7
  106. package/dist/browser/modules/word/document-io.d.ts +59 -27
  107. package/dist/browser/modules/word/document-io.js +80 -197
  108. package/dist/browser/modules/word/errors.d.ts +44 -1
  109. package/dist/browser/modules/word/errors.js +54 -2
  110. package/dist/browser/modules/word/excel.d.ts +14 -0
  111. package/dist/browser/modules/word/excel.js +13 -0
  112. package/dist/browser/modules/word/font/font-embed.d.ts +112 -0
  113. package/dist/browser/modules/word/font/font-embed.js +646 -0
  114. package/dist/{esm/modules/word → browser/modules/word/font}/font-obfuscation.js +4 -9
  115. package/dist/browser/modules/word/font/hyphenation.d.ts +65 -0
  116. package/dist/browser/modules/word/font/hyphenation.js +4210 -0
  117. package/dist/browser/modules/word/font/text-shaping.d.ts +58 -0
  118. package/dist/browser/modules/word/font/text-shaping.js +635 -0
  119. package/dist/browser/modules/word/html.d.ts +7 -6
  120. package/dist/browser/modules/word/html.js +6 -5
  121. package/dist/browser/modules/word/incremental-edit.d.ts +123 -0
  122. package/dist/browser/modules/word/incremental-edit.js +361 -0
  123. package/dist/browser/modules/word/index.base.d.ts +194 -10
  124. package/dist/browser/modules/word/index.base.js +138 -29
  125. package/dist/browser/modules/word/layout/layout-constants.d.ts +17 -0
  126. package/dist/browser/modules/word/layout/layout-constants.js +17 -0
  127. package/dist/browser/modules/word/layout/layout-full.d.ts +53 -0
  128. package/dist/browser/modules/word/layout/layout-full.js +1696 -0
  129. package/dist/browser/modules/word/layout/layout-model.d.ts +344 -0
  130. package/dist/browser/modules/word/layout/layout-model.js +16 -0
  131. package/dist/browser/modules/word/layout/layout.d.ts +63 -0
  132. package/dist/browser/modules/word/layout/layout.js +1167 -0
  133. package/dist/browser/modules/word/layout/render-page.d.ts +57 -0
  134. package/dist/browser/modules/word/layout/render-page.js +1238 -0
  135. package/dist/browser/modules/word/markdown.d.ts +14 -0
  136. package/dist/browser/modules/word/markdown.js +13 -0
  137. package/dist/browser/modules/word/patcher.d.ts +62 -0
  138. package/dist/browser/modules/word/patcher.js +537 -0
  139. package/dist/browser/modules/word/query/compat.d.ts +25 -0
  140. package/dist/browser/modules/word/query/compat.js +58 -0
  141. package/dist/browser/modules/word/query/data-binding.d.ts +22 -0
  142. package/dist/browser/modules/word/query/data-binding.js +392 -0
  143. package/dist/browser/modules/word/query/form-fields.d.ts +41 -0
  144. package/dist/browser/modules/word/query/form-fields.js +268 -0
  145. package/dist/browser/modules/word/query/format-search.d.ts +99 -0
  146. package/dist/browser/modules/word/query/format-search.js +329 -0
  147. package/dist/browser/modules/word/query/mail-merge.d.ts +25 -0
  148. package/dist/browser/modules/word/query/mail-merge.js +111 -0
  149. package/dist/browser/modules/word/query/merge.d.ts +50 -0
  150. package/dist/browser/modules/word/query/merge.js +617 -0
  151. package/dist/browser/modules/word/query/replace.d.ts +47 -0
  152. package/dist/browser/modules/word/query/replace.js +301 -0
  153. package/dist/browser/modules/word/query/revisions.d.ts +67 -0
  154. package/dist/browser/modules/word/query/revisions.js +879 -0
  155. package/dist/browser/modules/word/query/search.d.ts +129 -0
  156. package/dist/browser/modules/word/query/search.js +346 -0
  157. package/dist/browser/modules/word/query/split.d.ts +44 -0
  158. package/dist/browser/modules/word/query/split.js +135 -0
  159. package/dist/browser/modules/word/query/style-resolve.d.ts +104 -0
  160. package/dist/browser/modules/word/query/style-resolve.js +368 -0
  161. package/dist/browser/modules/word/reader/chart-parser.d.ts +20 -0
  162. package/dist/browser/modules/word/reader/chart-parser.js +810 -0
  163. package/dist/browser/modules/word/reader/comments-parser.d.ts +26 -0
  164. package/dist/browser/modules/word/reader/comments-parser.js +92 -0
  165. package/dist/browser/modules/word/reader/doc-props-parsers.d.ts +15 -0
  166. package/dist/browser/modules/word/reader/doc-props-parsers.js +190 -0
  167. package/dist/browser/modules/word/reader/docx-reader.d.ts +27 -0
  168. package/dist/browser/modules/word/reader/docx-reader.js +2557 -0
  169. package/dist/browser/modules/word/reader/drawing-helpers.d.ts +27 -0
  170. package/dist/browser/modules/word/reader/drawing-helpers.js +84 -0
  171. package/dist/browser/modules/word/reader/form-field-parser.d.ts +21 -0
  172. package/dist/browser/modules/word/reader/form-field-parser.js +82 -0
  173. package/dist/browser/modules/word/reader/image-parsers.d.ts +11 -0
  174. package/dist/browser/modules/word/reader/image-parsers.js +291 -0
  175. package/dist/browser/modules/word/reader/math-parser.d.ts +12 -0
  176. package/dist/browser/modules/word/reader/math-parser.js +422 -0
  177. package/dist/browser/modules/word/reader/metadata-parsers.d.ts +17 -0
  178. package/dist/browser/modules/word/reader/metadata-parsers.js +87 -0
  179. package/dist/browser/modules/word/reader/numbering-parser.d.ts +13 -0
  180. package/dist/browser/modules/word/reader/numbering-parser.js +166 -0
  181. package/dist/browser/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
  182. package/dist/browser/modules/word/reader/paragraph-section-parsers.js +503 -0
  183. package/dist/browser/modules/word/reader/parse-utils.d.ts +91 -0
  184. package/dist/browser/modules/word/reader/parse-utils.js +249 -0
  185. package/dist/browser/modules/word/reader/properties-parsers.d.ts +21 -0
  186. package/dist/browser/modules/word/reader/properties-parsers.js +332 -0
  187. package/dist/browser/modules/word/reader/reader-context.d.ts +69 -0
  188. package/dist/browser/modules/word/reader/reader-context.js +61 -0
  189. package/dist/browser/modules/word/reader/sdt-helpers.d.ts +29 -0
  190. package/dist/browser/modules/word/reader/sdt-helpers.js +111 -0
  191. package/dist/browser/modules/word/reader/settings-parser.d.ts +8 -0
  192. package/dist/browser/modules/word/reader/settings-parser.js +263 -0
  193. package/dist/browser/modules/word/reader/styles-parser.d.ts +12 -0
  194. package/dist/browser/modules/word/reader/styles-parser.js +147 -0
  195. package/dist/browser/modules/word/reader/table-properties-parsers.d.ts +12 -0
  196. package/dist/browser/modules/word/reader/table-properties-parsers.js +234 -0
  197. package/dist/browser/modules/word/reader/theme-parser.d.ts +8 -0
  198. package/dist/browser/modules/word/reader/theme-parser.js +167 -0
  199. package/dist/browser/modules/word/reader/watermark-parser.d.ts +15 -0
  200. package/dist/browser/modules/word/reader/watermark-parser.js +110 -0
  201. package/dist/browser/modules/word/security/cfb-reader.d.ts +37 -0
  202. package/dist/browser/modules/word/security/cfb-reader.js +410 -0
  203. package/dist/browser/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
  204. package/dist/browser/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  205. package/dist/browser/modules/word/security/document-protection.d.ts +93 -0
  206. package/dist/browser/modules/word/security/document-protection.js +201 -0
  207. package/dist/{types/modules/word → browser/modules/word/security}/encryption.d.ts +51 -4
  208. package/dist/browser/modules/word/security/encryption.js +602 -0
  209. package/dist/browser/modules/word/security/policy.d.ts +80 -0
  210. package/dist/browser/modules/word/security/policy.js +102 -0
  211. package/dist/browser/modules/word/template/template-chart.d.ts +56 -0
  212. package/dist/browser/modules/word/template/template-chart.js +167 -0
  213. package/dist/browser/modules/word/template/template-datasource.d.ts +154 -0
  214. package/dist/browser/modules/word/template/template-datasource.js +541 -0
  215. package/dist/browser/modules/word/template/template-engine.d.ts +121 -0
  216. package/dist/browser/modules/word/template/template-engine.js +1435 -0
  217. package/dist/browser/modules/word/types.d.ts +224 -25
  218. package/dist/browser/modules/word/units.d.ts +26 -0
  219. package/dist/browser/modules/word/units.js +43 -14
  220. package/dist/browser/modules/word/{writers → writer}/chart-writer.js +164 -23
  221. package/dist/browser/modules/word/writer/checkbox-writer.d.ts +17 -0
  222. package/dist/browser/modules/word/writer/checkbox-writer.js +79 -0
  223. package/dist/{types/modules/word/writers → browser/modules/word/writer}/comment-writer.d.ts +2 -1
  224. package/dist/browser/modules/word/{writers → writer}/comment-writer.js +8 -6
  225. package/dist/browser/modules/word/writer/common-parts.d.ts +57 -0
  226. package/dist/browser/modules/word/writer/common-parts.js +101 -0
  227. package/dist/{types/modules/word → browser/modules/word/writer}/content-types.d.ts +2 -2
  228. package/dist/{esm/modules/word → browser/modules/word/writer}/content-types.js +14 -6
  229. package/dist/browser/modules/word/writer/document-writer.d.ts +24 -0
  230. package/dist/browser/modules/word/writer/document-writer.js +473 -0
  231. package/dist/browser/modules/word/writer/docx-packager.d.ts +35 -0
  232. package/dist/browser/modules/word/writer/docx-packager.js +1515 -0
  233. package/dist/{types/modules/word/writers → browser/modules/word/writer}/footnote-writer.d.ts +3 -2
  234. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/footnote-writer.js +13 -10
  235. package/dist/{types/modules/word/writers → browser/modules/word/writer}/header-footer-writer.d.ts +3 -2
  236. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/header-footer-writer.js +39 -21
  237. package/dist/{types/modules/word/writers → browser/modules/word/writer}/image-writer.d.ts +1 -1
  238. package/dist/browser/modules/word/{writers → writer}/image-writer.js +11 -7
  239. package/dist/browser/modules/word/writer/math-writer.d.ts +20 -0
  240. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/math-writer.js +21 -1
  241. package/dist/browser/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
  242. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/numbering-writer.js +11 -4
  243. package/dist/browser/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
  244. package/dist/browser/modules/word/{writers → writer}/paragraph-writer.js +73 -38
  245. package/dist/browser/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
  246. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/parts-writer.js +91 -12
  247. package/dist/browser/modules/word/writer/reference-scanners.d.ts +42 -0
  248. package/dist/browser/modules/word/writer/reference-scanners.js +111 -0
  249. package/dist/browser/modules/word/writer/relationships.d.ts +52 -0
  250. package/dist/browser/modules/word/writer/relationships.js +117 -0
  251. package/dist/browser/modules/word/writer/render-context.d.ts +124 -0
  252. package/dist/browser/modules/word/writer/render-context.js +46 -0
  253. package/dist/browser/modules/word/{writers → writer}/run-writer.d.ts +10 -1
  254. package/dist/{esm/modules/word/writers → browser/modules/word/writer}/run-writer.js +126 -24
  255. package/dist/browser/modules/word/writer/sdt-writer.d.ts +25 -0
  256. package/dist/browser/modules/word/writer/sdt-writer.js +189 -0
  257. package/dist/browser/modules/word/writer/stream-buf.d.ts +37 -0
  258. package/dist/browser/modules/word/writer/stream-buf.js +73 -0
  259. package/dist/browser/modules/word/writer/streaming-writer.d.ts +344 -0
  260. package/dist/browser/modules/word/writer/streaming-writer.js +1382 -0
  261. package/dist/browser/modules/word/writer/string-buf.d.ts +8 -0
  262. package/dist/browser/modules/word/writer/string-buf.js +7 -0
  263. package/dist/browser/modules/word/{writers → writer}/styles-writer.js +32 -1
  264. package/dist/browser/modules/word/{writers → writer}/table-writer.d.ts +2 -1
  265. package/dist/browser/modules/word/{writers → writer}/table-writer.js +94 -11
  266. package/dist/browser/modules/xml/types.d.ts +22 -0
  267. package/dist/browser/utils/crypto.browser.d.ts +3 -1
  268. package/dist/browser/utils/crypto.browser.js +3 -1
  269. package/dist/browser/utils/crypto.d.ts +4 -1
  270. package/dist/browser/utils/crypto.js +4 -1
  271. package/dist/browser/utils/font-metrics.d.ts +63 -0
  272. package/dist/browser/utils/font-metrics.js +293 -0
  273. package/dist/browser/utils/string-buf.d.ts +42 -0
  274. package/dist/browser/utils/string-buf.js +89 -0
  275. package/dist/browser/utils/theme-colors.d.ts +55 -0
  276. package/dist/browser/utils/theme-colors.js +120 -0
  277. package/dist/cjs/modules/archive/compression/streaming-compress.browser.js +29 -0
  278. package/dist/cjs/modules/archive/compression/streaming-compress.js +9 -0
  279. package/dist/cjs/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  280. package/dist/cjs/modules/archive/fs/archive-file.js +78 -16
  281. package/dist/cjs/modules/archive/unzip/stream.browser.js +43 -2
  282. package/dist/cjs/modules/excel/chart/chart-ex-builder.js +7 -2
  283. package/dist/cjs/modules/excel/chart/chart-ex-renderer.js +4 -9
  284. package/dist/cjs/modules/excel/chart/chart.js +1 -7
  285. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +25 -1
  286. package/dist/cjs/modules/excel/stream/workbook-reader.js +9 -0
  287. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +228 -13
  288. package/dist/cjs/modules/excel/utils/string-buf.js +5 -81
  289. package/dist/cjs/modules/excel/workbook.browser.js +135 -25
  290. package/dist/cjs/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  291. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +32 -8
  292. package/dist/cjs/modules/excel/xlsx/xlsx.js +9 -1
  293. package/dist/cjs/modules/pdf/excel-bridge.js +33 -0
  294. package/dist/cjs/modules/pdf/font/metrics.js +11 -244
  295. package/dist/cjs/modules/pdf/index.js +2 -1
  296. package/dist/cjs/modules/pdf/render-layout-to-pdf.js +651 -0
  297. package/dist/cjs/modules/pdf/word-bridge.js +155 -274
  298. package/dist/cjs/modules/stream/index.base.js +4 -2
  299. package/dist/cjs/modules/stream/internal/sink-adapter.js +202 -0
  300. package/dist/cjs/modules/stream/pull-stream.js +51 -5
  301. package/dist/cjs/modules/word/advanced/diff.js +170 -0
  302. package/dist/cjs/modules/word/advanced/drawing-shapes.js +279 -0
  303. package/dist/cjs/modules/word/advanced/field-engine.js +1229 -0
  304. package/dist/cjs/modules/word/advanced/glossary.js +87 -0
  305. package/dist/cjs/modules/word/advanced/math-convert.js +599 -0
  306. package/dist/cjs/modules/word/advanced/ole-objects.js +277 -0
  307. package/dist/cjs/modules/word/advanced/style-map.js +329 -0
  308. package/dist/cjs/modules/word/advanced/validation.js +1068 -0
  309. package/dist/cjs/modules/word/advanced/vba-project.js +274 -0
  310. package/dist/cjs/modules/word/bridge/excel-bridge.js +1020 -0
  311. package/dist/cjs/modules/word/builder/document-handle.js +667 -0
  312. package/dist/cjs/modules/word/builder/paragraph-builders.js +109 -0
  313. package/dist/cjs/modules/word/builder/run-builders.js +676 -0
  314. package/dist/cjs/modules/word/builder/table-builders.js +53 -0
  315. package/dist/cjs/modules/word/constants.js +111 -2
  316. package/dist/cjs/modules/word/convert/conversion-ir.js +34 -0
  317. package/dist/cjs/modules/word/convert/docx-to-semantic.js +502 -0
  318. package/dist/cjs/modules/word/convert/flat-opc.js +390 -0
  319. package/dist/cjs/modules/word/convert/html/html-import.js +1910 -0
  320. package/dist/cjs/modules/word/{html-renderer.js → convert/html/html-renderer.js} +420 -69
  321. package/dist/cjs/modules/word/convert/html/html.js +20 -0
  322. package/dist/cjs/modules/word/convert/markdown/markdown-import.js +1329 -0
  323. package/dist/cjs/modules/word/convert/markdown/markdown-renderer.js +637 -0
  324. package/dist/cjs/modules/word/convert/markdown/markdown.js +21 -0
  325. package/dist/cjs/modules/word/convert/odt/odt.js +1936 -0
  326. package/dist/cjs/modules/word/core/color-utils.js +47 -0
  327. package/dist/cjs/modules/word/core/internal-utils.js +219 -0
  328. package/dist/cjs/modules/word/core/mapper.js +430 -0
  329. package/dist/cjs/modules/word/core/opc-paths.js +53 -0
  330. package/dist/cjs/modules/word/core/text-utils.js +210 -0
  331. package/dist/cjs/modules/word/core/walker.js +577 -0
  332. package/dist/cjs/modules/word/crypto.js +19 -8
  333. package/dist/cjs/modules/word/document-io.js +117 -197
  334. package/dist/cjs/modules/word/errors.js +59 -13
  335. package/dist/cjs/modules/word/excel.js +22 -0
  336. package/dist/cjs/modules/word/font/font-embed.js +652 -0
  337. package/dist/cjs/modules/word/{font-obfuscation.js → font/font-obfuscation.js} +4 -9
  338. package/dist/cjs/modules/word/font/hyphenation.js +4216 -0
  339. package/dist/cjs/modules/word/font/text-shaping.js +640 -0
  340. package/dist/cjs/modules/word/html.js +9 -7
  341. package/dist/cjs/modules/word/incremental-edit.js +366 -0
  342. package/dist/cjs/modules/word/index.base.js +370 -137
  343. package/dist/cjs/modules/word/layout/layout-constants.js +20 -0
  344. package/dist/cjs/modules/word/layout/layout-full.js +1699 -0
  345. package/dist/cjs/modules/word/layout/layout-model.js +17 -0
  346. package/dist/cjs/modules/word/layout/layout.js +1170 -0
  347. package/dist/cjs/modules/word/layout/render-page.js +1243 -0
  348. package/dist/cjs/modules/word/markdown.js +19 -0
  349. package/dist/cjs/modules/word/patcher.js +539 -0
  350. package/dist/cjs/modules/word/query/compat.js +61 -0
  351. package/dist/cjs/modules/word/query/data-binding.js +395 -0
  352. package/dist/cjs/modules/word/query/form-fields.js +272 -0
  353. package/dist/cjs/modules/word/query/format-search.js +334 -0
  354. package/dist/cjs/modules/word/query/mail-merge.js +114 -0
  355. package/dist/cjs/modules/word/query/merge.js +620 -0
  356. package/dist/cjs/modules/word/query/replace.js +304 -0
  357. package/dist/cjs/modules/word/query/revisions.js +885 -0
  358. package/dist/cjs/modules/word/query/search.js +361 -0
  359. package/dist/cjs/modules/word/query/split.js +138 -0
  360. package/dist/cjs/modules/word/query/style-resolve.js +374 -0
  361. package/dist/cjs/modules/word/reader/chart-parser.js +814 -0
  362. package/dist/cjs/modules/word/reader/comments-parser.js +96 -0
  363. package/dist/cjs/modules/word/reader/doc-props-parsers.js +194 -0
  364. package/dist/cjs/modules/word/reader/docx-reader.js +2560 -0
  365. package/dist/cjs/modules/word/reader/drawing-helpers.js +90 -0
  366. package/dist/cjs/modules/word/reader/form-field-parser.js +85 -0
  367. package/dist/cjs/modules/word/reader/image-parsers.js +293 -0
  368. package/dist/cjs/modules/word/reader/math-parser.js +424 -0
  369. package/dist/cjs/modules/word/reader/metadata-parsers.js +93 -0
  370. package/dist/cjs/modules/word/reader/numbering-parser.js +168 -0
  371. package/dist/cjs/modules/word/reader/paragraph-section-parsers.js +505 -0
  372. package/dist/cjs/modules/word/reader/parse-utils.js +271 -0
  373. package/dist/cjs/modules/word/reader/properties-parsers.js +338 -0
  374. package/dist/cjs/modules/word/reader/reader-context.js +66 -0
  375. package/dist/cjs/modules/word/reader/sdt-helpers.js +114 -0
  376. package/dist/cjs/modules/word/reader/settings-parser.js +265 -0
  377. package/dist/cjs/modules/word/reader/styles-parser.js +149 -0
  378. package/dist/cjs/modules/word/reader/table-properties-parsers.js +237 -0
  379. package/dist/cjs/modules/word/reader/theme-parser.js +169 -0
  380. package/dist/cjs/modules/word/reader/watermark-parser.js +113 -0
  381. package/dist/cjs/modules/word/security/cfb-reader.js +414 -0
  382. package/dist/cjs/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  383. package/dist/cjs/modules/word/security/document-protection.js +208 -0
  384. package/dist/cjs/modules/word/security/encryption.js +612 -0
  385. package/dist/cjs/modules/word/security/policy.js +106 -0
  386. package/dist/cjs/modules/word/template/template-chart.js +170 -0
  387. package/dist/cjs/modules/word/template/template-datasource.js +549 -0
  388. package/dist/cjs/modules/word/template/template-engine.js +1430 -0
  389. package/dist/cjs/modules/word/units.js +44 -14
  390. package/dist/cjs/modules/word/{writers → writer}/chart-writer.js +163 -22
  391. package/dist/cjs/modules/word/writer/checkbox-writer.js +82 -0
  392. package/dist/cjs/modules/word/{writers → writer}/comment-writer.js +8 -6
  393. package/dist/cjs/modules/word/writer/common-parts.js +104 -0
  394. package/dist/cjs/modules/word/{content-types.js → writer/content-types.js} +14 -6
  395. package/dist/cjs/modules/word/writer/document-writer.js +478 -0
  396. package/dist/cjs/modules/word/writer/docx-packager.js +1551 -0
  397. package/dist/cjs/modules/word/{writers → writer}/footnote-writer.js +13 -10
  398. package/dist/cjs/modules/word/{writers → writer}/header-footer-writer.js +38 -20
  399. package/dist/cjs/modules/word/{writers → writer}/image-writer.js +11 -7
  400. package/dist/cjs/modules/word/{writers → writer}/math-writer.js +21 -1
  401. package/dist/cjs/modules/word/{writers → writer}/numbering-writer.js +11 -4
  402. package/dist/cjs/modules/word/{writers → writer}/paragraph-writer.js +72 -37
  403. package/dist/cjs/modules/word/{writers → writer}/parts-writer.js +91 -12
  404. package/dist/cjs/modules/word/writer/reference-scanners.js +120 -0
  405. package/dist/cjs/modules/word/writer/relationships.js +124 -0
  406. package/dist/cjs/modules/word/writer/render-context.js +51 -0
  407. package/dist/cjs/modules/word/{writers → writer}/run-writer.js +127 -24
  408. package/dist/cjs/modules/word/writer/sdt-writer.js +192 -0
  409. package/dist/cjs/modules/word/writer/stream-buf.js +76 -0
  410. package/dist/cjs/modules/word/writer/streaming-writer.js +1387 -0
  411. package/dist/cjs/modules/word/writer/string-buf.js +11 -0
  412. package/dist/cjs/modules/word/{writers → writer}/styles-writer.js +32 -1
  413. package/dist/cjs/modules/word/{writers → writer}/table-writer.js +94 -11
  414. package/dist/cjs/utils/crypto.browser.js +3 -1
  415. package/dist/cjs/utils/crypto.js +4 -1
  416. package/dist/cjs/utils/font-metrics.js +303 -0
  417. package/dist/cjs/utils/string-buf.js +92 -0
  418. package/dist/cjs/utils/theme-colors.js +126 -0
  419. package/dist/esm/modules/archive/compression/streaming-compress.browser.js +29 -0
  420. package/dist/esm/modules/archive/compression/streaming-compress.js +9 -0
  421. package/dist/esm/modules/archive/compression/worker-pool/pool.browser.js +26 -1
  422. package/dist/esm/modules/archive/fs/archive-file.js +78 -16
  423. package/dist/esm/modules/archive/unzip/stream.browser.js +43 -2
  424. package/dist/esm/modules/excel/chart/chart-ex-builder.js +7 -2
  425. package/dist/esm/modules/excel/chart/chart-ex-renderer.js +4 -9
  426. package/dist/esm/modules/excel/chart/chart.js +1 -7
  427. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +25 -1
  428. package/dist/esm/modules/excel/stream/workbook-reader.js +9 -0
  429. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +228 -13
  430. package/dist/esm/modules/excel/utils/string-buf.js +4 -81
  431. package/dist/esm/modules/excel/workbook.browser.js +135 -25
  432. package/dist/esm/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
  433. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +32 -8
  434. package/dist/esm/modules/excel/xlsx/xlsx.js +9 -1
  435. package/dist/esm/modules/pdf/excel-bridge.js +32 -0
  436. package/dist/esm/modules/pdf/font/metrics.js +3 -237
  437. package/dist/esm/modules/pdf/index.js +1 -1
  438. package/dist/esm/modules/pdf/render-layout-to-pdf.js +647 -0
  439. package/dist/esm/modules/pdf/word-bridge.js +122 -274
  440. package/dist/esm/modules/stream/index.base.js +2 -1
  441. package/dist/esm/modules/stream/internal/sink-adapter.js +198 -0
  442. package/dist/esm/modules/stream/pull-stream.js +51 -5
  443. package/dist/esm/modules/word/advanced/diff.js +167 -0
  444. package/dist/esm/modules/word/advanced/drawing-shapes.js +268 -0
  445. package/dist/esm/modules/word/advanced/field-engine.js +1225 -0
  446. package/dist/esm/modules/word/advanced/glossary.js +79 -0
  447. package/dist/esm/modules/word/advanced/math-convert.js +595 -0
  448. package/dist/esm/modules/word/advanced/ole-objects.js +271 -0
  449. package/dist/esm/modules/word/advanced/style-map.js +322 -0
  450. package/dist/esm/modules/word/advanced/validation.js +1065 -0
  451. package/dist/esm/modules/word/advanced/vba-project.js +265 -0
  452. package/dist/esm/modules/word/bridge/excel-bridge.js +980 -0
  453. package/dist/esm/modules/word/builder/document-handle.js +664 -0
  454. package/dist/esm/modules/word/builder/paragraph-builders.js +90 -0
  455. package/dist/esm/modules/word/builder/run-builders.js +600 -0
  456. package/dist/esm/modules/word/builder/table-builders.js +45 -0
  457. package/dist/esm/modules/word/constants.js +109 -1
  458. package/dist/esm/modules/word/convert/conversion-ir.js +31 -0
  459. package/dist/esm/modules/word/convert/docx-to-semantic.js +499 -0
  460. package/dist/esm/modules/word/convert/flat-opc.js +385 -0
  461. package/dist/esm/modules/word/convert/html/html-import.js +1907 -0
  462. package/dist/{browser/modules/word → esm/modules/word/convert/html}/html-renderer.js +420 -69
  463. package/dist/esm/modules/word/convert/html/html.js +15 -0
  464. package/dist/esm/modules/word/convert/markdown/markdown-import.js +1325 -0
  465. package/dist/esm/modules/word/convert/markdown/markdown-renderer.js +634 -0
  466. package/dist/esm/modules/word/convert/markdown/markdown.js +15 -0
  467. package/dist/esm/modules/word/convert/odt/odt.js +1932 -0
  468. package/dist/esm/modules/word/core/color-utils.js +43 -0
  469. package/dist/esm/modules/word/core/internal-utils.js +209 -0
  470. package/dist/esm/modules/word/core/mapper.js +427 -0
  471. package/dist/esm/modules/word/core/opc-paths.js +48 -0
  472. package/dist/esm/modules/word/core/text-utils.js +202 -0
  473. package/dist/esm/modules/word/core/walker.js +570 -0
  474. package/dist/esm/modules/word/crypto.js +13 -7
  475. package/dist/esm/modules/word/document-io.js +80 -197
  476. package/dist/esm/modules/word/errors.js +54 -2
  477. package/dist/esm/modules/word/excel.js +13 -0
  478. package/dist/esm/modules/word/font/font-embed.js +646 -0
  479. package/dist/{browser/modules/word → esm/modules/word/font}/font-obfuscation.js +4 -9
  480. package/dist/esm/modules/word/font/hyphenation.js +4210 -0
  481. package/dist/esm/modules/word/font/text-shaping.js +635 -0
  482. package/dist/esm/modules/word/html.js +6 -5
  483. package/dist/esm/modules/word/incremental-edit.js +361 -0
  484. package/dist/esm/modules/word/index.base.js +138 -29
  485. package/dist/esm/modules/word/layout/layout-constants.js +17 -0
  486. package/dist/esm/modules/word/layout/layout-full.js +1696 -0
  487. package/dist/esm/modules/word/layout/layout-model.js +16 -0
  488. package/dist/esm/modules/word/layout/layout.js +1167 -0
  489. package/dist/esm/modules/word/layout/render-page.js +1238 -0
  490. package/dist/esm/modules/word/markdown.js +13 -0
  491. package/dist/esm/modules/word/patcher.js +537 -0
  492. package/dist/esm/modules/word/query/compat.js +58 -0
  493. package/dist/esm/modules/word/query/data-binding.js +392 -0
  494. package/dist/esm/modules/word/query/form-fields.js +268 -0
  495. package/dist/esm/modules/word/query/format-search.js +329 -0
  496. package/dist/esm/modules/word/query/mail-merge.js +111 -0
  497. package/dist/esm/modules/word/query/merge.js +617 -0
  498. package/dist/esm/modules/word/query/replace.js +301 -0
  499. package/dist/esm/modules/word/query/revisions.js +879 -0
  500. package/dist/esm/modules/word/query/search.js +346 -0
  501. package/dist/esm/modules/word/query/split.js +135 -0
  502. package/dist/esm/modules/word/query/style-resolve.js +368 -0
  503. package/dist/esm/modules/word/reader/chart-parser.js +810 -0
  504. package/dist/esm/modules/word/reader/comments-parser.js +92 -0
  505. package/dist/esm/modules/word/reader/doc-props-parsers.js +190 -0
  506. package/dist/esm/modules/word/reader/docx-reader.js +2557 -0
  507. package/dist/esm/modules/word/reader/drawing-helpers.js +84 -0
  508. package/dist/esm/modules/word/reader/form-field-parser.js +82 -0
  509. package/dist/esm/modules/word/reader/image-parsers.js +291 -0
  510. package/dist/esm/modules/word/reader/math-parser.js +422 -0
  511. package/dist/esm/modules/word/reader/metadata-parsers.js +87 -0
  512. package/dist/esm/modules/word/reader/numbering-parser.js +166 -0
  513. package/dist/esm/modules/word/reader/paragraph-section-parsers.js +503 -0
  514. package/dist/esm/modules/word/reader/parse-utils.js +249 -0
  515. package/dist/esm/modules/word/reader/properties-parsers.js +332 -0
  516. package/dist/esm/modules/word/reader/reader-context.js +61 -0
  517. package/dist/esm/modules/word/reader/sdt-helpers.js +111 -0
  518. package/dist/esm/modules/word/reader/settings-parser.js +263 -0
  519. package/dist/esm/modules/word/reader/styles-parser.js +147 -0
  520. package/dist/esm/modules/word/reader/table-properties-parsers.js +234 -0
  521. package/dist/esm/modules/word/reader/theme-parser.js +167 -0
  522. package/dist/esm/modules/word/reader/watermark-parser.js +110 -0
  523. package/dist/esm/modules/word/security/cfb-reader.js +410 -0
  524. package/dist/esm/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
  525. package/dist/esm/modules/word/security/document-protection.js +201 -0
  526. package/dist/esm/modules/word/security/encryption.js +602 -0
  527. package/dist/esm/modules/word/security/policy.js +102 -0
  528. package/dist/esm/modules/word/template/template-chart.js +167 -0
  529. package/dist/esm/modules/word/template/template-datasource.js +541 -0
  530. package/dist/esm/modules/word/template/template-engine.js +1435 -0
  531. package/dist/esm/modules/word/units.js +43 -14
  532. package/dist/esm/modules/word/{writers → writer}/chart-writer.js +164 -23
  533. package/dist/esm/modules/word/writer/checkbox-writer.js +79 -0
  534. package/dist/esm/modules/word/{writers → writer}/comment-writer.js +8 -6
  535. package/dist/esm/modules/word/writer/common-parts.js +101 -0
  536. package/dist/{browser/modules/word → esm/modules/word/writer}/content-types.js +14 -6
  537. package/dist/esm/modules/word/writer/document-writer.js +473 -0
  538. package/dist/esm/modules/word/writer/docx-packager.js +1515 -0
  539. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/footnote-writer.js +13 -10
  540. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/header-footer-writer.js +39 -21
  541. package/dist/esm/modules/word/{writers → writer}/image-writer.js +11 -7
  542. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/math-writer.js +21 -1
  543. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/numbering-writer.js +11 -4
  544. package/dist/esm/modules/word/{writers → writer}/paragraph-writer.js +73 -38
  545. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/parts-writer.js +91 -12
  546. package/dist/esm/modules/word/writer/reference-scanners.js +111 -0
  547. package/dist/esm/modules/word/writer/relationships.js +117 -0
  548. package/dist/esm/modules/word/writer/render-context.js +46 -0
  549. package/dist/{browser/modules/word/writers → esm/modules/word/writer}/run-writer.js +126 -24
  550. package/dist/esm/modules/word/writer/sdt-writer.js +189 -0
  551. package/dist/esm/modules/word/writer/stream-buf.js +73 -0
  552. package/dist/esm/modules/word/writer/streaming-writer.js +1382 -0
  553. package/dist/esm/modules/word/writer/string-buf.js +7 -0
  554. package/dist/esm/modules/word/{writers → writer}/styles-writer.js +32 -1
  555. package/dist/esm/modules/word/{writers → writer}/table-writer.js +94 -11
  556. package/dist/esm/utils/crypto.browser.js +3 -1
  557. package/dist/esm/utils/crypto.js +4 -1
  558. package/dist/esm/utils/font-metrics.js +293 -0
  559. package/dist/esm/utils/string-buf.js +89 -0
  560. package/dist/esm/utils/theme-colors.js +120 -0
  561. package/dist/iife/excelts.iife.js +70692 -70337
  562. package/dist/iife/excelts.iife.js.map +1 -1
  563. package/dist/iife/excelts.iife.min.js +57 -57
  564. package/dist/types/modules/archive/fs/archive-file.d.ts +8 -5
  565. package/dist/types/modules/excel/chart/chart-ex-types.d.ts +0 -12
  566. package/dist/types/modules/excel/chart/chart.d.ts +1 -5
  567. package/dist/types/modules/excel/chart/types.d.ts +0 -6
  568. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
  569. package/dist/types/modules/excel/utils/string-buf.d.ts +5 -26
  570. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
  571. package/dist/types/modules/excel/xlsx/xlsx.d.ts +10 -2
  572. package/dist/types/modules/pdf/excel-bridge.d.ts +30 -1
  573. package/dist/types/modules/pdf/font/metrics.d.ts +3 -52
  574. package/dist/types/modules/pdf/index.d.ts +1 -1
  575. package/dist/types/modules/pdf/render-layout-to-pdf.d.ts +66 -0
  576. package/dist/types/modules/pdf/word-bridge.d.ts +80 -12
  577. package/dist/types/modules/stream/index.base.d.ts +2 -0
  578. package/dist/types/modules/stream/internal/sink-adapter.d.ts +65 -0
  579. package/dist/types/modules/stream/pull-stream.d.ts +19 -2
  580. package/dist/types/modules/stream/types.d.ts +13 -1
  581. package/dist/types/modules/word/advanced/diff.d.ts +61 -0
  582. package/dist/types/modules/word/advanced/drawing-shapes.d.ts +269 -0
  583. package/dist/types/modules/word/advanced/field-engine.d.ts +43 -0
  584. package/dist/types/modules/word/advanced/glossary.d.ts +86 -0
  585. package/dist/types/modules/word/advanced/math-convert.d.ts +30 -0
  586. package/dist/types/modules/word/advanced/ole-objects.d.ts +115 -0
  587. package/dist/types/modules/word/advanced/style-map.d.ts +105 -0
  588. package/dist/types/modules/word/advanced/validation.d.ts +56 -0
  589. package/dist/types/modules/word/advanced/vba-project.d.ts +91 -0
  590. package/dist/types/modules/word/bridge/excel-bridge.d.ts +127 -0
  591. package/dist/types/modules/word/builder/document-handle.d.ts +151 -0
  592. package/dist/types/modules/word/builder/paragraph-builders.d.ts +61 -0
  593. package/dist/types/modules/word/builder/run-builders.d.ts +374 -0
  594. package/dist/types/modules/word/builder/table-builders.d.ts +23 -0
  595. package/dist/types/modules/word/constants.d.ts +39 -1
  596. package/dist/types/modules/word/convert/conversion-ir.d.ts +210 -0
  597. package/dist/types/modules/word/convert/docx-to-semantic.d.ts +39 -0
  598. package/dist/types/modules/word/convert/flat-opc.d.ts +44 -0
  599. package/dist/types/modules/word/convert/html/html-import.d.ts +50 -0
  600. package/dist/{browser/modules/word → types/modules/word/convert/html}/html-renderer.d.ts +14 -1
  601. package/dist/types/modules/word/convert/html/html.d.ts +15 -0
  602. package/dist/types/modules/word/convert/markdown/markdown-import.d.ts +68 -0
  603. package/dist/types/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
  604. package/dist/types/modules/word/convert/markdown/markdown.d.ts +15 -0
  605. package/dist/types/modules/word/convert/odt/odt.d.ts +41 -0
  606. package/dist/types/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
  607. package/dist/types/modules/word/core/internal-utils.d.ts +90 -0
  608. package/dist/types/modules/word/core/mapper.d.ts +44 -0
  609. package/dist/types/modules/word/core/opc-paths.d.ts +33 -0
  610. package/dist/types/modules/word/core/text-utils.d.ts +38 -0
  611. package/dist/types/modules/word/core/walker.d.ts +119 -0
  612. package/dist/types/modules/word/crypto.d.ts +14 -9
  613. package/dist/types/modules/word/document-io.d.ts +59 -27
  614. package/dist/types/modules/word/errors.d.ts +44 -1
  615. package/dist/types/modules/word/excel.d.ts +14 -0
  616. package/dist/types/modules/word/font/font-embed.d.ts +112 -0
  617. package/dist/types/modules/word/font/hyphenation.d.ts +65 -0
  618. package/dist/types/modules/word/font/text-shaping.d.ts +58 -0
  619. package/dist/types/modules/word/html.d.ts +7 -6
  620. package/dist/types/modules/word/incremental-edit.d.ts +123 -0
  621. package/dist/types/modules/word/index.base.d.ts +194 -10
  622. package/dist/types/modules/word/layout/layout-constants.d.ts +17 -0
  623. package/dist/types/modules/word/layout/layout-full.d.ts +53 -0
  624. package/dist/types/modules/word/layout/layout-model.d.ts +344 -0
  625. package/dist/types/modules/word/layout/layout.d.ts +63 -0
  626. package/dist/types/modules/word/layout/render-page.d.ts +57 -0
  627. package/dist/types/modules/word/markdown.d.ts +14 -0
  628. package/dist/types/modules/word/patcher.d.ts +62 -0
  629. package/dist/types/modules/word/query/compat.d.ts +25 -0
  630. package/dist/types/modules/word/query/data-binding.d.ts +22 -0
  631. package/dist/types/modules/word/query/form-fields.d.ts +41 -0
  632. package/dist/types/modules/word/query/format-search.d.ts +99 -0
  633. package/dist/types/modules/word/query/mail-merge.d.ts +25 -0
  634. package/dist/types/modules/word/query/merge.d.ts +50 -0
  635. package/dist/types/modules/word/query/replace.d.ts +47 -0
  636. package/dist/types/modules/word/query/revisions.d.ts +67 -0
  637. package/dist/types/modules/word/query/search.d.ts +129 -0
  638. package/dist/types/modules/word/query/split.d.ts +44 -0
  639. package/dist/types/modules/word/query/style-resolve.d.ts +104 -0
  640. package/dist/types/modules/word/reader/chart-parser.d.ts +20 -0
  641. package/dist/types/modules/word/reader/comments-parser.d.ts +26 -0
  642. package/dist/types/modules/word/reader/doc-props-parsers.d.ts +15 -0
  643. package/dist/types/modules/word/reader/docx-reader.d.ts +27 -0
  644. package/dist/types/modules/word/reader/drawing-helpers.d.ts +27 -0
  645. package/dist/types/modules/word/reader/form-field-parser.d.ts +21 -0
  646. package/dist/types/modules/word/reader/image-parsers.d.ts +11 -0
  647. package/dist/types/modules/word/reader/math-parser.d.ts +12 -0
  648. package/dist/types/modules/word/reader/metadata-parsers.d.ts +17 -0
  649. package/dist/types/modules/word/reader/numbering-parser.d.ts +13 -0
  650. package/dist/types/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
  651. package/dist/types/modules/word/reader/parse-utils.d.ts +91 -0
  652. package/dist/types/modules/word/reader/properties-parsers.d.ts +21 -0
  653. package/dist/types/modules/word/reader/reader-context.d.ts +69 -0
  654. package/dist/types/modules/word/reader/sdt-helpers.d.ts +29 -0
  655. package/dist/types/modules/word/reader/settings-parser.d.ts +8 -0
  656. package/dist/types/modules/word/reader/styles-parser.d.ts +12 -0
  657. package/dist/types/modules/word/reader/table-properties-parsers.d.ts +12 -0
  658. package/dist/types/modules/word/reader/theme-parser.d.ts +8 -0
  659. package/dist/types/modules/word/reader/watermark-parser.d.ts +15 -0
  660. package/dist/types/modules/word/security/cfb-reader.d.ts +37 -0
  661. package/dist/types/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
  662. package/dist/types/modules/word/security/document-protection.d.ts +93 -0
  663. package/dist/{browser/modules/word → types/modules/word/security}/encryption.d.ts +51 -4
  664. package/dist/types/modules/word/security/policy.d.ts +80 -0
  665. package/dist/types/modules/word/template/template-chart.d.ts +56 -0
  666. package/dist/types/modules/word/template/template-datasource.d.ts +154 -0
  667. package/dist/types/modules/word/template/template-engine.d.ts +121 -0
  668. package/dist/types/modules/word/types.d.ts +224 -25
  669. package/dist/types/modules/word/units.d.ts +26 -0
  670. package/dist/types/modules/word/writer/checkbox-writer.d.ts +17 -0
  671. package/dist/{browser/modules/word/writers → types/modules/word/writer}/comment-writer.d.ts +2 -1
  672. package/dist/types/modules/word/writer/common-parts.d.ts +57 -0
  673. package/dist/{browser/modules/word → types/modules/word/writer}/content-types.d.ts +2 -2
  674. package/dist/types/modules/word/writer/document-writer.d.ts +24 -0
  675. package/dist/types/modules/word/writer/docx-packager.d.ts +35 -0
  676. package/dist/{browser/modules/word/writers → types/modules/word/writer}/footnote-writer.d.ts +3 -2
  677. package/dist/{browser/modules/word/writers → types/modules/word/writer}/header-footer-writer.d.ts +3 -2
  678. package/dist/{browser/modules/word/writers → types/modules/word/writer}/image-writer.d.ts +1 -1
  679. package/dist/types/modules/word/writer/math-writer.d.ts +20 -0
  680. package/dist/types/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
  681. package/dist/types/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
  682. package/dist/types/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
  683. package/dist/types/modules/word/writer/reference-scanners.d.ts +42 -0
  684. package/dist/types/modules/word/writer/relationships.d.ts +52 -0
  685. package/dist/types/modules/word/writer/render-context.d.ts +124 -0
  686. package/dist/types/modules/word/{writers → writer}/run-writer.d.ts +10 -1
  687. package/dist/types/modules/word/writer/sdt-writer.d.ts +25 -0
  688. package/dist/types/modules/word/writer/stream-buf.d.ts +37 -0
  689. package/dist/types/modules/word/writer/streaming-writer.d.ts +344 -0
  690. package/dist/types/modules/word/writer/string-buf.d.ts +8 -0
  691. package/dist/types/modules/word/{writers → writer}/table-writer.d.ts +2 -1
  692. package/dist/types/modules/xml/types.d.ts +22 -0
  693. package/dist/types/utils/crypto.browser.d.ts +3 -1
  694. package/dist/types/utils/crypto.d.ts +4 -1
  695. package/dist/types/utils/font-metrics.d.ts +63 -0
  696. package/dist/types/utils/string-buf.d.ts +42 -0
  697. package/dist/types/utils/theme-colors.d.ts +55 -0
  698. package/package.json +121 -39
  699. package/dist/browser/modules/word/color-utils.js +0 -94
  700. package/dist/browser/modules/word/document.d.ts +0 -657
  701. package/dist/browser/modules/word/document.js +0 -1533
  702. package/dist/browser/modules/word/docx-packager.d.ts +0 -14
  703. package/dist/browser/modules/word/docx-packager.js +0 -822
  704. package/dist/browser/modules/word/docx-reader.d.ts +0 -11
  705. package/dist/browser/modules/word/docx-reader.js +0 -4929
  706. package/dist/browser/modules/word/encryption.js +0 -274
  707. package/dist/browser/modules/word/internal-utils.d.ts +0 -23
  708. package/dist/browser/modules/word/internal-utils.js +0 -54
  709. package/dist/browser/modules/word/namespaces.d.ts +0 -159
  710. package/dist/browser/modules/word/namespaces.js +0 -189
  711. package/dist/browser/modules/word/relationships.d.ts +0 -30
  712. package/dist/browser/modules/word/relationships.js +0 -48
  713. package/dist/browser/modules/word/writers/checkbox-writer.d.ts +0 -9
  714. package/dist/browser/modules/word/writers/checkbox-writer.js +0 -42
  715. package/dist/browser/modules/word/writers/document-writer.d.ts +0 -16
  716. package/dist/browser/modules/word/writers/document-writer.js +0 -461
  717. package/dist/browser/modules/word/writers/math-writer.d.ts +0 -9
  718. package/dist/cjs/modules/word/color-utils.js +0 -97
  719. package/dist/cjs/modules/word/document.js +0 -1645
  720. package/dist/cjs/modules/word/docx-packager.js +0 -825
  721. package/dist/cjs/modules/word/docx-reader.js +0 -4932
  722. package/dist/cjs/modules/word/encryption.js +0 -282
  723. package/dist/cjs/modules/word/internal-utils.js +0 -59
  724. package/dist/cjs/modules/word/namespaces.js +0 -192
  725. package/dist/cjs/modules/word/relationships.js +0 -55
  726. package/dist/cjs/modules/word/writers/checkbox-writer.js +0 -45
  727. package/dist/cjs/modules/word/writers/document-writer.js +0 -465
  728. package/dist/esm/modules/word/color-utils.js +0 -94
  729. package/dist/esm/modules/word/document.js +0 -1533
  730. package/dist/esm/modules/word/docx-packager.js +0 -822
  731. package/dist/esm/modules/word/docx-reader.js +0 -4929
  732. package/dist/esm/modules/word/encryption.js +0 -274
  733. package/dist/esm/modules/word/internal-utils.js +0 -54
  734. package/dist/esm/modules/word/namespaces.js +0 -189
  735. package/dist/esm/modules/word/relationships.js +0 -48
  736. package/dist/esm/modules/word/writers/checkbox-writer.js +0 -42
  737. package/dist/esm/modules/word/writers/document-writer.js +0 -461
  738. package/dist/types/modules/word/document.d.ts +0 -657
  739. package/dist/types/modules/word/docx-packager.d.ts +0 -14
  740. package/dist/types/modules/word/docx-reader.d.ts +0 -11
  741. package/dist/types/modules/word/internal-utils.d.ts +0 -23
  742. package/dist/types/modules/word/namespaces.d.ts +0 -159
  743. package/dist/types/modules/word/relationships.d.ts +0 -30
  744. package/dist/types/modules/word/writers/checkbox-writer.d.ts +0 -9
  745. package/dist/types/modules/word/writers/document-writer.d.ts +0 -16
  746. package/dist/types/modules/word/writers/math-writer.d.ts +0 -9
  747. /package/dist/browser/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
  748. /package/dist/browser/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
  749. /package/dist/browser/modules/word/{writers → writer}/section-writer.d.ts +0 -0
  750. /package/dist/browser/modules/word/{writers → writer}/section-writer.js +0 -0
  751. /package/dist/browser/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
  752. /package/dist/browser/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
  753. /package/dist/browser/modules/word/{writers → writer}/textbox-writer.js +0 -0
  754. /package/dist/browser/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
  755. /package/dist/browser/modules/word/{writers → writer}/toc-writer.js +0 -0
  756. /package/dist/cjs/modules/word/{writers → writer}/section-writer.js +0 -0
  757. /package/dist/cjs/modules/word/{writers → writer}/textbox-writer.js +0 -0
  758. /package/dist/cjs/modules/word/{writers → writer}/toc-writer.js +0 -0
  759. /package/dist/esm/modules/word/{writers → writer}/section-writer.js +0 -0
  760. /package/dist/esm/modules/word/{writers → writer}/textbox-writer.js +0 -0
  761. /package/dist/esm/modules/word/{writers → writer}/toc-writer.js +0 -0
  762. /package/dist/types/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
  763. /package/dist/types/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
  764. /package/dist/types/modules/word/{writers → writer}/section-writer.d.ts +0 -0
  765. /package/dist/types/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
  766. /package/dist/types/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
  767. /package/dist/types/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
@@ -0,0 +1,1238 @@
1
+ /**
2
+ * Word Document Page Renderer — SVG Output
3
+ *
4
+ * Renders DOCX document pages to SVG strings for visual preview.
5
+ * Uses the layout engine for pagination and produces approximate
6
+ * visual representations of document content.
7
+ *
8
+ * @stability experimental
9
+ */
10
+ import { measureTextWidth, mapToStandardFont } from "../../../utils/font-metrics.js";
11
+ import { xmlEncode, xmlEncodeAttr } from "../../xml/encode.js";
12
+ import { isHyperlink, isRun } from "../core/text-utils.js";
13
+ import { EMU_PER_POINT } from "../units.js";
14
+ import { layoutDocument } from "./layout.js";
15
+ import { DEFAULT_PAGE_HEIGHT_TWIPS, DEFAULT_PAGE_MARGIN_TWIPS, DEFAULT_PAGE_WIDTH_TWIPS } from "./layout-constants.js";
16
+ // =============================================================================
17
+ // Internal Constants
18
+ // =============================================================================
19
+ /** Conversion: twips to points. */
20
+ const TWIPS_TO_PT = 1 / 20;
21
+ /** Conversion: EMU to points. */
22
+ const EMU_TO_PT = 1 / EMU_PER_POINT;
23
+ /** Default font size in points. */
24
+ const DEFAULT_FONT_SIZE_PT = 12;
25
+ /** Default font name. */
26
+ const DEFAULT_FONT = "Calibri";
27
+ // =============================================================================
28
+ // Internal Helpers
29
+ // =============================================================================
30
+ /** Convert twips to points. */
31
+ function twipsToPt(twips) {
32
+ return twips * TWIPS_TO_PT;
33
+ }
34
+ /** Convert EMU to points. */
35
+ function emuToPt(emu) {
36
+ return emu * EMU_TO_PT;
37
+ }
38
+ /** Extract font name from a Run's properties. */
39
+ function getRunFontName(run) {
40
+ const font = run.properties?.font;
41
+ if (!font) {
42
+ return DEFAULT_FONT;
43
+ }
44
+ if (typeof font === "string") {
45
+ return font;
46
+ }
47
+ return font.ascii ?? font.hAnsi ?? DEFAULT_FONT;
48
+ }
49
+ /** Get font size in points from RunProperties. */
50
+ function getRunFontSizePt(props) {
51
+ if (props?.size) {
52
+ return props.size / 2;
53
+ }
54
+ return DEFAULT_FONT_SIZE_PT;
55
+ }
56
+ /** Resolve font family for SVG (uses the fonts map if provided). */
57
+ function resolveFontFamily(fontName, fontsMap) {
58
+ if (fontsMap) {
59
+ const mapped = fontsMap.get(fontName);
60
+ if (mapped) {
61
+ return mapped;
62
+ }
63
+ }
64
+ // Use generic sans-serif fallback for common fonts
65
+ const lower = fontName.toLowerCase();
66
+ if (lower.includes("times") || lower.includes("roman") || lower.includes("serif")) {
67
+ return `"${fontName}", serif`;
68
+ }
69
+ if (lower.includes("courier") || lower.includes("mono") || lower.includes("consolas")) {
70
+ return `"${fontName}", monospace`;
71
+ }
72
+ return `"${fontName}", sans-serif`;
73
+ }
74
+ /** Sanitize a string into a valid 6-digit hex color, or undefined. */
75
+ function sanitizeHexColor(raw) {
76
+ if (!raw) {
77
+ return undefined;
78
+ }
79
+ const stripped = raw.replace(/^#/, "");
80
+ if (/^[0-9a-fA-F]{6}$/.test(stripped) || /^[0-9a-fA-F]{3}$/.test(stripped)) {
81
+ return stripped;
82
+ }
83
+ return undefined;
84
+ }
85
+ /** Get CSS color from a hex color string or "auto". */
86
+ function resolveColor(color) {
87
+ if (!color) {
88
+ return undefined;
89
+ }
90
+ if (typeof color === "string") {
91
+ if (color === "auto") {
92
+ return undefined;
93
+ }
94
+ const safe = sanitizeHexColor(color);
95
+ return safe ? `#${safe}` : undefined;
96
+ }
97
+ if (color.val === "auto") {
98
+ return undefined;
99
+ }
100
+ const safe = sanitizeHexColor(color.val);
101
+ return safe ? `#${safe}` : undefined;
102
+ }
103
+ /** Determine heading level from paragraph style name. Returns 0 for non-headings. */
104
+ function getHeadingLevel(props) {
105
+ const style = props?.style;
106
+ if (!style) {
107
+ return 0;
108
+ }
109
+ const match = /^[Hh]eading(\d)$/.exec(style);
110
+ if (match) {
111
+ return parseInt(match[1], 10);
112
+ }
113
+ return 0;
114
+ }
115
+ /** Get font size multiplier based on heading level. */
116
+ function getHeadingFontScale(level) {
117
+ switch (level) {
118
+ case 1:
119
+ return 2.0;
120
+ case 2:
121
+ return 1.6;
122
+ case 3:
123
+ return 1.4;
124
+ case 4:
125
+ return 1.2;
126
+ case 5:
127
+ return 1.1;
128
+ case 6:
129
+ return 1.0;
130
+ default:
131
+ return 1.0;
132
+ }
133
+ }
134
+ /** Extract plain text from a Run. */
135
+ function getRunText(run) {
136
+ let text = "";
137
+ for (const item of run.content) {
138
+ switch (item.type) {
139
+ case "text":
140
+ text += item.text;
141
+ break;
142
+ case "tab":
143
+ text += " ";
144
+ break;
145
+ case "symbol":
146
+ text += " ";
147
+ break;
148
+ case "noBreakHyphen":
149
+ case "softHyphen":
150
+ text += "-";
151
+ break;
152
+ default:
153
+ break;
154
+ }
155
+ }
156
+ return text;
157
+ }
158
+ /** Get section properties for a given section index. */
159
+ function getSectionProps(doc, layout, pageNumber) {
160
+ // Find which section this page belongs to
161
+ let sectionIdx = 0;
162
+ let accumulatedPages = 0;
163
+ for (let s = 0; s < layout.sectionPageCounts.length; s++) {
164
+ accumulatedPages += layout.sectionPageCounts[s];
165
+ if (pageNumber <= accumulatedPages) {
166
+ sectionIdx = s;
167
+ break;
168
+ }
169
+ }
170
+ // Find the section properties for this section
171
+ // Walk through body to find the nth section break
172
+ let currentSec = 0;
173
+ for (const item of doc.body) {
174
+ if (item.type === "paragraph" && item.properties?.sectionProperties) {
175
+ if (currentSec === sectionIdx) {
176
+ return item.properties.sectionProperties;
177
+ }
178
+ currentSec++;
179
+ }
180
+ }
181
+ // Last section uses doc.sectionProperties
182
+ return doc.sectionProperties;
183
+ }
184
+ // =============================================================================
185
+ // Paragraph Rendering
186
+ // =============================================================================
187
+ /** Render a paragraph and return the Y advance. */
188
+ function renderParagraph(para, state) {
189
+ const props = para.properties;
190
+ const spacing = props?.spacing;
191
+ const headingLevel = getHeadingLevel(props);
192
+ const headingScale = getHeadingFontScale(headingLevel);
193
+ // Space before
194
+ let spaceBefore = 0;
195
+ if (spacing?.beforeAutoSpacing) {
196
+ spaceBefore = 5; // ~5pt auto spacing
197
+ }
198
+ else if (spacing?.before != null) {
199
+ spaceBefore = twipsToPt(spacing.before);
200
+ }
201
+ state.cursorY += spaceBefore;
202
+ // Thematic break (horizontal rule)
203
+ if (props?.thematicBreak) {
204
+ const lineY = state.cursorY;
205
+ state.elements.push(`<line x1="${state.marginLeftPt}" y1="${lineY}" x2="${state.marginLeftPt + state.contentWidthPt}" y2="${lineY}" stroke="#999999" stroke-width="1"/>`);
206
+ state.cursorY += 6;
207
+ return;
208
+ }
209
+ // Determine paragraph indentation
210
+ const indent = props?.indent;
211
+ const leftIndentPt = indent?.left ? twipsToPt(indent.left) : 0;
212
+ const firstLineIndentPt = indent?.firstLine ? twipsToPt(indent.firstLine) : 0;
213
+ // Determine alignment
214
+ const alignment = props?.alignment ?? "left";
215
+ // Line height
216
+ let lineHeightPt = DEFAULT_FONT_SIZE_PT * 1.2;
217
+ if (spacing?.line) {
218
+ const rule = spacing.lineRule ?? "auto";
219
+ switch (rule) {
220
+ case "exact":
221
+ lineHeightPt = twipsToPt(spacing.line);
222
+ break;
223
+ case "atLeast":
224
+ lineHeightPt = Math.max(twipsToPt(spacing.line), lineHeightPt);
225
+ break;
226
+ case "auto":
227
+ lineHeightPt = DEFAULT_FONT_SIZE_PT * 1.2 * (spacing.line / 240);
228
+ break;
229
+ }
230
+ }
231
+ // Apply heading scale to line height
232
+ lineHeightPt *= headingScale;
233
+ // Collect runs and render as text spans on lines
234
+ const runs = collectParagraphRuns(para);
235
+ if (runs.length === 0) {
236
+ // Empty paragraph — advance by line height
237
+ state.cursorY += lineHeightPt;
238
+ }
239
+ else {
240
+ // Simple line wrapping: measure text and wrap at content width
241
+ const availableWidth = state.contentWidthPt - leftIndentPt;
242
+ const lines = wrapRunsToLines(runs, availableWidth, firstLineIndentPt, headingScale);
243
+ for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
244
+ const line = lines[lineIdx];
245
+ state.cursorY += lineHeightPt;
246
+ // Calculate x position based on alignment
247
+ let xOffset = state.marginLeftPt + leftIndentPt;
248
+ if (lineIdx === 0) {
249
+ xOffset += firstLineIndentPt;
250
+ }
251
+ if (alignment === "center") {
252
+ const lineWidth = measureLineWidth(line, headingScale);
253
+ xOffset = state.marginLeftPt + (state.contentWidthPt - lineWidth) / 2;
254
+ }
255
+ else if (alignment === "right" || alignment === "end") {
256
+ const lineWidth = measureLineWidth(line, headingScale);
257
+ xOffset = state.marginLeftPt + state.contentWidthPt - lineWidth;
258
+ }
259
+ // Render each run segment on this line
260
+ let currentX = xOffset;
261
+ for (const segment of line) {
262
+ const fontSize = getRunFontSizePt(segment.properties) * headingScale;
263
+ const fontFamily = resolveFontFamily(getRunFontName({ properties: segment.properties, content: [] }), state.fontsMap);
264
+ const isBold = segment.properties?.bold || headingLevel > 0;
265
+ const isItalic = segment.properties?.italic;
266
+ const color = resolveColor(segment.properties?.color);
267
+ const underline = segment.properties?.underline;
268
+ const strike = segment.properties?.strike;
269
+ // Build style attributes
270
+ let attrs = `x="${currentX.toFixed(2)}" y="${state.cursorY.toFixed(2)}"`;
271
+ attrs += ` font-family="${xmlEncodeAttr(fontFamily)}"`;
272
+ attrs += ` font-size="${fontSize.toFixed(1)}"`;
273
+ if (isBold) {
274
+ attrs += ` font-weight="bold"`;
275
+ }
276
+ if (isItalic) {
277
+ attrs += ` font-style="italic"`;
278
+ }
279
+ if (color) {
280
+ attrs += ` fill="${color}"`;
281
+ }
282
+ if (underline && underline !== "none") {
283
+ // underline can be true, a style string, or UnderlineSpec
284
+ const isNone = typeof underline === "object" && "style" in underline && underline.style === "none";
285
+ if (!isNone) {
286
+ attrs += ` text-decoration="underline"`;
287
+ }
288
+ }
289
+ else if (strike) {
290
+ attrs += ` text-decoration="line-through"`;
291
+ }
292
+ const escapedText = xmlEncode(segment.text);
293
+ if (escapedText.length > 0) {
294
+ state.elements.push(`<text ${attrs}>${escapedText}</text>`);
295
+ }
296
+ // Advance X position using text measurement
297
+ const measuredFont = mapToStandardFont(getRunFontName({ properties: segment.properties, content: [] }));
298
+ const textWidth = measureTextWidth(segment.text, measuredFont, fontSize);
299
+ currentX += textWidth;
300
+ }
301
+ }
302
+ }
303
+ // Handle inline images within the paragraph
304
+ renderParagraphImages(para, state);
305
+ // Space after
306
+ let spaceAfter = 0;
307
+ if (spacing?.afterAutoSpacing) {
308
+ spaceAfter = 5;
309
+ }
310
+ else if (spacing?.after != null) {
311
+ spaceAfter = twipsToPt(spacing.after);
312
+ }
313
+ state.cursorY += spaceAfter;
314
+ }
315
+ /** Collect all text segments from a paragraph's children. */
316
+ function collectParagraphRuns(para) {
317
+ const segments = [];
318
+ for (const child of para.children) {
319
+ if (isRun(child)) {
320
+ const text = getRunText(child);
321
+ if (text.length > 0) {
322
+ segments.push({ text, properties: child.properties });
323
+ }
324
+ }
325
+ else if (isHyperlink(child)) {
326
+ for (const run of child.children) {
327
+ const text = getRunText(run);
328
+ if (text.length > 0) {
329
+ segments.push({ text, properties: run.properties });
330
+ }
331
+ }
332
+ }
333
+ }
334
+ return segments;
335
+ }
336
+ /** Wrap text segments into lines based on available width. */
337
+ function wrapRunsToLines(segments, availableWidth, firstLineIndent, headingScale) {
338
+ const lines = [];
339
+ let currentLine = [];
340
+ let currentLineWidth = 0;
341
+ let isFirstLine = true;
342
+ let effectiveWidth = availableWidth - firstLineIndent;
343
+ for (const segment of segments) {
344
+ const fontSize = getRunFontSizePt(segment.properties) * headingScale;
345
+ const fontName = mapToStandardFont(getRunFontName({ properties: segment.properties, content: [] }));
346
+ const segmentWidth = measureTextWidth(segment.text, fontName, fontSize);
347
+ if (currentLineWidth + segmentWidth <= effectiveWidth || currentLine.length === 0) {
348
+ // Fits on current line
349
+ currentLine.push(segment);
350
+ currentLineWidth += segmentWidth;
351
+ }
352
+ else {
353
+ // Need to wrap — try word-level splitting
354
+ const words = segment.text.split(/(\s+)/);
355
+ let bufferedText = "";
356
+ let bufferedWidth = 0;
357
+ for (const word of words) {
358
+ const wordWidth = measureTextWidth(word, fontName, fontSize);
359
+ if (currentLineWidth + bufferedWidth + wordWidth <= effectiveWidth ||
360
+ (currentLine.length === 0 && bufferedText.length === 0)) {
361
+ bufferedText += word;
362
+ bufferedWidth += wordWidth;
363
+ }
364
+ else {
365
+ // Flush buffered text to current line
366
+ if (bufferedText.length > 0) {
367
+ currentLine.push({ text: bufferedText, properties: segment.properties });
368
+ }
369
+ // Start new line
370
+ lines.push(currentLine);
371
+ currentLine = [];
372
+ currentLineWidth = 0;
373
+ if (isFirstLine) {
374
+ isFirstLine = false;
375
+ effectiveWidth = availableWidth;
376
+ }
377
+ bufferedText = word;
378
+ bufferedWidth = wordWidth;
379
+ }
380
+ }
381
+ // Flush remaining buffered text
382
+ if (bufferedText.length > 0) {
383
+ currentLine.push({ text: bufferedText, properties: segment.properties });
384
+ currentLineWidth += bufferedWidth;
385
+ }
386
+ }
387
+ }
388
+ if (currentLine.length > 0) {
389
+ lines.push(currentLine);
390
+ }
391
+ // Ensure at least one empty line for non-empty segments
392
+ if (lines.length === 0 && segments.length > 0) {
393
+ lines.push(segments);
394
+ }
395
+ return lines;
396
+ }
397
+ /** Measure the total width of a line of segments in points. */
398
+ function measureLineWidth(segments, headingScale) {
399
+ let total = 0;
400
+ for (const segment of segments) {
401
+ const fontSize = getRunFontSizePt(segment.properties) * headingScale;
402
+ const fontName = mapToStandardFont(getRunFontName({ properties: segment.properties, content: [] }));
403
+ total += measureTextWidth(segment.text, fontName, fontSize);
404
+ }
405
+ return total;
406
+ }
407
+ /** Render inline images found in paragraph runs. */
408
+ function renderParagraphImages(para, state) {
409
+ for (const child of para.children) {
410
+ if (!isRun(child)) {
411
+ continue;
412
+ }
413
+ for (const item of child.content) {
414
+ if (item.type === "image") {
415
+ const img = item;
416
+ const widthPt = emuToPt(img.width);
417
+ const heightPt = emuToPt(img.height);
418
+ // Find image data from document
419
+ const imgData = findImageData(state.doc, img.rId);
420
+ if (imgData) {
421
+ const dataUri = `data:${imageMediaTypeToMime(imgData.mediaType)};base64,${uint8ToBase64(imgData.data)}`;
422
+ state.elements.push(`<image x="${state.marginLeftPt}" y="${state.cursorY}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" href="${xmlEncodeAttr(dataUri)}"/>`);
423
+ }
424
+ else {
425
+ // Render placeholder rectangle
426
+ state.elements.push(`<rect x="${state.marginLeftPt}" y="${state.cursorY}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" fill="#f0f0f0" stroke="#cccccc" stroke-width="0.5"/>` +
427
+ `<text x="${(state.marginLeftPt + widthPt / 2).toFixed(1)}" y="${(state.cursorY + heightPt / 2).toFixed(1)}" text-anchor="middle" font-size="8" fill="#999999">[Image]</text>`);
428
+ }
429
+ state.cursorY += heightPt;
430
+ }
431
+ }
432
+ }
433
+ }
434
+ /** Find image data by relationship ID. */
435
+ function findImageData(doc, rId) {
436
+ if (!doc.images) {
437
+ return undefined;
438
+ }
439
+ for (const img of doc.images) {
440
+ if (img.rId === rId) {
441
+ return { data: img.data, mediaType: img.mediaType };
442
+ }
443
+ }
444
+ return undefined;
445
+ }
446
+ /**
447
+ * Map an `ImageMediaType` value (e.g. "png", "svg") to the MIME type required
448
+ * by `data:` URIs. The model uses short tokens, but data URIs need full
449
+ * `image/<subtype>` form — without this, browsers fail to decode the SVG
450
+ * preview's embedded images.
451
+ */
452
+ function imageMediaTypeToMime(mediaType) {
453
+ switch (mediaType) {
454
+ case "svg":
455
+ return "image/svg+xml";
456
+ case "jpeg":
457
+ case "png":
458
+ case "gif":
459
+ case "bmp":
460
+ case "tiff":
461
+ case "webp":
462
+ return `image/${mediaType}`;
463
+ case "emf":
464
+ return "image/x-emf";
465
+ case "wmf":
466
+ return "image/x-wmf";
467
+ default:
468
+ return `image/${mediaType}`;
469
+ }
470
+ }
471
+ /** Convert Uint8Array to base64 string. */
472
+ function uint8ToBase64(data) {
473
+ // Process in chunks to avoid call stack overflow with large arrays
474
+ const CHUNK_SIZE = 8192;
475
+ let binary = "";
476
+ for (let i = 0; i < data.length; i += CHUNK_SIZE) {
477
+ const chunk = data.subarray(i, Math.min(i + CHUNK_SIZE, data.length));
478
+ for (let j = 0; j < chunk.length; j++) {
479
+ binary += String.fromCharCode(chunk[j]);
480
+ }
481
+ }
482
+ return btoa(binary);
483
+ }
484
+ // =============================================================================
485
+ // Table Rendering
486
+ // =============================================================================
487
+ /** Render a table. */
488
+ function renderTable(table, state) {
489
+ const startY = state.cursorY;
490
+ const tableX = state.marginLeftPt;
491
+ // Calculate column widths
492
+ const colWidths = computeTableColumnWidths(table, state.contentWidthPt);
493
+ const totalWidth = colWidths.reduce((sum, w) => sum + w, 0);
494
+ // Track row Y positions for border drawing
495
+ const rowYPositions = [startY];
496
+ for (const row of table.rows) {
497
+ const rowStartY = state.cursorY;
498
+ const rowHeight = estimateRowHeightPt(row, colWidths, state);
499
+ // Render cell backgrounds and content
500
+ let cellX = tableX;
501
+ for (let c = 0; c < row.cells.length; c++) {
502
+ const cell = row.cells[c];
503
+ const gridSpan = cell.properties?.gridSpan ?? 1;
504
+ let cellWidth = 0;
505
+ for (let g = 0; g < gridSpan && c + g < colWidths.length; g++) {
506
+ cellWidth += colWidths[c + g];
507
+ }
508
+ // Cell background
509
+ const shading = cell.properties?.shading;
510
+ if (shading?.fill && shading.fill !== "auto") {
511
+ const safeFill = sanitizeHexColor(shading.fill);
512
+ if (safeFill) {
513
+ state.elements.push(`<rect x="${cellX.toFixed(2)}" y="${rowStartY.toFixed(2)}" width="${cellWidth.toFixed(2)}" height="${rowHeight.toFixed(2)}" fill="#${safeFill}" stroke="none"/>`);
514
+ }
515
+ }
516
+ // Render cell content (simplified — just text)
517
+ const cellPadding = 4; // ~4pt padding
518
+ let cellCursorY = rowStartY + cellPadding;
519
+ for (const content of cell.content) {
520
+ if (content.type === "paragraph") {
521
+ // Simplified: render first run of each paragraph
522
+ const runs = collectParagraphRuns(content);
523
+ if (runs.length > 0) {
524
+ const allText = runs.map(r => r.text).join("");
525
+ const firstRun = runs[0];
526
+ const fontSize = getRunFontSizePt(firstRun.properties);
527
+ const fontFamily = resolveFontFamily(getRunFontName({ properties: firstRun.properties, content: [] }), state.fontsMap);
528
+ const isBold = firstRun.properties?.bold;
529
+ cellCursorY += fontSize * 1.2;
530
+ let textAttrs = `x="${(cellX + cellPadding).toFixed(2)}" y="${cellCursorY.toFixed(2)}"`;
531
+ textAttrs += ` font-family="${xmlEncodeAttr(fontFamily)}"`;
532
+ textAttrs += ` font-size="${fontSize.toFixed(1)}"`;
533
+ if (isBold) {
534
+ textAttrs += ` font-weight="bold"`;
535
+ }
536
+ // Clip text to cell width
537
+ const maxChars = Math.floor((cellWidth - cellPadding * 2) / (fontSize * 0.5));
538
+ const displayText = allText.length > maxChars ? allText.slice(0, maxChars) + "…" : allText;
539
+ state.elements.push(`<text ${textAttrs}>${xmlEncode(displayText)}</text>`);
540
+ }
541
+ else {
542
+ cellCursorY += DEFAULT_FONT_SIZE_PT * 1.2;
543
+ }
544
+ }
545
+ }
546
+ cellX += cellWidth;
547
+ }
548
+ state.cursorY += rowHeight;
549
+ rowYPositions.push(state.cursorY);
550
+ }
551
+ // Draw table borders (outer rect + row/col lines)
552
+ const tableEndY = state.cursorY;
553
+ const borderColor = getTableBorderColor(table);
554
+ // Outer border
555
+ state.elements.push(`<rect x="${tableX.toFixed(2)}" y="${startY.toFixed(2)}" width="${totalWidth.toFixed(2)}" height="${(tableEndY - startY).toFixed(2)}" fill="none" stroke="${borderColor}" stroke-width="0.75"/>`);
556
+ // Horizontal row lines
557
+ for (let r = 1; r < rowYPositions.length - 1; r++) {
558
+ const y = rowYPositions[r];
559
+ state.elements.push(`<line x1="${tableX.toFixed(2)}" y1="${y.toFixed(2)}" x2="${(tableX + totalWidth).toFixed(2)}" y2="${y.toFixed(2)}" stroke="${borderColor}" stroke-width="0.5"/>`);
560
+ }
561
+ // Vertical column lines
562
+ let colX = tableX;
563
+ for (let c = 0; c < colWidths.length - 1; c++) {
564
+ colX += colWidths[c];
565
+ state.elements.push(`<line x1="${colX.toFixed(2)}" y1="${startY.toFixed(2)}" x2="${colX.toFixed(2)}" y2="${tableEndY.toFixed(2)}" stroke="${borderColor}" stroke-width="0.5"/>`);
566
+ }
567
+ // Add some spacing after the table
568
+ state.cursorY += 6;
569
+ }
570
+ /** Compute column widths in points for a table. */
571
+ function computeTableColumnWidths(table, availableWidthPt) {
572
+ if (table.columnWidths && table.columnWidths.length > 0) {
573
+ return table.columnWidths.map(w => twipsToPt(w));
574
+ }
575
+ // Fall back to equal distribution based on max cell count
576
+ let maxCols = 0;
577
+ for (const row of table.rows) {
578
+ if (row.cells.length > maxCols) {
579
+ maxCols = row.cells.length;
580
+ }
581
+ }
582
+ if (maxCols === 0) {
583
+ return [availableWidthPt];
584
+ }
585
+ const colWidth = availableWidthPt / maxCols;
586
+ return Array.from({ length: maxCols }, () => colWidth);
587
+ }
588
+ /** Estimate row height in points. */
589
+ function estimateRowHeightPt(row, colWidths, state) {
590
+ // Check explicit height
591
+ if (row.properties?.height?.value) {
592
+ const rule = row.properties.height.rule;
593
+ if (rule === "exact") {
594
+ return twipsToPt(row.properties.height.value);
595
+ }
596
+ }
597
+ // Estimate from content
598
+ let maxHeight = DEFAULT_FONT_SIZE_PT * 1.2 + 8; // minimum: one line + padding
599
+ for (let c = 0; c < row.cells.length; c++) {
600
+ const cell = row.cells[c];
601
+ let cellHeight = 8; // padding
602
+ for (const content of cell.content) {
603
+ if (content.type === "paragraph") {
604
+ const runs = collectParagraphRuns(content);
605
+ const lineHeight = DEFAULT_FONT_SIZE_PT * 1.2;
606
+ if (runs.length === 0) {
607
+ cellHeight += lineHeight;
608
+ }
609
+ else {
610
+ // Estimate line count
611
+ const allText = runs.map(r => r.text).join("");
612
+ const gridSpan = cell.properties?.gridSpan ?? 1;
613
+ let cellWidth = 0;
614
+ for (let g = 0; g < gridSpan && c + g < colWidths.length; g++) {
615
+ cellWidth += colWidths[c + g];
616
+ }
617
+ const charsPerLine = Math.max(1, Math.floor((cellWidth - 8) / (DEFAULT_FONT_SIZE_PT * 0.5)));
618
+ const lineCount = Math.max(1, Math.ceil(allText.length / charsPerLine));
619
+ cellHeight += lineCount * lineHeight;
620
+ }
621
+ }
622
+ }
623
+ if (cellHeight > maxHeight) {
624
+ maxHeight = cellHeight;
625
+ }
626
+ }
627
+ // Respect atLeast constraint
628
+ if (row.properties?.height?.value) {
629
+ return Math.max(twipsToPt(row.properties.height.value), maxHeight);
630
+ }
631
+ return maxHeight;
632
+ }
633
+ /** Get the border color for a table. */
634
+ function getTableBorderColor(table) {
635
+ const borders = table.properties?.borders;
636
+ if (borders?.top?.color && borders.top.color !== "auto") {
637
+ const safe = sanitizeHexColor(borders.top.color);
638
+ if (safe) {
639
+ return `#${safe}`;
640
+ }
641
+ }
642
+ return "#000000";
643
+ }
644
+ // =============================================================================
645
+ // Floating Image Rendering
646
+ // =============================================================================
647
+ /** Render a floating image. */
648
+ function renderFloatingImage(item, state) {
649
+ const img = item;
650
+ const widthPt = emuToPt(img.width);
651
+ const heightPt = emuToPt(img.height);
652
+ const imgData = findImageData(state.doc, img.rId);
653
+ if (imgData) {
654
+ const dataUri = `data:${imageMediaTypeToMime(imgData.mediaType)};base64,${uint8ToBase64(imgData.data)}`;
655
+ state.elements.push(`<image x="${state.marginLeftPt}" y="${state.cursorY.toFixed(2)}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" href="${xmlEncodeAttr(dataUri)}"/>`);
656
+ }
657
+ else {
658
+ state.elements.push(`<rect x="${state.marginLeftPt}" y="${state.cursorY.toFixed(2)}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" fill="#f0f0f0" stroke="#cccccc" stroke-width="0.5"/>` +
659
+ `<text x="${(state.marginLeftPt + widthPt / 2).toFixed(1)}" y="${(state.cursorY + heightPt / 2).toFixed(1)}" text-anchor="middle" font-size="8" fill="#999999">[Image]</text>`);
660
+ }
661
+ // topAndBottom wrap consumes space
662
+ const wrapStyle = img.wrap?.style;
663
+ if (wrapStyle === "topAndBottom" || !wrapStyle) {
664
+ state.cursorY += heightPt;
665
+ }
666
+ }
667
+ // =============================================================================
668
+ // Page Rendering Core
669
+ // =============================================================================
670
+ /** Render a single page's content to SVG elements. */
671
+ function renderPageContent(doc, layout, pageNumber, sectionProps, options) {
672
+ const pageWidthPt = twipsToPt(sectionProps?.pageSize?.width ?? DEFAULT_PAGE_WIDTH_TWIPS);
673
+ const pageHeightPt = twipsToPt(sectionProps?.pageSize?.height ?? DEFAULT_PAGE_HEIGHT_TWIPS);
674
+ const marginTopPt = twipsToPt(sectionProps?.margins?.top ?? DEFAULT_PAGE_MARGIN_TWIPS);
675
+ const marginBottomPt = twipsToPt(sectionProps?.margins?.bottom ?? DEFAULT_PAGE_MARGIN_TWIPS);
676
+ const marginLeftPt = twipsToPt(sectionProps?.margins?.left ?? DEFAULT_PAGE_MARGIN_TWIPS);
677
+ const marginRightPt = twipsToPt(sectionProps?.margins?.right ?? DEFAULT_PAGE_MARGIN_TWIPS);
678
+ const contentWidthPt = pageWidthPt - marginLeftPt - marginRightPt;
679
+ const contentHeightPt = pageHeightPt - marginTopPt - marginBottomPt;
680
+ const state = {
681
+ pageWidthPt,
682
+ pageHeightPt,
683
+ marginTopPt,
684
+ marginBottomPt,
685
+ marginLeftPt,
686
+ marginRightPt,
687
+ contentWidthPt,
688
+ contentHeightPt,
689
+ fontsMap: options?.fonts,
690
+ doc,
691
+ cursorY: marginTopPt,
692
+ elements: []
693
+ };
694
+ // Render body content that belongs to this page
695
+ for (let i = 0; i < doc.body.length; i++) {
696
+ const contentPage = layout.contentPages[i];
697
+ if (contentPage !== pageNumber) {
698
+ continue;
699
+ }
700
+ // Stop rendering if we've exceeded the content area
701
+ if (state.cursorY > pageHeightPt - marginBottomPt) {
702
+ break;
703
+ }
704
+ const item = doc.body[i];
705
+ switch (item.type) {
706
+ case "paragraph":
707
+ renderParagraph(item, state);
708
+ break;
709
+ case "table":
710
+ renderTable(item, state);
711
+ break;
712
+ case "floatingImage":
713
+ renderFloatingImage(item, state);
714
+ break;
715
+ default:
716
+ // Skip unsupported content types (TOC, shapes, etc.)
717
+ // Advance cursor slightly to maintain spacing
718
+ state.cursorY += DEFAULT_FONT_SIZE_PT * 1.2;
719
+ break;
720
+ }
721
+ }
722
+ return { elements: state.elements, pageWidthPt, pageHeightPt };
723
+ }
724
+ // =============================================================================
725
+ // Public API
726
+ // =============================================================================
727
+ /**
728
+ * Render a specific page of a DOCX document to an SVG string.
729
+ *
730
+ * @param doc - The parsed DOCX document
731
+ * @param pageNumber - 1-based page number to render
732
+ * @param options - Rendering options
733
+ * @returns SVG string for the specified page
734
+ *
735
+ * @stability experimental
736
+ */
737
+ export function renderPageToSvg(doc, pageNumber, options) {
738
+ const layout = layoutDocument(doc, {
739
+ measureText: (text, fontName, fontSize) => measureTextWidth(text, mapToStandardFont(fontName), fontSize)
740
+ });
741
+ if (pageNumber < 1 || pageNumber > layout.pageCount) {
742
+ throw new RangeError(`Page number ${pageNumber} out of range. Document has ${layout.pageCount} page(s).`);
743
+ }
744
+ const sectionProps = getSectionProps(doc, layout, pageNumber);
745
+ const { elements, pageWidthPt, pageHeightPt } = renderPageContent(doc, layout, pageNumber, sectionProps, options);
746
+ return buildSvgDocument(elements, pageWidthPt, pageHeightPt, options);
747
+ }
748
+ /**
749
+ * Render all pages of a DOCX document to SVG strings.
750
+ *
751
+ * @param doc - The parsed DOCX document
752
+ * @param options - Rendering options
753
+ * @returns Array of SVG strings, one per page
754
+ *
755
+ * @stability experimental
756
+ */
757
+ export function renderDocumentToSvg(doc, options) {
758
+ const layout = layoutDocument(doc, {
759
+ measureText: (text, fontName, fontSize) => measureTextWidth(text, mapToStandardFont(fontName), fontSize)
760
+ });
761
+ const svgPages = [];
762
+ for (let page = 1; page <= layout.pageCount; page++) {
763
+ const sectionProps = getSectionProps(doc, layout, page);
764
+ const { elements, pageWidthPt, pageHeightPt } = renderPageContent(doc, layout, page, sectionProps, options);
765
+ svgPages.push(buildSvgDocument(elements, pageWidthPt, pageHeightPt, options));
766
+ }
767
+ return svgPages;
768
+ }
769
+ /** Build the final SVG document string from rendered elements. */
770
+ function buildSvgDocument(elements, pageWidthPt, pageHeightPt, options) {
771
+ const scale = options?.scale ?? 1.0;
772
+ const bgColor = options?.backgroundColor ?? "white";
773
+ // Determine output dimensions
774
+ let outputWidth;
775
+ let outputHeight;
776
+ if (options?.width && options?.height) {
777
+ outputWidth = options.width;
778
+ outputHeight = options.height;
779
+ }
780
+ else if (options?.width) {
781
+ outputWidth = options.width;
782
+ outputHeight = (pageHeightPt / pageWidthPt) * options.width;
783
+ }
784
+ else if (options?.height) {
785
+ outputHeight = options.height;
786
+ outputWidth = (pageWidthPt / pageHeightPt) * options.height;
787
+ }
788
+ else {
789
+ outputWidth = pageWidthPt * scale;
790
+ outputHeight = pageHeightPt * scale;
791
+ }
792
+ const viewBox = `0 0 ${pageWidthPt.toFixed(2)} ${pageHeightPt.toFixed(2)}`;
793
+ let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${outputWidth.toFixed(2)}" height="${outputHeight.toFixed(2)}" viewBox="${viewBox}">\n`;
794
+ svg += ` <rect width="100%" height="100%" fill="${xmlEncodeAttr(bgColor)}"/>\n`;
795
+ for (const element of elements) {
796
+ svg += ` ${element}\n`;
797
+ }
798
+ svg += `</svg>`;
799
+ return svg;
800
+ }
801
+ // =============================================================================
802
+ // New API: Render from pre-computed LayoutDocument (no re-layout)
803
+ // =============================================================================
804
+ /**
805
+ * Render a page from a pre-computed LayoutDocument to SVG.
806
+ * This avoids re-computing layout — just serializes positioned elements to SVG.
807
+ *
808
+ * @param layout - A LayoutDocument produced by layoutDocumentFull().
809
+ * @param pageNumber - 1-based page number to render.
810
+ * @param options - Rendering options (scale, dimensions, background color).
811
+ * @returns SVG string.
812
+ *
813
+ * @stability experimental
814
+ */
815
+ export function renderPageFromLayout(layout, pageNumber, options) {
816
+ if (pageNumber < 1 || pageNumber > layout.totalPages) {
817
+ throw new RangeError(`Page number ${pageNumber} out of range. Document has ${layout.totalPages} page(s).`);
818
+ }
819
+ const page = layout.pages[pageNumber - 1];
820
+ const { geometry } = page;
821
+ const elements = [];
822
+ // Header / footer paragraphs and tables come with layout-y already
823
+ // expressed as a page-absolute offset (the layout engine adds the
824
+ // section's `pgMar.header` to header content and starts footer
825
+ // content at `pageHeight - pgMar.footer`). Use a geometry with
826
+ // `marginTop: 0` so SVG y-coordinates resolve straight from
827
+ // layout-y. Tables in header / footer are uncommon but legal —
828
+ // dispatch through the same renderers used for body content.
829
+ const bandGeometry = { ...geometry, marginTop: 0 };
830
+ if (page.header) {
831
+ for (const item of page.header) {
832
+ if (item.type === "paragraph") {
833
+ renderLayoutParagraphToSvg(item, bandGeometry, elements);
834
+ }
835
+ else {
836
+ renderLayoutTableToSvg(item, bandGeometry, elements);
837
+ }
838
+ }
839
+ }
840
+ // Render each positioned content element. Every PageContent variant is
841
+ // handled — most non-paragraph/table types degrade to a placeholder rect
842
+ // (charts, shapes, opaque drawings), an inline glyph (check-boxes, math),
843
+ // or a recursive descent (text-boxes, SDTs). Adding a new PageContent
844
+ // variant is a build error here until a case is added.
845
+ for (const item of page.content) {
846
+ switch (item.type) {
847
+ case "paragraph":
848
+ renderLayoutParagraphToSvg(item, geometry, elements);
849
+ break;
850
+ case "table":
851
+ renderLayoutTableToSvg(item, geometry, elements);
852
+ break;
853
+ case "image":
854
+ renderLayoutImageToSvg(item, geometry, elements);
855
+ break;
856
+ case "float":
857
+ renderLayoutFloatToSvg(item, geometry, elements);
858
+ break;
859
+ case "textBox":
860
+ renderLayoutTextBoxToSvg(item, geometry, elements);
861
+ break;
862
+ case "shape":
863
+ renderLayoutShapeToSvg(item, geometry, elements);
864
+ break;
865
+ case "chart":
866
+ renderLayoutChartToSvg(item, geometry, elements);
867
+ break;
868
+ case "sdt":
869
+ renderLayoutSdtToSvg(item, geometry, elements);
870
+ break;
871
+ case "math":
872
+ renderLayoutMathToSvg(item, geometry, elements);
873
+ break;
874
+ case "checkBox":
875
+ renderLayoutCheckBoxToSvg(item, geometry, elements);
876
+ break;
877
+ case "tableOfContents":
878
+ renderLayoutTocToSvg(item, geometry, elements);
879
+ break;
880
+ case "altChunk":
881
+ renderLayoutPlaceholderToSvg(item.rect, geometry, `[${item.contentType}]`, elements);
882
+ break;
883
+ case "opaqueDrawing":
884
+ renderLayoutPlaceholderToSvg(item.rect, geometry, "[drawing]", elements);
885
+ break;
886
+ default: {
887
+ const _exhaustive = item;
888
+ throw new Error(`renderPageFromLayout: unhandled PageContent ${_exhaustive.type}`);
889
+ }
890
+ }
891
+ }
892
+ // Footer — `bandGeometry` (declared near the header above) shares the
893
+ // same "layout-y is page-absolute" rule for both bands.
894
+ if (page.footer) {
895
+ for (const item of page.footer) {
896
+ if (item.type === "paragraph") {
897
+ renderLayoutParagraphToSvg(item, bandGeometry, elements);
898
+ }
899
+ else {
900
+ renderLayoutTableToSvg(item, bandGeometry, elements);
901
+ }
902
+ }
903
+ }
904
+ // Footnote separator (drawn above the footnote area; see ECMA-376
905
+ // §17.11.10). Same coordinate convention as bands: the layout y
906
+ // value is page-absolute.
907
+ if (page.footnoteSeparator) {
908
+ const sep = page.footnoteSeparator;
909
+ const ruleWidth = sep.kind === "separator" ? geometry.contentWidth / 3 : geometry.contentWidth;
910
+ const x1 = geometry.marginLeft;
911
+ const x2 = x1 + ruleWidth;
912
+ elements.push(`<line x1="${x1.toFixed(2)}" y1="${sep.y.toFixed(2)}" x2="${x2.toFixed(2)}" y2="${sep.y.toFixed(2)}" stroke="black" stroke-width="0.5"/>`);
913
+ }
914
+ // Footnote area paragraphs (page-absolute y, like header/footer).
915
+ if (page.footnoteArea) {
916
+ for (const para of page.footnoteArea) {
917
+ renderLayoutParagraphToSvg(para, bandGeometry, elements);
918
+ }
919
+ }
920
+ return buildSvgDocument(elements, geometry.width, geometry.height, options);
921
+ }
922
+ /** Render a LayoutParagraph to SVG text elements. */
923
+ function renderLayoutParagraphToSvg(para, geometry, elements) {
924
+ for (const line of para.lines) {
925
+ const lineY = geometry.marginTop + para.rect.y + line.y + line.baseline;
926
+ const lineTopY = geometry.marginTop + para.rect.y + line.y;
927
+ for (const item of line.runs) {
928
+ if (item.type === "image") {
929
+ // Inline image: bottom-aligned within the line, matching
930
+ // Word's default for in-line images. Empty data → emit
931
+ // nothing rather than an invalid <image href> with empty src.
932
+ if (item.data.length === 0) {
933
+ continue;
934
+ }
935
+ const x = geometry.marginLeft + item.x;
936
+ const yBottom = lineTopY + Math.min(line.height, item.height);
937
+ const yTop = yBottom - item.height;
938
+ const dataUri = `data:${item.mimeType};base64,${bytesToBase64(item.data)}`;
939
+ elements.push(`<image x="${x.toFixed(2)}" y="${yTop.toFixed(2)}" width="${item.width.toFixed(2)}" height="${item.height.toFixed(2)}" href="${xmlEncodeAttr(dataUri)}"/>`);
940
+ continue;
941
+ }
942
+ const run = item;
943
+ const x = geometry.marginLeft + run.x;
944
+ // Sub/superscript: shift the SVG baseline. SVG y-axis points
945
+ // downward (opposite of PDF), so superscript moves UP (smaller
946
+ // y) and subscript moves DOWN (larger y) — opposite signs from
947
+ // the PDF code.
948
+ let runY = lineY;
949
+ if (run.verticalAlign === "superscript") {
950
+ runY = lineY - run.fontSize * 0.33;
951
+ }
952
+ else if (run.verticalAlign === "subscript") {
953
+ runY = lineY + run.fontSize * 0.33;
954
+ }
955
+ let attrs = `x="${x.toFixed(2)}" y="${runY.toFixed(2)}"`;
956
+ attrs += ` font-family="${xmlEncodeAttr(run.font)}"`;
957
+ attrs += ` font-size="${run.fontSize.toFixed(1)}"`;
958
+ if (run.bold) {
959
+ attrs += ` font-weight="bold"`;
960
+ }
961
+ if (run.italic) {
962
+ attrs += ` font-style="italic"`;
963
+ }
964
+ if (run.color) {
965
+ const safe = sanitizeHexColor(run.color);
966
+ if (safe) {
967
+ attrs += ` fill="#${safe}"`;
968
+ }
969
+ }
970
+ if (run.underline) {
971
+ attrs += ` text-decoration="underline"`;
972
+ }
973
+ else if (run.strikethrough) {
974
+ attrs += ` text-decoration="line-through"`;
975
+ }
976
+ const escapedText = xmlEncode(run.text);
977
+ if (escapedText.length > 0) {
978
+ elements.push(`<text ${attrs}>${escapedText}</text>`);
979
+ }
980
+ }
981
+ }
982
+ }
983
+ /** Render a LayoutTable to SVG (borders + cell content). */
984
+ function renderLayoutTableToSvg(table, geometry, elements) {
985
+ // Draw cell borders and content
986
+ for (const cell of table.cells) {
987
+ const cellX = geometry.marginLeft + table.rect.x + cell.rect.x;
988
+ const cellY = geometry.marginTop + table.rect.y + cell.rect.y;
989
+ const w = cell.rect.width;
990
+ const h = cell.rect.height;
991
+ // Background
992
+ if (cell.backgroundColor) {
993
+ const safeBg = sanitizeHexColor(cell.backgroundColor);
994
+ if (safeBg) {
995
+ elements.push(`<rect x="${cellX.toFixed(2)}" y="${cellY.toFixed(2)}" width="${w.toFixed(2)}" height="${h.toFixed(2)}" fill="#${safeBg}" stroke="none"/>`);
996
+ }
997
+ }
998
+ // Border
999
+ elements.push(`<rect x="${cellX.toFixed(2)}" y="${cellY.toFixed(2)}" width="${w.toFixed(2)}" height="${h.toFixed(2)}" fill="none" stroke="#cccccc" stroke-width="0.5"/>`);
1000
+ // Cell paragraph content
1001
+ for (const content of cell.content) {
1002
+ if (content.type === "paragraph") {
1003
+ const offsetPara = {
1004
+ ...content,
1005
+ rect: {
1006
+ ...content.rect,
1007
+ y: table.rect.y + cell.rect.y + content.rect.y
1008
+ }
1009
+ };
1010
+ // Offset line runs by cell x
1011
+ const offsetLines = content.lines.map(line => ({
1012
+ ...line,
1013
+ runs: line.runs.map(run => ({
1014
+ ...run,
1015
+ x: run.x + table.rect.x + cell.rect.x
1016
+ }))
1017
+ }));
1018
+ renderLayoutParagraphToSvg({ ...offsetPara, lines: offsetLines }, geometry, elements);
1019
+ }
1020
+ }
1021
+ }
1022
+ }
1023
+ // =============================================================================
1024
+ // SVG renderers — extended PageContent variants
1025
+ // =============================================================================
1026
+ function absRect(rect, geometry) {
1027
+ return {
1028
+ x: geometry.marginLeft + rect.x,
1029
+ y: geometry.marginTop + rect.y,
1030
+ width: rect.width,
1031
+ height: rect.height
1032
+ };
1033
+ }
1034
+ function pushPlaceholder(abs, fillStroke, elements) {
1035
+ const fill = fillStroke.fill ?? "none";
1036
+ const stroke = fillStroke.stroke ?? "#bbbbbb";
1037
+ const sw = (fillStroke.strokeWidth ?? 0.5).toFixed(2);
1038
+ elements.push(`<rect x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.width.toFixed(2)}" height="${abs.height.toFixed(2)}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"/>`);
1039
+ }
1040
+ function renderLayoutImageToSvg(img, geometry, elements) {
1041
+ const abs = absRect(img.rect, geometry);
1042
+ if (img.data.length === 0) {
1043
+ pushPlaceholder(abs, { stroke: "#888888" }, elements);
1044
+ return;
1045
+ }
1046
+ const dataUri = `data:${img.mimeType};base64,${bytesToBase64(img.data)}`;
1047
+ elements.push(`<image x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.width.toFixed(2)}" height="${abs.height.toFixed(2)}" href="${xmlEncodeAttr(dataUri)}"/>`);
1048
+ }
1049
+ function renderLayoutFloatToSvg(float, geometry, elements) {
1050
+ // Floats currently always wrap a LayoutImage. Behind-text floats render
1051
+ // before main content in document order; SVG is painters-algorithm so a
1052
+ // dedicated z-ordering pass would belong upstream — for now rendering
1053
+ // order matches `page.content` order which is good enough.
1054
+ if (float.content.type === "image") {
1055
+ renderLayoutImageToSvg(float.content, geometry, elements);
1056
+ }
1057
+ else {
1058
+ renderLayoutParagraphToSvg(float.content, geometry, elements);
1059
+ }
1060
+ }
1061
+ function renderLayoutTextBoxToSvg(tb, geometry, elements) {
1062
+ const abs = absRect(tb.rect, geometry);
1063
+ const safeStroke = tb.border ? sanitizeHexColor(tb.border.color) : undefined;
1064
+ const safeFill = tb.background ? sanitizeHexColor(tb.background) : undefined;
1065
+ pushPlaceholder(abs, {
1066
+ fill: safeFill ? `#${safeFill}` : undefined,
1067
+ stroke: safeStroke ? `#${safeStroke}` : undefined,
1068
+ strokeWidth: tb.border?.width
1069
+ }, elements);
1070
+ // Translate inner content by the text-box origin and recurse through the
1071
+ // generic SVG dispatcher so nested content (paragraphs, tables, even
1072
+ // shapes) renders correctly.
1073
+ const innerGeometry = {
1074
+ ...geometry,
1075
+ marginLeft: geometry.marginLeft + tb.rect.x,
1076
+ marginTop: geometry.marginTop + tb.rect.y
1077
+ };
1078
+ renderPageContentList(tb.content, innerGeometry, elements);
1079
+ }
1080
+ function renderLayoutShapeToSvg(shape, geometry, elements) {
1081
+ const abs = absRect(shape.rect, geometry);
1082
+ const fill = shape.fillColor ? `#${sanitizeHexColor(shape.fillColor)}` : "none";
1083
+ const stroke = shape.strokeColor ? `#${sanitizeHexColor(shape.strokeColor)}` : "#888888";
1084
+ const sw = (shape.strokeWidth ?? 0.75).toFixed(2);
1085
+ // Map a few common preset shapes; everything else falls back to a rect.
1086
+ if (shape.preset === "ellipse" || shape.preset === "oval") {
1087
+ const cx = (abs.x + abs.width / 2).toFixed(2);
1088
+ const cy = (abs.y + abs.height / 2).toFixed(2);
1089
+ const rx = (abs.width / 2).toFixed(2);
1090
+ const ry = (abs.height / 2).toFixed(2);
1091
+ elements.push(`<ellipse cx="${cx}" cy="${cy}" rx="${rx}" ry="${ry}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"/>`);
1092
+ }
1093
+ else if (shape.preset === "line") {
1094
+ elements.push(`<line x1="${abs.x.toFixed(2)}" y1="${abs.y.toFixed(2)}" x2="${(abs.x + abs.width).toFixed(2)}" y2="${(abs.y + abs.height).toFixed(2)}" stroke="${stroke}" stroke-width="${sw}"/>`);
1095
+ }
1096
+ else {
1097
+ elements.push(`<rect x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.width.toFixed(2)}" height="${abs.height.toFixed(2)}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"/>`);
1098
+ }
1099
+ if (shape.textContent && shape.textContent.length > 0) {
1100
+ const innerGeometry = {
1101
+ ...geometry,
1102
+ marginLeft: geometry.marginLeft + shape.rect.x,
1103
+ marginTop: geometry.marginTop + shape.rect.y
1104
+ };
1105
+ renderPageContentList(shape.textContent, innerGeometry, elements);
1106
+ }
1107
+ }
1108
+ function renderLayoutChartToSvg(chart, geometry, elements) {
1109
+ const abs = absRect(chart.rect, geometry);
1110
+ if (chart.svg) {
1111
+ // Inline a pre-rendered SVG fragment inside a <g> with an absolute
1112
+ // translate so it ends up at the right page coordinates.
1113
+ elements.push(`<g transform="translate(${abs.x.toFixed(2)} ${abs.y.toFixed(2)})">${chart.svg}</g>`);
1114
+ return;
1115
+ }
1116
+ pushPlaceholder(abs, { stroke: "#666666" }, elements);
1117
+ if (chart.title) {
1118
+ const cx = abs.x + abs.width / 2;
1119
+ const cy = abs.y + abs.height / 2;
1120
+ elements.push(`<text x="${cx.toFixed(2)}" y="${cy.toFixed(2)}" text-anchor="middle" dominant-baseline="central" font-family="Helvetica" font-size="10" fill="#444444">${xmlEncode(chart.title)}</text>`);
1121
+ }
1122
+ }
1123
+ function renderLayoutSdtToSvg(sdt, geometry, elements) {
1124
+ // SDT is transparent visually; recurse into its children using the
1125
+ // page-relative geometry but offset by the SDT's own rect.
1126
+ const innerGeometry = {
1127
+ ...geometry,
1128
+ marginLeft: geometry.marginLeft + sdt.rect.x,
1129
+ marginTop: geometry.marginTop + sdt.rect.y
1130
+ };
1131
+ renderPageContentList(sdt.content, innerGeometry, elements);
1132
+ }
1133
+ function renderLayoutMathToSvg(math, geometry, elements) {
1134
+ const abs = absRect(math.rect, geometry);
1135
+ // Render the plain-text fallback. Renderers that want true math display
1136
+ // can read `math.mathML` from the layout document directly.
1137
+ elements.push(`<text x="${abs.x.toFixed(2)}" y="${(abs.y + abs.height * 0.8).toFixed(2)}" font-family="serif" font-style="italic" font-size="${(abs.height * 0.7).toFixed(1)}" fill="#000">${xmlEncode(math.text)}</text>`);
1138
+ }
1139
+ function renderLayoutCheckBoxToSvg(cb, geometry, elements) {
1140
+ const abs = absRect(cb.rect, geometry);
1141
+ // Draw the actual square so the rendered output is independent of font
1142
+ // availability.
1143
+ elements.push(`<rect x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.height.toFixed(2)}" height="${abs.height.toFixed(2)}" fill="white" stroke="#000" stroke-width="0.75"/>`);
1144
+ if (cb.checked) {
1145
+ const x1 = abs.x + abs.height * 0.2;
1146
+ const y1 = abs.y + abs.height * 0.55;
1147
+ const x2 = abs.x + abs.height * 0.45;
1148
+ const y2 = abs.y + abs.height * 0.8;
1149
+ const x3 = abs.x + abs.height * 0.85;
1150
+ const y3 = abs.y + abs.height * 0.2;
1151
+ elements.push(`<polyline points="${x1.toFixed(2)},${y1.toFixed(2)} ${x2.toFixed(2)},${y2.toFixed(2)} ${x3.toFixed(2)},${y3.toFixed(2)}" fill="none" stroke="#000" stroke-width="1"/>`);
1152
+ }
1153
+ }
1154
+ function renderLayoutTocToSvg(toc, geometry, elements) {
1155
+ // TOC is a list of LayoutParagraphs; render them with a y-offset by the
1156
+ // TOC's own rect.
1157
+ const innerGeometry = {
1158
+ ...geometry,
1159
+ marginLeft: geometry.marginLeft + toc.rect.x,
1160
+ marginTop: geometry.marginTop + toc.rect.y
1161
+ };
1162
+ for (const p of toc.entries) {
1163
+ renderLayoutParagraphToSvg(p, innerGeometry, elements);
1164
+ }
1165
+ }
1166
+ function renderLayoutPlaceholderToSvg(rect, geometry, label, elements) {
1167
+ const abs = absRect(rect, geometry);
1168
+ pushPlaceholder(abs, { stroke: "#888888" }, elements);
1169
+ const cx = abs.x + abs.width / 2;
1170
+ const cy = abs.y + abs.height / 2;
1171
+ elements.push(`<text x="${cx.toFixed(2)}" y="${cy.toFixed(2)}" text-anchor="middle" dominant-baseline="central" font-family="Helvetica" font-size="9" fill="#666">${xmlEncode(label)}</text>`);
1172
+ }
1173
+ /** Recursive dispatch helper used by container variants (SDT, TextBox, Shape). */
1174
+ function renderPageContentList(items, geometry, elements) {
1175
+ for (const item of items) {
1176
+ switch (item.type) {
1177
+ case "paragraph":
1178
+ renderLayoutParagraphToSvg(item, geometry, elements);
1179
+ break;
1180
+ case "table":
1181
+ renderLayoutTableToSvg(item, geometry, elements);
1182
+ break;
1183
+ case "image":
1184
+ renderLayoutImageToSvg(item, geometry, elements);
1185
+ break;
1186
+ case "float":
1187
+ renderLayoutFloatToSvg(item, geometry, elements);
1188
+ break;
1189
+ case "textBox":
1190
+ renderLayoutTextBoxToSvg(item, geometry, elements);
1191
+ break;
1192
+ case "shape":
1193
+ renderLayoutShapeToSvg(item, geometry, elements);
1194
+ break;
1195
+ case "chart":
1196
+ renderLayoutChartToSvg(item, geometry, elements);
1197
+ break;
1198
+ case "sdt":
1199
+ renderLayoutSdtToSvg(item, geometry, elements);
1200
+ break;
1201
+ case "math":
1202
+ renderLayoutMathToSvg(item, geometry, elements);
1203
+ break;
1204
+ case "checkBox":
1205
+ renderLayoutCheckBoxToSvg(item, geometry, elements);
1206
+ break;
1207
+ case "tableOfContents":
1208
+ renderLayoutTocToSvg(item, geometry, elements);
1209
+ break;
1210
+ case "altChunk":
1211
+ renderLayoutPlaceholderToSvg(item.rect, geometry, `[${item.contentType}]`, elements);
1212
+ break;
1213
+ case "opaqueDrawing":
1214
+ renderLayoutPlaceholderToSvg(item.rect, geometry, "[drawing]", elements);
1215
+ break;
1216
+ default: {
1217
+ const _exhaustive = item;
1218
+ throw new Error(`renderPageContentList: unhandled PageContent ${_exhaustive.type}`);
1219
+ }
1220
+ }
1221
+ }
1222
+ }
1223
+ function bytesToBase64(bytes) {
1224
+ // Same approach as core/internal-utils.ts to stay browser-friendly.
1225
+ let binary = "";
1226
+ for (let i = 0; i < bytes.length; i++) {
1227
+ binary += String.fromCharCode(bytes[i]);
1228
+ }
1229
+ if (typeof globalThis.btoa === "function") {
1230
+ return globalThis.btoa(binary);
1231
+ }
1232
+ // Node fallback
1233
+ const buf = globalThis.Buffer;
1234
+ if (buf) {
1235
+ return buf.from(binary, "binary").toString("base64");
1236
+ }
1237
+ throw new Error("btoa / Buffer unavailable; cannot encode image data");
1238
+ }