@cj-tech-master/excelts 9.4.2 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (618) hide show
  1. package/dist/browser/index.browser.d.ts +8 -5
  2. package/dist/browser/index.browser.js +19 -1
  3. package/dist/browser/index.d.ts +4 -2
  4. package/dist/browser/index.js +9 -1
  5. package/dist/browser/modules/excel/chart/cache-populator.d.ts +49 -0
  6. package/dist/browser/modules/excel/chart/cache-populator.js +1171 -0
  7. package/dist/browser/modules/excel/chart/chart-api.d.ts +92 -0
  8. package/dist/browser/modules/excel/chart/chart-api.js +364 -0
  9. package/dist/browser/modules/excel/chart/chart-builder.d.ts +48 -0
  10. package/dist/browser/modules/excel/chart/chart-builder.js +2432 -0
  11. package/dist/browser/modules/excel/chart/chart-ex-builder.d.ts +36 -0
  12. package/dist/browser/modules/excel/chart/chart-ex-builder.js +903 -0
  13. package/dist/browser/modules/excel/chart/chart-ex-parser.d.ts +8 -0
  14. package/dist/browser/modules/excel/chart/chart-ex-parser.js +1205 -0
  15. package/dist/browser/modules/excel/chart/chart-ex-renderer.d.ts +187 -0
  16. package/dist/browser/modules/excel/chart/chart-ex-renderer.js +5352 -0
  17. package/dist/browser/modules/excel/chart/chart-ex-types.d.ts +531 -0
  18. package/dist/browser/modules/excel/chart/chart-ex-types.js +11 -0
  19. package/dist/browser/modules/excel/chart/chart-images.d.ts +78 -0
  20. package/dist/browser/modules/excel/chart/chart-images.js +363 -0
  21. package/dist/browser/modules/excel/chart/chart-presets.d.ts +392 -0
  22. package/dist/browser/modules/excel/chart/chart-presets.js +179 -0
  23. package/dist/browser/modules/excel/chart/chart-renderer.d.ts +550 -0
  24. package/dist/browser/modules/excel/chart/chart-renderer.js +6440 -0
  25. package/dist/browser/modules/excel/chart/chart-sidecar.d.ts +21 -0
  26. package/dist/browser/modules/excel/chart/chart-sidecar.js +427 -0
  27. package/dist/browser/modules/excel/chart/chart-utils.d.ts +306 -0
  28. package/dist/browser/modules/excel/chart/chart-utils.js +821 -0
  29. package/dist/browser/modules/excel/chart/chart.d.ts +504 -0
  30. package/dist/browser/modules/excel/chart/chart.js +1320 -0
  31. package/dist/browser/modules/excel/chart/glyph-rasterizer.d.ts +62 -0
  32. package/dist/browser/modules/excel/chart/glyph-rasterizer.js +658 -0
  33. package/dist/browser/modules/excel/chart/index.d.ts +54 -0
  34. package/dist/browser/modules/excel/chart/index.js +46 -0
  35. package/dist/browser/modules/excel/chart/install.d.ts +44 -0
  36. package/dist/browser/modules/excel/chart/install.js +91 -0
  37. package/dist/browser/modules/excel/chart/shape-properties.d.ts +156 -0
  38. package/dist/browser/modules/excel/chart/shape-properties.js +1557 -0
  39. package/dist/browser/modules/excel/chart/stroke-font.d.ts +36 -0
  40. package/dist/browser/modules/excel/chart/stroke-font.js +1556 -0
  41. package/dist/browser/modules/excel/chart/topojson.d.ts +98 -0
  42. package/dist/browser/modules/excel/chart/topojson.js +236 -0
  43. package/dist/browser/modules/excel/chart/types.d.ts +2559 -0
  44. package/dist/browser/modules/excel/chart/types.js +8 -0
  45. package/dist/browser/modules/excel/chart-host-registry.d.ts +157 -0
  46. package/dist/browser/modules/excel/chart-host-registry.js +90 -0
  47. package/dist/browser/modules/excel/chartsheet.d.ts +102 -0
  48. package/dist/browser/modules/excel/chartsheet.js +196 -0
  49. package/dist/browser/modules/excel/defined-names.d.ts +35 -0
  50. package/dist/browser/modules/excel/defined-names.js +44 -4
  51. package/dist/browser/modules/excel/errors.d.ts +6 -0
  52. package/dist/browser/modules/excel/errors.js +9 -0
  53. package/dist/browser/modules/excel/form-control.d.ts +6 -0
  54. package/dist/browser/modules/excel/form-control.js +17 -0
  55. package/dist/browser/modules/excel/image.js +12 -2
  56. package/dist/browser/modules/excel/pivot-chart.d.ts +7 -0
  57. package/dist/browser/modules/excel/pivot-chart.js +53 -0
  58. package/dist/browser/modules/excel/pivot-table.d.ts +55 -0
  59. package/dist/browser/modules/excel/pivot-table.js +35 -0
  60. package/dist/browser/modules/excel/range.js +5 -1
  61. package/dist/browser/modules/excel/sparkline/index.d.ts +7 -0
  62. package/dist/browser/modules/excel/sparkline/index.js +7 -0
  63. package/dist/browser/modules/excel/sparkline/sparkline.d.ts +206 -0
  64. package/dist/browser/modules/excel/sparkline/sparkline.js +750 -0
  65. package/dist/browser/modules/excel/stream/worksheet-writer.js +3 -2
  66. package/dist/browser/modules/excel/table.js +42 -6
  67. package/dist/browser/modules/excel/types.d.ts +72 -0
  68. package/dist/browser/modules/excel/utils/address.d.ts +18 -0
  69. package/dist/browser/modules/excel/utils/address.js +28 -0
  70. package/dist/browser/modules/excel/utils/drawing-utils.js +11 -6
  71. package/dist/browser/modules/excel/utils/guid.d.ts +15 -0
  72. package/dist/browser/modules/excel/utils/guid.js +35 -0
  73. package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +74 -0
  74. package/dist/browser/modules/excel/utils/ooxml-paths.js +206 -9
  75. package/dist/browser/modules/excel/utils/ooxml-validator/check-chart-sidecar.d.ts +35 -0
  76. package/dist/browser/modules/excel/utils/ooxml-validator/check-chart-sidecar.js +101 -0
  77. package/dist/browser/modules/excel/utils/ooxml-validator/check-chart.d.ts +32 -0
  78. package/dist/browser/modules/excel/utils/ooxml-validator/check-chart.js +2125 -0
  79. package/dist/browser/modules/excel/utils/ooxml-validator/check-chartsheet.d.ts +9 -0
  80. package/dist/browser/modules/excel/utils/ooxml-validator/check-chartsheet.js +26 -0
  81. package/dist/browser/modules/excel/utils/ooxml-validator/check-content-types.d.ts +16 -0
  82. package/dist/browser/modules/excel/utils/ooxml-validator/check-content-types.js +181 -0
  83. package/dist/browser/modules/excel/utils/ooxml-validator/check-drawing.d.ts +34 -0
  84. package/dist/browser/modules/excel/utils/ooxml-validator/check-drawing.js +267 -0
  85. package/dist/browser/modules/excel/utils/ooxml-validator/check-pivot.d.ts +14 -0
  86. package/dist/browser/modules/excel/utils/ooxml-validator/check-pivot.js +104 -0
  87. package/dist/browser/modules/excel/utils/ooxml-validator/check-relationships.d.ts +18 -0
  88. package/dist/browser/modules/excel/utils/ooxml-validator/check-relationships.js +184 -0
  89. package/dist/browser/modules/excel/utils/ooxml-validator/check-structure.d.ts +21 -0
  90. package/dist/browser/modules/excel/utils/ooxml-validator/check-structure.js +56 -0
  91. package/dist/browser/modules/excel/utils/ooxml-validator/check-styles.d.ts +15 -0
  92. package/dist/browser/modules/excel/utils/ooxml-validator/check-styles.js +89 -0
  93. package/dist/browser/modules/excel/utils/ooxml-validator/check-table.d.ts +31 -0
  94. package/dist/browser/modules/excel/utils/ooxml-validator/check-table.js +177 -0
  95. package/dist/browser/modules/excel/utils/ooxml-validator/check-workbook.d.ts +19 -0
  96. package/dist/browser/modules/excel/utils/ooxml-validator/check-workbook.js +163 -0
  97. package/dist/browser/modules/excel/utils/ooxml-validator/check-worksheet.d.ts +25 -0
  98. package/dist/browser/modules/excel/utils/ooxml-validator/check-worksheet.js +569 -0
  99. package/dist/browser/modules/excel/utils/ooxml-validator/context.d.ts +85 -0
  100. package/dist/browser/modules/excel/utils/ooxml-validator/context.js +191 -0
  101. package/dist/browser/modules/excel/utils/ooxml-validator/index.d.ts +31 -0
  102. package/dist/browser/modules/excel/utils/ooxml-validator/index.js +102 -0
  103. package/dist/browser/modules/excel/utils/ooxml-validator/path-utils.d.ts +67 -0
  104. package/dist/browser/modules/excel/utils/ooxml-validator/path-utils.js +156 -0
  105. package/dist/browser/modules/excel/utils/ooxml-validator/reporter.d.ts +41 -0
  106. package/dist/browser/modules/excel/utils/ooxml-validator/reporter.js +61 -0
  107. package/dist/browser/modules/excel/utils/ooxml-validator/types.d.ts +109 -0
  108. package/dist/browser/modules/excel/utils/ooxml-validator/types.js +12 -0
  109. package/dist/browser/modules/excel/utils/ooxml-validator/xml-utils.d.ts +38 -0
  110. package/dist/browser/modules/excel/utils/ooxml-validator/xml-utils.js +100 -0
  111. package/dist/browser/modules/excel/workbook.browser.d.ts +248 -30
  112. package/dist/browser/modules/excel/workbook.browser.js +966 -31
  113. package/dist/browser/modules/excel/workbook.d.ts +43 -0
  114. package/dist/browser/modules/excel/workbook.js +48 -0
  115. package/dist/browser/modules/excel/worksheet.d.ts +157 -3
  116. package/dist/browser/modules/excel/worksheet.js +394 -35
  117. package/dist/browser/modules/excel/xlsx/rel-type.d.ts +40 -0
  118. package/dist/browser/modules/excel/xlsx/rel-type.js +41 -1
  119. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +1 -0
  120. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +11 -2
  121. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +12 -10
  122. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +96 -22
  123. package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.d.ts +353 -0
  124. package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.js +6000 -0
  125. package/dist/browser/modules/excel/xlsx/xform/comment/threaded-comments-xform.d.ts +60 -0
  126. package/dist/browser/modules/excel/xlsx/xform/comment/threaded-comments-xform.js +213 -0
  127. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +150 -11
  128. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +20 -1
  129. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  130. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +30 -0
  131. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +109 -5
  132. package/dist/browser/modules/excel/xlsx/xform/drawing/graphic-frame-xform.d.ts +54 -0
  133. package/dist/browser/modules/excel/xlsx/xform/drawing/graphic-frame-xform.js +225 -0
  134. package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +3 -1
  135. package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +18 -3
  136. package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +46 -0
  137. package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +294 -12
  138. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +13 -2
  139. package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +32 -6
  140. package/dist/browser/modules/excel/xlsx/xform/sheet/chartsheet-xform.d.ts +185 -0
  141. package/dist/browser/modules/excel/xlsx/xform/sheet/chartsheet-xform.js +441 -0
  142. package/dist/browser/modules/excel/xlsx/xform/sheet/ext-lst-xform.d.ts +1 -0
  143. package/dist/browser/modules/excel/xlsx/xform/sheet/ext-lst-xform.js +51 -2
  144. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +196 -20
  145. package/dist/browser/modules/excel/xlsx/xform/table/auto-filter-xform.js +16 -1
  146. package/dist/browser/modules/excel/xlsx/xform/table/table-column-xform.js +17 -2
  147. package/dist/browser/modules/excel/xlsx/xform/xsd-values.d.ts +63 -0
  148. package/dist/browser/modules/excel/xlsx/xform/xsd-values.js +101 -0
  149. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +115 -21
  150. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +4422 -78
  151. package/dist/browser/modules/pdf/builder/document-builder.d.ts +74 -0
  152. package/dist/browser/modules/pdf/builder/document-builder.js +507 -2
  153. package/dist/browser/modules/pdf/builder/pdf-editor.js +48 -3
  154. package/dist/browser/modules/pdf/excel-bridge.d.ts +69 -0
  155. package/dist/browser/modules/pdf/excel-bridge.js +683 -12
  156. package/dist/browser/modules/pdf/font/font-manager.d.ts +25 -0
  157. package/dist/browser/modules/pdf/font/font-manager.js +39 -0
  158. package/dist/browser/modules/pdf/index.d.ts +5 -2
  159. package/dist/browser/modules/pdf/index.js +3 -1
  160. package/dist/browser/modules/pdf/render/chart-surface.d.ts +33 -0
  161. package/dist/browser/modules/pdf/render/chart-surface.js +200 -0
  162. package/dist/browser/modules/pdf/render/layout-engine.d.ts +22 -1
  163. package/dist/browser/modules/pdf/render/layout-engine.js +436 -56
  164. package/dist/browser/modules/pdf/render/page-renderer.js +169 -28
  165. package/dist/browser/modules/pdf/render/pdf-exporter.js +117 -7
  166. package/dist/browser/modules/pdf/types.d.ts +227 -23
  167. package/dist/browser/modules/pdf/types.js +4 -0
  168. package/dist/browser/modules/pdf/word-bridge.d.ts +47 -0
  169. package/dist/browser/modules/pdf/word-bridge.js +304 -0
  170. package/dist/browser/modules/word/constants.d.ts +179 -0
  171. package/dist/browser/modules/word/constants.js +231 -0
  172. package/dist/browser/modules/word/content-types.d.ts +27 -0
  173. package/dist/browser/modules/word/content-types.js +53 -0
  174. package/dist/browser/modules/word/digital-signatures.d.ts +87 -0
  175. package/dist/browser/modules/word/digital-signatures.js +134 -0
  176. package/dist/browser/modules/word/document.d.ts +728 -0
  177. package/dist/browser/modules/word/document.js +1795 -0
  178. package/dist/browser/modules/word/docx-packager.d.ts +14 -0
  179. package/dist/browser/modules/word/docx-packager.js +822 -0
  180. package/dist/browser/modules/word/docx-reader.d.ts +11 -0
  181. package/dist/browser/modules/word/docx-reader.js +4929 -0
  182. package/dist/browser/modules/word/encryption.d.ts +102 -0
  183. package/dist/browser/modules/word/encryption.js +274 -0
  184. package/dist/browser/modules/word/errors.d.ts +49 -0
  185. package/dist/browser/modules/word/errors.js +68 -0
  186. package/dist/browser/modules/word/font-obfuscation.d.ts +31 -0
  187. package/dist/browser/modules/word/font-obfuscation.js +83 -0
  188. package/dist/browser/modules/word/html-renderer.d.ts +38 -0
  189. package/dist/browser/modules/word/html-renderer.js +782 -0
  190. package/dist/browser/modules/word/index.base.d.ts +19 -0
  191. package/dist/browser/modules/word/index.base.js +51 -0
  192. package/dist/browser/modules/word/index.browser.d.ts +4 -0
  193. package/dist/browser/modules/word/index.browser.js +4 -0
  194. package/dist/browser/modules/word/index.d.ts +4 -0
  195. package/dist/browser/modules/word/index.js +4 -0
  196. package/dist/browser/modules/word/internal-utils.d.ts +23 -0
  197. package/dist/browser/modules/word/internal-utils.js +54 -0
  198. package/dist/browser/modules/word/relationships.d.ts +31 -0
  199. package/dist/browser/modules/word/relationships.js +56 -0
  200. package/dist/browser/modules/word/types.d.ts +2325 -0
  201. package/dist/browser/modules/word/types.js +10 -0
  202. package/dist/browser/modules/word/units.d.ts +49 -0
  203. package/dist/browser/modules/word/units.js +111 -0
  204. package/dist/browser/modules/word/writers/chart-writer.d.ts +10 -0
  205. package/dist/browser/modules/word/writers/chart-writer.js +385 -0
  206. package/dist/browser/modules/word/writers/checkbox-writer.d.ts +9 -0
  207. package/dist/browser/modules/word/writers/checkbox-writer.js +42 -0
  208. package/dist/browser/modules/word/writers/comment-writer.d.ts +15 -0
  209. package/dist/browser/modules/word/writers/comment-writer.js +70 -0
  210. package/dist/browser/modules/word/writers/document-writer.d.ts +16 -0
  211. package/dist/browser/modules/word/writers/document-writer.js +461 -0
  212. package/dist/browser/modules/word/writers/footnote-writer.d.ts +11 -0
  213. package/dist/browser/modules/word/writers/footnote-writer.js +72 -0
  214. package/dist/browser/modules/word/writers/header-footer-writer.d.ts +13 -0
  215. package/dist/browser/modules/word/writers/header-footer-writer.js +129 -0
  216. package/dist/browser/modules/word/writers/image-writer.d.ts +10 -0
  217. package/dist/browser/modules/word/writers/image-writer.js +185 -0
  218. package/dist/browser/modules/word/writers/math-writer.d.ts +9 -0
  219. package/dist/browser/modules/word/writers/math-writer.js +428 -0
  220. package/dist/browser/modules/word/writers/numbering-writer.d.ts +10 -0
  221. package/dist/browser/modules/word/writers/numbering-writer.js +125 -0
  222. package/dist/browser/modules/word/writers/paragraph-writer.d.ts +13 -0
  223. package/dist/browser/modules/word/writers/paragraph-writer.js +516 -0
  224. package/dist/browser/modules/word/writers/parts-writer.d.ts +26 -0
  225. package/dist/browser/modules/word/writers/parts-writer.js +660 -0
  226. package/dist/browser/modules/word/writers/run-writer.d.ts +15 -0
  227. package/dist/browser/modules/word/writers/run-writer.js +649 -0
  228. package/dist/browser/modules/word/writers/section-writer.d.ts +10 -0
  229. package/dist/browser/modules/word/writers/section-writer.js +238 -0
  230. package/dist/browser/modules/word/writers/styles-writer.d.ts +10 -0
  231. package/dist/browser/modules/word/writers/styles-writer.js +242 -0
  232. package/dist/browser/modules/word/writers/table-writer.d.ts +10 -0
  233. package/dist/browser/modules/word/writers/table-writer.js +503 -0
  234. package/dist/browser/modules/word/writers/textbox-writer.d.ts +9 -0
  235. package/dist/browser/modules/word/writers/textbox-writer.js +53 -0
  236. package/dist/browser/modules/word/writers/toc-writer.d.ts +9 -0
  237. package/dist/browser/modules/word/writers/toc-writer.js +79 -0
  238. package/dist/browser/modules/xml/encode.d.ts +56 -7
  239. package/dist/browser/modules/xml/encode.js +157 -11
  240. package/dist/cjs/index.js +13 -2
  241. package/dist/cjs/modules/excel/chart/cache-populator.js +1178 -0
  242. package/dist/cjs/modules/excel/chart/chart-api.js +371 -0
  243. package/dist/cjs/modules/excel/chart/chart-builder.js +2440 -0
  244. package/dist/cjs/modules/excel/chart/chart-ex-builder.js +907 -0
  245. package/dist/cjs/modules/excel/chart/chart-ex-parser.js +1208 -0
  246. package/dist/cjs/modules/excel/chart/chart-ex-renderer.js +5364 -0
  247. package/dist/cjs/modules/excel/chart/chart-ex-types.js +12 -0
  248. package/dist/cjs/modules/excel/chart/chart-images.js +366 -0
  249. package/dist/cjs/modules/excel/chart/chart-presets.js +184 -0
  250. package/dist/cjs/modules/excel/chart/chart-renderer.js +6450 -0
  251. package/dist/cjs/modules/excel/chart/chart-sidecar.js +433 -0
  252. package/dist/cjs/modules/excel/chart/chart-utils.js +845 -0
  253. package/dist/cjs/modules/excel/chart/chart.js +1324 -0
  254. package/dist/cjs/modules/excel/chart/glyph-rasterizer.js +664 -0
  255. package/dist/cjs/modules/excel/chart/index.js +101 -0
  256. package/dist/cjs/modules/excel/chart/install.js +95 -0
  257. package/dist/cjs/modules/excel/chart/shape-properties.js +1577 -0
  258. package/dist/cjs/modules/excel/chart/stroke-font.js +1559 -0
  259. package/dist/cjs/modules/excel/chart/topojson.js +239 -0
  260. package/dist/cjs/modules/excel/chart/types.js +9 -0
  261. package/dist/cjs/modules/excel/chart-host-registry.js +96 -0
  262. package/dist/cjs/modules/excel/chartsheet.js +199 -0
  263. package/dist/cjs/modules/excel/defined-names.js +44 -4
  264. package/dist/cjs/modules/excel/errors.js +11 -1
  265. package/dist/cjs/modules/excel/form-control.js +17 -0
  266. package/dist/cjs/modules/excel/image.js +12 -2
  267. package/dist/cjs/modules/excel/pivot-chart.js +56 -0
  268. package/dist/cjs/modules/excel/pivot-table.js +35 -0
  269. package/dist/cjs/modules/excel/range.js +5 -1
  270. package/dist/cjs/modules/excel/sparkline/index.js +23 -0
  271. package/dist/cjs/modules/excel/sparkline/sparkline.js +756 -0
  272. package/dist/cjs/modules/excel/stream/worksheet-writer.js +3 -2
  273. package/dist/cjs/modules/excel/table.js +42 -6
  274. package/dist/cjs/modules/excel/utils/address.js +29 -0
  275. package/dist/cjs/modules/excel/utils/drawing-utils.js +11 -6
  276. package/dist/cjs/modules/excel/utils/guid.js +38 -0
  277. package/dist/cjs/modules/excel/utils/ooxml-paths.js +246 -9
  278. package/dist/cjs/modules/excel/utils/ooxml-validator/check-chart-sidecar.js +103 -0
  279. package/dist/cjs/modules/excel/utils/ooxml-validator/check-chart.js +2128 -0
  280. package/dist/cjs/modules/excel/utils/ooxml-validator/check-chartsheet.js +29 -0
  281. package/dist/cjs/modules/excel/utils/ooxml-validator/check-content-types.js +184 -0
  282. package/dist/cjs/modules/excel/utils/ooxml-validator/check-drawing.js +270 -0
  283. package/dist/cjs/modules/excel/utils/ooxml-validator/check-pivot.js +107 -0
  284. package/dist/cjs/modules/excel/utils/ooxml-validator/check-relationships.js +188 -0
  285. package/dist/cjs/modules/excel/utils/ooxml-validator/check-structure.js +60 -0
  286. package/dist/cjs/modules/excel/utils/ooxml-validator/check-styles.js +92 -0
  287. package/dist/cjs/modules/excel/utils/ooxml-validator/check-table.js +180 -0
  288. package/dist/cjs/modules/excel/utils/ooxml-validator/check-workbook.js +166 -0
  289. package/dist/cjs/modules/excel/utils/ooxml-validator/check-worksheet.js +572 -0
  290. package/dist/cjs/modules/excel/utils/ooxml-validator/context.js +196 -0
  291. package/dist/cjs/modules/excel/utils/ooxml-validator/index.js +105 -0
  292. package/dist/cjs/modules/excel/utils/ooxml-validator/path-utils.js +168 -0
  293. package/dist/cjs/modules/excel/utils/ooxml-validator/reporter.js +66 -0
  294. package/dist/cjs/modules/excel/utils/ooxml-validator/types.js +13 -0
  295. package/dist/cjs/modules/excel/utils/ooxml-validator/xml-utils.js +110 -0
  296. package/dist/cjs/modules/excel/workbook.browser.js +973 -38
  297. package/dist/cjs/modules/excel/workbook.js +48 -0
  298. package/dist/cjs/modules/excel/worksheet.js +393 -34
  299. package/dist/cjs/modules/excel/xlsx/rel-type.js +41 -1
  300. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +11 -2
  301. package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +12 -10
  302. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +96 -22
  303. package/dist/cjs/modules/excel/xlsx/xform/chart/chart-space-xform.js +6003 -0
  304. package/dist/cjs/modules/excel/xlsx/xform/comment/threaded-comments-xform.js +219 -0
  305. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +149 -10
  306. package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +20 -1
  307. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  308. package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +109 -5
  309. package/dist/cjs/modules/excel/xlsx/xform/drawing/graphic-frame-xform.js +228 -0
  310. package/dist/cjs/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +18 -3
  311. package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +294 -12
  312. package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +32 -6
  313. package/dist/cjs/modules/excel/xlsx/xform/sheet/chartsheet-xform.js +444 -0
  314. package/dist/cjs/modules/excel/xlsx/xform/sheet/ext-lst-xform.js +51 -2
  315. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +195 -19
  316. package/dist/cjs/modules/excel/xlsx/xform/table/auto-filter-xform.js +16 -1
  317. package/dist/cjs/modules/excel/xlsx/xform/table/table-column-xform.js +17 -2
  318. package/dist/cjs/modules/excel/xlsx/xform/xsd-values.js +106 -0
  319. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +4420 -76
  320. package/dist/cjs/modules/pdf/builder/document-builder.js +506 -1
  321. package/dist/cjs/modules/pdf/builder/pdf-editor.js +48 -3
  322. package/dist/cjs/modules/pdf/excel-bridge.js +684 -12
  323. package/dist/cjs/modules/pdf/font/font-manager.js +39 -0
  324. package/dist/cjs/modules/pdf/index.js +5 -1
  325. package/dist/cjs/modules/pdf/render/chart-surface.js +203 -0
  326. package/dist/cjs/modules/pdf/render/layout-engine.js +437 -56
  327. package/dist/cjs/modules/pdf/render/page-renderer.js +169 -28
  328. package/dist/cjs/modules/pdf/render/pdf-exporter.js +115 -5
  329. package/dist/cjs/modules/pdf/types.js +5 -0
  330. package/dist/cjs/modules/pdf/word-bridge.js +307 -0
  331. package/dist/cjs/modules/word/constants.js +234 -0
  332. package/dist/cjs/modules/word/content-types.js +57 -0
  333. package/dist/cjs/modules/word/digital-signatures.js +140 -0
  334. package/dist/cjs/modules/word/document.js +1909 -0
  335. package/dist/cjs/modules/word/docx-packager.js +825 -0
  336. package/dist/cjs/modules/word/docx-reader.js +4932 -0
  337. package/dist/cjs/modules/word/encryption.js +282 -0
  338. package/dist/cjs/modules/word/errors.js +88 -0
  339. package/dist/cjs/modules/word/font-obfuscation.js +88 -0
  340. package/dist/cjs/modules/word/html-renderer.js +785 -0
  341. package/dist/cjs/modules/word/index.base.js +199 -0
  342. package/dist/cjs/modules/word/index.browser.js +20 -0
  343. package/dist/cjs/modules/word/index.js +20 -0
  344. package/dist/cjs/modules/word/internal-utils.js +59 -0
  345. package/dist/cjs/modules/word/relationships.js +60 -0
  346. package/dist/cjs/modules/word/types.js +11 -0
  347. package/dist/cjs/modules/word/units.js +135 -0
  348. package/dist/cjs/modules/word/writers/chart-writer.js +388 -0
  349. package/dist/cjs/modules/word/writers/checkbox-writer.js +45 -0
  350. package/dist/cjs/modules/word/writers/comment-writer.js +74 -0
  351. package/dist/cjs/modules/word/writers/document-writer.js +465 -0
  352. package/dist/cjs/modules/word/writers/footnote-writer.js +76 -0
  353. package/dist/cjs/modules/word/writers/header-footer-writer.js +134 -0
  354. package/dist/cjs/modules/word/writers/image-writer.js +188 -0
  355. package/dist/cjs/modules/word/writers/math-writer.js +431 -0
  356. package/dist/cjs/modules/word/writers/numbering-writer.js +128 -0
  357. package/dist/cjs/modules/word/writers/paragraph-writer.js +521 -0
  358. package/dist/cjs/modules/word/writers/parts-writer.js +671 -0
  359. package/dist/cjs/modules/word/writers/run-writer.js +655 -0
  360. package/dist/cjs/modules/word/writers/section-writer.js +241 -0
  361. package/dist/cjs/modules/word/writers/styles-writer.js +245 -0
  362. package/dist/cjs/modules/word/writers/table-writer.js +506 -0
  363. package/dist/cjs/modules/word/writers/textbox-writer.js +56 -0
  364. package/dist/cjs/modules/word/writers/toc-writer.js +82 -0
  365. package/dist/cjs/modules/xml/encode.js +158 -11
  366. package/dist/esm/index.browser.js +20 -2
  367. package/dist/esm/index.js +9 -1
  368. package/dist/esm/modules/excel/chart/cache-populator.js +1171 -0
  369. package/dist/esm/modules/excel/chart/chart-api.js +364 -0
  370. package/dist/esm/modules/excel/chart/chart-builder.js +2432 -0
  371. package/dist/esm/modules/excel/chart/chart-ex-builder.js +903 -0
  372. package/dist/esm/modules/excel/chart/chart-ex-parser.js +1205 -0
  373. package/dist/esm/modules/excel/chart/chart-ex-renderer.js +5352 -0
  374. package/dist/esm/modules/excel/chart/chart-ex-types.js +11 -0
  375. package/dist/esm/modules/excel/chart/chart-images.js +363 -0
  376. package/dist/esm/modules/excel/chart/chart-presets.js +179 -0
  377. package/dist/esm/modules/excel/chart/chart-renderer.js +6440 -0
  378. package/dist/esm/modules/excel/chart/chart-sidecar.js +427 -0
  379. package/dist/esm/modules/excel/chart/chart-utils.js +821 -0
  380. package/dist/esm/modules/excel/chart/chart.js +1320 -0
  381. package/dist/esm/modules/excel/chart/glyph-rasterizer.js +658 -0
  382. package/dist/esm/modules/excel/chart/index.js +46 -0
  383. package/dist/esm/modules/excel/chart/install.js +91 -0
  384. package/dist/esm/modules/excel/chart/shape-properties.js +1557 -0
  385. package/dist/esm/modules/excel/chart/stroke-font.js +1556 -0
  386. package/dist/esm/modules/excel/chart/topojson.js +236 -0
  387. package/dist/esm/modules/excel/chart/types.js +8 -0
  388. package/dist/esm/modules/excel/chart-host-registry.js +90 -0
  389. package/dist/esm/modules/excel/chartsheet.js +196 -0
  390. package/dist/esm/modules/excel/defined-names.js +44 -4
  391. package/dist/esm/modules/excel/errors.js +9 -0
  392. package/dist/esm/modules/excel/form-control.js +17 -0
  393. package/dist/esm/modules/excel/image.js +12 -2
  394. package/dist/esm/modules/excel/pivot-chart.js +53 -0
  395. package/dist/esm/modules/excel/pivot-table.js +35 -0
  396. package/dist/esm/modules/excel/range.js +5 -1
  397. package/dist/esm/modules/excel/sparkline/index.js +7 -0
  398. package/dist/esm/modules/excel/sparkline/sparkline.js +750 -0
  399. package/dist/esm/modules/excel/stream/worksheet-writer.js +3 -2
  400. package/dist/esm/modules/excel/table.js +42 -6
  401. package/dist/esm/modules/excel/utils/address.js +28 -0
  402. package/dist/esm/modules/excel/utils/drawing-utils.js +11 -6
  403. package/dist/esm/modules/excel/utils/guid.js +35 -0
  404. package/dist/esm/modules/excel/utils/ooxml-paths.js +206 -9
  405. package/dist/esm/modules/excel/utils/ooxml-validator/check-chart-sidecar.js +101 -0
  406. package/dist/esm/modules/excel/utils/ooxml-validator/check-chart.js +2125 -0
  407. package/dist/esm/modules/excel/utils/ooxml-validator/check-chartsheet.js +26 -0
  408. package/dist/esm/modules/excel/utils/ooxml-validator/check-content-types.js +181 -0
  409. package/dist/esm/modules/excel/utils/ooxml-validator/check-drawing.js +267 -0
  410. package/dist/esm/modules/excel/utils/ooxml-validator/check-pivot.js +104 -0
  411. package/dist/esm/modules/excel/utils/ooxml-validator/check-relationships.js +184 -0
  412. package/dist/esm/modules/excel/utils/ooxml-validator/check-structure.js +56 -0
  413. package/dist/esm/modules/excel/utils/ooxml-validator/check-styles.js +89 -0
  414. package/dist/esm/modules/excel/utils/ooxml-validator/check-table.js +177 -0
  415. package/dist/esm/modules/excel/utils/ooxml-validator/check-workbook.js +163 -0
  416. package/dist/esm/modules/excel/utils/ooxml-validator/check-worksheet.js +569 -0
  417. package/dist/esm/modules/excel/utils/ooxml-validator/context.js +191 -0
  418. package/dist/esm/modules/excel/utils/ooxml-validator/index.js +102 -0
  419. package/dist/esm/modules/excel/utils/ooxml-validator/path-utils.js +156 -0
  420. package/dist/esm/modules/excel/utils/ooxml-validator/reporter.js +61 -0
  421. package/dist/esm/modules/excel/utils/ooxml-validator/types.js +12 -0
  422. package/dist/esm/modules/excel/utils/ooxml-validator/xml-utils.js +100 -0
  423. package/dist/esm/modules/excel/workbook.browser.js +969 -34
  424. package/dist/esm/modules/excel/workbook.js +48 -0
  425. package/dist/esm/modules/excel/worksheet.js +394 -35
  426. package/dist/esm/modules/excel/xlsx/rel-type.js +41 -1
  427. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +11 -2
  428. package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +12 -10
  429. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +96 -22
  430. package/dist/esm/modules/excel/xlsx/xform/chart/chart-space-xform.js +6000 -0
  431. package/dist/esm/modules/excel/xlsx/xform/comment/threaded-comments-xform.js +213 -0
  432. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +150 -11
  433. package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +20 -1
  434. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
  435. package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +109 -5
  436. package/dist/esm/modules/excel/xlsx/xform/drawing/graphic-frame-xform.js +225 -0
  437. package/dist/esm/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +18 -3
  438. package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +294 -12
  439. package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +32 -6
  440. package/dist/esm/modules/excel/xlsx/xform/sheet/chartsheet-xform.js +441 -0
  441. package/dist/esm/modules/excel/xlsx/xform/sheet/ext-lst-xform.js +51 -2
  442. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +196 -20
  443. package/dist/esm/modules/excel/xlsx/xform/table/auto-filter-xform.js +16 -1
  444. package/dist/esm/modules/excel/xlsx/xform/table/table-column-xform.js +17 -2
  445. package/dist/esm/modules/excel/xlsx/xform/xsd-values.js +101 -0
  446. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +4422 -78
  447. package/dist/esm/modules/pdf/builder/document-builder.js +507 -2
  448. package/dist/esm/modules/pdf/builder/pdf-editor.js +48 -3
  449. package/dist/esm/modules/pdf/excel-bridge.js +683 -12
  450. package/dist/esm/modules/pdf/font/font-manager.js +39 -0
  451. package/dist/esm/modules/pdf/index.js +3 -1
  452. package/dist/esm/modules/pdf/render/chart-surface.js +200 -0
  453. package/dist/esm/modules/pdf/render/layout-engine.js +436 -56
  454. package/dist/esm/modules/pdf/render/page-renderer.js +169 -28
  455. package/dist/esm/modules/pdf/render/pdf-exporter.js +117 -7
  456. package/dist/esm/modules/pdf/types.js +4 -0
  457. package/dist/esm/modules/pdf/word-bridge.js +304 -0
  458. package/dist/esm/modules/word/constants.js +231 -0
  459. package/dist/esm/modules/word/content-types.js +53 -0
  460. package/dist/esm/modules/word/digital-signatures.js +134 -0
  461. package/dist/esm/modules/word/document.js +1795 -0
  462. package/dist/esm/modules/word/docx-packager.js +822 -0
  463. package/dist/esm/modules/word/docx-reader.js +4929 -0
  464. package/dist/esm/modules/word/encryption.js +274 -0
  465. package/dist/esm/modules/word/errors.js +68 -0
  466. package/dist/esm/modules/word/font-obfuscation.js +83 -0
  467. package/dist/esm/modules/word/html-renderer.js +782 -0
  468. package/dist/esm/modules/word/index.base.js +51 -0
  469. package/dist/esm/modules/word/index.browser.js +4 -0
  470. package/dist/esm/modules/word/index.js +4 -0
  471. package/dist/esm/modules/word/internal-utils.js +54 -0
  472. package/dist/esm/modules/word/relationships.js +56 -0
  473. package/dist/esm/modules/word/types.js +10 -0
  474. package/dist/esm/modules/word/units.js +111 -0
  475. package/dist/esm/modules/word/writers/chart-writer.js +385 -0
  476. package/dist/esm/modules/word/writers/checkbox-writer.js +42 -0
  477. package/dist/esm/modules/word/writers/comment-writer.js +70 -0
  478. package/dist/esm/modules/word/writers/document-writer.js +461 -0
  479. package/dist/esm/modules/word/writers/footnote-writer.js +72 -0
  480. package/dist/esm/modules/word/writers/header-footer-writer.js +129 -0
  481. package/dist/esm/modules/word/writers/image-writer.js +185 -0
  482. package/dist/esm/modules/word/writers/math-writer.js +428 -0
  483. package/dist/esm/modules/word/writers/numbering-writer.js +125 -0
  484. package/dist/esm/modules/word/writers/paragraph-writer.js +516 -0
  485. package/dist/esm/modules/word/writers/parts-writer.js +660 -0
  486. package/dist/esm/modules/word/writers/run-writer.js +649 -0
  487. package/dist/esm/modules/word/writers/section-writer.js +238 -0
  488. package/dist/esm/modules/word/writers/styles-writer.js +242 -0
  489. package/dist/esm/modules/word/writers/table-writer.js +503 -0
  490. package/dist/esm/modules/word/writers/textbox-writer.js +53 -0
  491. package/dist/esm/modules/word/writers/toc-writer.js +79 -0
  492. package/dist/esm/modules/xml/encode.js +157 -11
  493. package/dist/iife/excelts.iife.js +11789 -687
  494. package/dist/iife/excelts.iife.js.map +1 -1
  495. package/dist/iife/excelts.iife.min.js +52 -44
  496. package/dist/types/index.browser.d.ts +8 -5
  497. package/dist/types/index.d.ts +4 -2
  498. package/dist/types/modules/excel/chart/cache-populator.d.ts +49 -0
  499. package/dist/types/modules/excel/chart/chart-api.d.ts +92 -0
  500. package/dist/types/modules/excel/chart/chart-builder.d.ts +48 -0
  501. package/dist/types/modules/excel/chart/chart-ex-builder.d.ts +36 -0
  502. package/dist/types/modules/excel/chart/chart-ex-parser.d.ts +8 -0
  503. package/dist/types/modules/excel/chart/chart-ex-renderer.d.ts +187 -0
  504. package/dist/types/modules/excel/chart/chart-ex-types.d.ts +531 -0
  505. package/dist/types/modules/excel/chart/chart-images.d.ts +78 -0
  506. package/dist/types/modules/excel/chart/chart-presets.d.ts +392 -0
  507. package/dist/types/modules/excel/chart/chart-renderer.d.ts +550 -0
  508. package/dist/types/modules/excel/chart/chart-sidecar.d.ts +21 -0
  509. package/dist/types/modules/excel/chart/chart-utils.d.ts +306 -0
  510. package/dist/types/modules/excel/chart/chart.d.ts +504 -0
  511. package/dist/types/modules/excel/chart/glyph-rasterizer.d.ts +62 -0
  512. package/dist/types/modules/excel/chart/index.d.ts +54 -0
  513. package/dist/types/modules/excel/chart/install.d.ts +44 -0
  514. package/dist/types/modules/excel/chart/shape-properties.d.ts +156 -0
  515. package/dist/types/modules/excel/chart/stroke-font.d.ts +36 -0
  516. package/dist/types/modules/excel/chart/topojson.d.ts +98 -0
  517. package/dist/types/modules/excel/chart/types.d.ts +2559 -0
  518. package/dist/types/modules/excel/chart-host-registry.d.ts +157 -0
  519. package/dist/types/modules/excel/chartsheet.d.ts +102 -0
  520. package/dist/types/modules/excel/defined-names.d.ts +35 -0
  521. package/dist/types/modules/excel/errors.d.ts +6 -0
  522. package/dist/types/modules/excel/form-control.d.ts +6 -0
  523. package/dist/types/modules/excel/pivot-chart.d.ts +7 -0
  524. package/dist/types/modules/excel/pivot-table.d.ts +55 -0
  525. package/dist/types/modules/excel/sparkline/index.d.ts +7 -0
  526. package/dist/types/modules/excel/sparkline/sparkline.d.ts +206 -0
  527. package/dist/types/modules/excel/types.d.ts +72 -0
  528. package/dist/types/modules/excel/utils/address.d.ts +18 -0
  529. package/dist/types/modules/excel/utils/guid.d.ts +15 -0
  530. package/dist/types/modules/excel/utils/ooxml-paths.d.ts +74 -0
  531. package/dist/types/modules/excel/utils/ooxml-validator/check-chart-sidecar.d.ts +35 -0
  532. package/dist/types/modules/excel/utils/ooxml-validator/check-chart.d.ts +32 -0
  533. package/dist/types/modules/excel/utils/ooxml-validator/check-chartsheet.d.ts +9 -0
  534. package/dist/types/modules/excel/utils/ooxml-validator/check-content-types.d.ts +16 -0
  535. package/dist/types/modules/excel/utils/ooxml-validator/check-drawing.d.ts +34 -0
  536. package/dist/types/modules/excel/utils/ooxml-validator/check-pivot.d.ts +14 -0
  537. package/dist/types/modules/excel/utils/ooxml-validator/check-relationships.d.ts +18 -0
  538. package/dist/types/modules/excel/utils/ooxml-validator/check-structure.d.ts +21 -0
  539. package/dist/types/modules/excel/utils/ooxml-validator/check-styles.d.ts +15 -0
  540. package/dist/types/modules/excel/utils/ooxml-validator/check-table.d.ts +31 -0
  541. package/dist/types/modules/excel/utils/ooxml-validator/check-workbook.d.ts +19 -0
  542. package/dist/types/modules/excel/utils/ooxml-validator/check-worksheet.d.ts +25 -0
  543. package/dist/types/modules/excel/utils/ooxml-validator/context.d.ts +85 -0
  544. package/dist/types/modules/excel/utils/ooxml-validator/index.d.ts +31 -0
  545. package/dist/types/modules/excel/utils/ooxml-validator/path-utils.d.ts +67 -0
  546. package/dist/types/modules/excel/utils/ooxml-validator/reporter.d.ts +41 -0
  547. package/dist/types/modules/excel/utils/ooxml-validator/types.d.ts +109 -0
  548. package/dist/types/modules/excel/utils/ooxml-validator/xml-utils.d.ts +38 -0
  549. package/dist/types/modules/excel/workbook.browser.d.ts +248 -30
  550. package/dist/types/modules/excel/workbook.d.ts +43 -0
  551. package/dist/types/modules/excel/worksheet.d.ts +157 -3
  552. package/dist/types/modules/excel/xlsx/rel-type.d.ts +40 -0
  553. package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +1 -0
  554. package/dist/types/modules/excel/xlsx/xform/chart/chart-space-xform.d.ts +353 -0
  555. package/dist/types/modules/excel/xlsx/xform/comment/threaded-comments-xform.d.ts +60 -0
  556. package/dist/types/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +30 -0
  557. package/dist/types/modules/excel/xlsx/xform/drawing/graphic-frame-xform.d.ts +54 -0
  558. package/dist/types/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +3 -1
  559. package/dist/types/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +46 -0
  560. package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +13 -2
  561. package/dist/types/modules/excel/xlsx/xform/sheet/chartsheet-xform.d.ts +185 -0
  562. package/dist/types/modules/excel/xlsx/xform/sheet/ext-lst-xform.d.ts +1 -0
  563. package/dist/types/modules/excel/xlsx/xform/xsd-values.d.ts +63 -0
  564. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +115 -21
  565. package/dist/types/modules/pdf/builder/document-builder.d.ts +74 -0
  566. package/dist/types/modules/pdf/excel-bridge.d.ts +69 -0
  567. package/dist/types/modules/pdf/font/font-manager.d.ts +25 -0
  568. package/dist/types/modules/pdf/index.d.ts +5 -2
  569. package/dist/types/modules/pdf/render/chart-surface.d.ts +33 -0
  570. package/dist/types/modules/pdf/render/layout-engine.d.ts +22 -1
  571. package/dist/types/modules/pdf/types.d.ts +227 -23
  572. package/dist/types/modules/pdf/word-bridge.d.ts +47 -0
  573. package/dist/types/modules/word/constants.d.ts +179 -0
  574. package/dist/types/modules/word/content-types.d.ts +27 -0
  575. package/dist/types/modules/word/digital-signatures.d.ts +87 -0
  576. package/dist/types/modules/word/document.d.ts +728 -0
  577. package/dist/types/modules/word/docx-packager.d.ts +14 -0
  578. package/dist/types/modules/word/docx-reader.d.ts +11 -0
  579. package/dist/types/modules/word/encryption.d.ts +102 -0
  580. package/dist/types/modules/word/errors.d.ts +49 -0
  581. package/dist/types/modules/word/font-obfuscation.d.ts +31 -0
  582. package/dist/types/modules/word/html-renderer.d.ts +38 -0
  583. package/dist/types/modules/word/index.base.d.ts +19 -0
  584. package/dist/types/modules/word/index.browser.d.ts +4 -0
  585. package/dist/types/modules/word/index.d.ts +4 -0
  586. package/dist/types/modules/word/internal-utils.d.ts +23 -0
  587. package/dist/types/modules/word/relationships.d.ts +31 -0
  588. package/dist/types/modules/word/types.d.ts +2325 -0
  589. package/dist/types/modules/word/units.d.ts +49 -0
  590. package/dist/types/modules/word/writers/chart-writer.d.ts +10 -0
  591. package/dist/types/modules/word/writers/checkbox-writer.d.ts +9 -0
  592. package/dist/types/modules/word/writers/comment-writer.d.ts +15 -0
  593. package/dist/types/modules/word/writers/document-writer.d.ts +16 -0
  594. package/dist/types/modules/word/writers/footnote-writer.d.ts +11 -0
  595. package/dist/types/modules/word/writers/header-footer-writer.d.ts +13 -0
  596. package/dist/types/modules/word/writers/image-writer.d.ts +10 -0
  597. package/dist/types/modules/word/writers/math-writer.d.ts +9 -0
  598. package/dist/types/modules/word/writers/numbering-writer.d.ts +10 -0
  599. package/dist/types/modules/word/writers/paragraph-writer.d.ts +13 -0
  600. package/dist/types/modules/word/writers/parts-writer.d.ts +26 -0
  601. package/dist/types/modules/word/writers/run-writer.d.ts +15 -0
  602. package/dist/types/modules/word/writers/section-writer.d.ts +10 -0
  603. package/dist/types/modules/word/writers/styles-writer.d.ts +10 -0
  604. package/dist/types/modules/word/writers/table-writer.d.ts +10 -0
  605. package/dist/types/modules/word/writers/textbox-writer.d.ts +9 -0
  606. package/dist/types/modules/word/writers/toc-writer.d.ts +9 -0
  607. package/dist/types/modules/xml/encode.d.ts +56 -7
  608. package/package.json +29 -11
  609. package/dist/browser/modules/excel/utils/ooxml-validator.d.ts +0 -48
  610. package/dist/browser/modules/excel/utils/ooxml-validator.js +0 -493
  611. package/dist/browser/modules/excel/utils/passthrough-manager.d.ts +0 -77
  612. package/dist/browser/modules/excel/utils/passthrough-manager.js +0 -129
  613. package/dist/cjs/modules/excel/utils/ooxml-validator.js +0 -499
  614. package/dist/cjs/modules/excel/utils/passthrough-manager.js +0 -133
  615. package/dist/esm/modules/excel/utils/ooxml-validator.js +0 -493
  616. package/dist/esm/modules/excel/utils/passthrough-manager.js +0 -129
  617. package/dist/types/modules/excel/utils/ooxml-validator.d.ts +0 -48
  618. package/dist/types/modules/excel/utils/passthrough-manager.d.ts +0 -77
@@ -0,0 +1,1577 @@
1
+ "use strict";
2
+ /**
3
+ * Shape property (spPr) and text property (txPr) utilities.
4
+ *
5
+ * During chart parsing, spPr and txPr elements are captured as raw XML strings
6
+ * for perfect round-trip fidelity. These utilities provide structured read/write
7
+ * access to the most commonly used properties:
8
+ *
9
+ * - Fill color (solid sRGB / theme)
10
+ * - Line/outline color and width
11
+ * - Font size, bold, italic, color, family
12
+ *
13
+ * The approach: parse raw XML on demand using regex extraction (no full DOM),
14
+ * and generate raw XML from structured models when creating new properties.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.isRawXmlShape = isRawXmlShape;
18
+ exports.isRawXmlTxPr = isRawXmlTxPr;
19
+ exports.parseSpPr = parseSpPr;
20
+ exports.getSpPrFillColor = getSpPrFillColor;
21
+ exports.getSpPrFill = getSpPrFill;
22
+ exports.getSpPrLine = getSpPrLine;
23
+ exports.getSpPrGradient = getSpPrGradient;
24
+ exports.getSpPrPattern = getSpPrPattern;
25
+ exports.parseTxPr = parseTxPr;
26
+ exports.getTxPrFontSize = getTxPrFontSize;
27
+ exports.getTxPrColor = getTxPrColor;
28
+ exports.getTxPrFontFamily = getTxPrFontFamily;
29
+ exports.getTxPrBold = getTxPrBold;
30
+ exports.getTxPrItalic = getTxPrItalic;
31
+ exports.buildSpPr = buildSpPr;
32
+ exports.buildTxPr = buildTxPr;
33
+ exports.setSpPrFill = setSpPrFill;
34
+ exports.setSpPrLine = setSpPrLine;
35
+ // ============================================================================
36
+ // Raw XML access helpers
37
+ // ============================================================================
38
+ /** Get the raw XML string if the object was captured as raw XML. */
39
+ function getRawXml(obj) {
40
+ return obj?._rawXml;
41
+ }
42
+ /**
43
+ * Check if the object is purely a raw XML capture — `_rawXml` is set
44
+ * and NO structured fields have been populated. The parser produces
45
+ * dual-state objects (both `_rawXml` and structured) from raw bytes so
46
+ * downstream consumers get the best of both worlds: cheap byte-perfect
47
+ * round-trip PLUS typed access. Getters (`getSpPrFillColor` et al.)
48
+ * must prefer structured when present; setters must NOT reparse from
49
+ * `_rawXml` because doing so wipes any prior structured mutation.
50
+ *
51
+ * Writers must ALSO consult this predicate before short-circuiting to
52
+ * the raw bytes: if the model has been mutated through a direct
53
+ * property assignment (`spPr.fill = {...}` without routing through
54
+ * `setSpPrFill`), the raw bytes are stale and the structured path
55
+ * must win. Exported for use by `_renderSpPr` in both the classic
56
+ * chart-space xform and the ChartEx renderer.
57
+ *
58
+ * Previously `isRawXml` returned `true` whenever `_rawXml` was a
59
+ * string, which caused `setSpPrFill` → `parseSpPr` to re-read from
60
+ * raw and discard pending `line.width` / `fill.solid` assignments.
61
+ */
62
+ function isRawXmlShape(obj) {
63
+ return isRawXml(obj);
64
+ }
65
+ /**
66
+ * Whether a `ChartTextProperties` object is a pure raw-XML capture
67
+ * with no structured fields set. Analogous to {@link isRawXmlShape}
68
+ * for shape properties: when a caller directly assigns `txPr.color`,
69
+ * `txPr.size`, etc., the stale `_rawXml` must NOT win — the writer
70
+ * should fall through to the structured rendering path.
71
+ */
72
+ function isRawXmlTxPr(obj) {
73
+ if (!obj || typeof obj._rawXml !== "string") {
74
+ return false;
75
+ }
76
+ const structuredKeys = [
77
+ "size",
78
+ "bold",
79
+ "italic",
80
+ "underline",
81
+ "strike",
82
+ "color",
83
+ "fontFamily",
84
+ "eastAsianFamily",
85
+ "complexScriptFamily",
86
+ "rotation",
87
+ "baseline",
88
+ "kern",
89
+ "spacing",
90
+ "cap",
91
+ "lang"
92
+ ];
93
+ for (const key of structuredKeys) {
94
+ if (obj[key] !== undefined) {
95
+ return false;
96
+ }
97
+ }
98
+ return true;
99
+ }
100
+ function isRawXml(obj) {
101
+ if (!obj || typeof obj._rawXml !== "string") {
102
+ return false;
103
+ }
104
+ // "Purely raw" when no structured field is present. Enumerate the
105
+ // fields we care about so adding new structured slots to
106
+ // `ShapeProperties` doesn't require touching this predicate —
107
+ // anything absent from this list is either raw-bytes-only (like
108
+ // `extLst`) or part of the raw payload itself.
109
+ const structuredKeys = [
110
+ "fill",
111
+ "line",
112
+ "effectList",
113
+ "scene3d",
114
+ "sp3d",
115
+ "transform",
116
+ "presetGeometry",
117
+ "customGeometry"
118
+ ];
119
+ for (const key of structuredKeys) {
120
+ if (obj[key] !== undefined) {
121
+ return false;
122
+ }
123
+ }
124
+ return true;
125
+ }
126
+ // ============================================================================
127
+ // Color parsing from raw XML
128
+ // ============================================================================
129
+ // Pre-compiled regexes for parseColorFromXml (always called with "a" prefix)
130
+ const SRGB_CLR_RE = /<a:srgbClr\s+val="([0-9A-Fa-f]{6})"/i;
131
+ const SCHEME_CLR_RE = /<a:schemeClr\s+val="([^"]+)"/i;
132
+ // Pre-compiled regexes for parseShadowElement
133
+ const OUTER_SHDW_RE = /<a:outerShdw\s+([^>]*)>([\s\S]*?)<\/a:outerShdw>/;
134
+ const INNER_SHDW_RE = /<a:innerShdw\s+([^>]*)>([\s\S]*?)<\/a:innerShdw>/;
135
+ const SHADOW_RES = {
136
+ "a:outerShdw": OUTER_SHDW_RE,
137
+ "a:innerShdw": INNER_SHDW_RE
138
+ };
139
+ /**
140
+ * Extract a region from `xml` between the opening tag match and the corresponding
141
+ * closing tag (or a reasonable fallback for self-closing elements).
142
+ */
143
+ function extractColorRegion(xml, openMatch, closeTag) {
144
+ const endIdx = xml.indexOf(closeTag, openMatch.index);
145
+ if (endIdx >= 0) {
146
+ // Stop at the close tag's `>` so the region never spills into the
147
+ // next sibling (which could itself have a colour element whose
148
+ // modifiers would then be misattributed).
149
+ const closeGt = xml.indexOf(">", endIdx);
150
+ return xml.slice(openMatch.index, closeGt >= 0 ? closeGt + 1 : endIdx + closeTag.length);
151
+ }
152
+ // No close tag — the element is self-closing (`<a:srgbClr val="FF0000"/>`)
153
+ // or truncated. DrawingML never nests modifiers inside a self-closing
154
+ // colour token, so return just the opening fragment up to the first
155
+ // `>` to avoid picking up modifiers that belong to a sibling colour.
156
+ const openEnd = xml.indexOf(">", openMatch.index);
157
+ return xml.slice(openMatch.index, openEnd >= 0 ? openEnd + 1 : openMatch.index + openMatch[0].length);
158
+ }
159
+ /**
160
+ * Parse all DrawingML color modifiers from a region of XML.
161
+ * Handles: alpha, tint, shade, satMod, lumMod, lumOff.
162
+ *
163
+ * Regexes accept `-?\d+(?:\.\d+)?` — negative and fractional values
164
+ * are legal in third-party exports (e.g. `<a:tint val="-5000"/>`,
165
+ * `<a:satMod val="123456.7"/>`); `\d+` alone dropped them silently.
166
+ * `parseFloat` with rounding preserves the intended semantics.
167
+ */
168
+ function parseColorModifiers(region, color) {
169
+ const parseModifierValue = (m) => m ? Math.round(parseFloat(m[1])) : undefined;
170
+ const alphaMatch = /<a:alpha\s+val="(-?\d+(?:\.\d+)?)"/.exec(region);
171
+ const alphaVal = parseModifierValue(alphaMatch);
172
+ if (alphaVal !== undefined) {
173
+ color.alpha = alphaVal;
174
+ }
175
+ const tintMatch = /<a:tint\s+val="(-?\d+(?:\.\d+)?)"/.exec(region);
176
+ if (tintMatch) {
177
+ color.tint = parseFloat(tintMatch[1]) / 100000;
178
+ }
179
+ const shadeMatch = /<a:shade\s+val="(-?\d+(?:\.\d+)?)"/.exec(region);
180
+ const shadeVal = parseModifierValue(shadeMatch);
181
+ if (shadeVal !== undefined) {
182
+ color.shade = shadeVal;
183
+ }
184
+ const satModMatch = /<a:satMod\s+val="(-?\d+(?:\.\d+)?)"/.exec(region);
185
+ const satModVal = parseModifierValue(satModMatch);
186
+ if (satModVal !== undefined) {
187
+ color.satMod = satModVal;
188
+ }
189
+ const lumModMatch = /<a:lumMod\s+val="(-?\d+(?:\.\d+)?)"/.exec(region);
190
+ const lumModVal = parseModifierValue(lumModMatch);
191
+ if (lumModVal !== undefined) {
192
+ color.lumMod = lumModVal;
193
+ }
194
+ const lumOffMatch = /<a:lumOff\s+val="(-?\d+(?:\.\d+)?)"/.exec(region);
195
+ const lumOffVal = parseModifierValue(lumOffMatch);
196
+ if (lumOffVal !== undefined) {
197
+ color.lumOff = lumOffVal;
198
+ }
199
+ }
200
+ // Pre-compiled regexes for sysClr / prstClr
201
+ const SYS_CLR_RE = /<a:sysClr\s+val="([^"]+)"/i;
202
+ const PRST_CLR_RE = /<a:prstClr\s+val="([^"]+)"/i;
203
+ function parseColorFromXml(xml) {
204
+ // Try srgbClr
205
+ const srgbMatch = SRGB_CLR_RE.exec(xml);
206
+ if (srgbMatch) {
207
+ const color = { srgb: srgbMatch[1].toUpperCase() };
208
+ const region = extractColorRegion(xml, srgbMatch, `</a:srgbClr`);
209
+ parseColorModifiers(region, color);
210
+ return color;
211
+ }
212
+ // Try schemeClr (theme)
213
+ const schemeMatch = SCHEME_CLR_RE.exec(xml);
214
+ if (schemeMatch) {
215
+ // Theme index → canonical scheme name. `tx1/bg1/tx2/bg2` are
216
+ // "slide"-style aliases of `dk1/lt1/dk2/lt2` defined in ECMA-376
217
+ // §20.1.2.3.29, so we fold them into the same indices rather than
218
+ // dropping them as "unknown theme" (which used to silently return
219
+ // index 0 / `dk1` and corrupt the colour on round-trip).
220
+ const themeMap = {
221
+ dk1: 0,
222
+ tx1: 0,
223
+ lt1: 1,
224
+ bg1: 1,
225
+ dk2: 2,
226
+ tx2: 2,
227
+ lt2: 3,
228
+ bg2: 3,
229
+ accent1: 4,
230
+ accent2: 5,
231
+ accent3: 6,
232
+ accent4: 7,
233
+ accent5: 8,
234
+ accent6: 9,
235
+ hlink: 10,
236
+ folHlink: 11
237
+ };
238
+ const raw = schemeMatch[1];
239
+ const idx = themeMap[raw];
240
+ // When we can't map the name to a theme index (e.g. `phClr` — the
241
+ // DrawingML "placeholder colour" token — or a future addition),
242
+ // preserve it as a scheme-name token under `schemeName` so the
243
+ // writer re-emits `<a:schemeClr val="…">` on round-trip. The old
244
+ // code stored the raw token under `sysClr`, which caused the
245
+ // writer to emit `<a:sysClr>` instead — silently changing the
246
+ // DrawingML element type and breaking theme placeholder semantics.
247
+ const color = idx !== undefined ? { theme: idx } : { schemeName: raw };
248
+ const region = extractColorRegion(xml, schemeMatch, `</a:schemeClr`);
249
+ parseColorModifiers(region, color);
250
+ return color;
251
+ }
252
+ // Try sysClr (system color)
253
+ const sysMatch = SYS_CLR_RE.exec(xml);
254
+ if (sysMatch) {
255
+ const color = { sysClr: sysMatch[1] };
256
+ const region = extractColorRegion(xml, sysMatch, `</a:sysClr`);
257
+ parseColorModifiers(region, color);
258
+ return color;
259
+ }
260
+ // Try prstClr (preset color)
261
+ const prstMatch = PRST_CLR_RE.exec(xml);
262
+ if (prstMatch) {
263
+ const color = { prstClr: prstMatch[1] };
264
+ const region = extractColorRegion(xml, prstMatch, `</a:prstClr`);
265
+ parseColorModifiers(region, color);
266
+ return color;
267
+ }
268
+ return undefined;
269
+ }
270
+ // ============================================================================
271
+ // Gradient / pattern fill parsing from raw XML
272
+ // ============================================================================
273
+ function parseGradientFill(xml) {
274
+ const gradStart = xml.indexOf("<a:gradFill");
275
+ const gradEnd = xml.indexOf("</a:gradFill");
276
+ if (gradStart < 0 || gradEnd < 0) {
277
+ return undefined;
278
+ }
279
+ const region = xml.slice(gradStart, gradEnd + 20);
280
+ // Parse gradient stops. OOXML `<a:gs pos="N">` encodes `N` as
281
+ // hundredths of a percent (0–100000), NOT thousandths. The
282
+ // previous implementation divided by 1000 — producing `stop.position`
283
+ // values that were 100× too large (e.g. a 50% stop decoded as 50
284
+ // instead of 0.5). Paired with the equally-wrong writer multiplier
285
+ // of ×1000, round-trip byte-compared equal but any freshly-built
286
+ // gradient rendered in Excel at a wildly wrong position. See the
287
+ // companion fix in `chart-ex-renderer.ts:renderSpPr` gradient path.
288
+ const stops = [];
289
+ // Find each <a:gs pos="..."> ... </a:gs>
290
+ const gsListStart = region.indexOf("<a:gsLst");
291
+ const gsListEnd = region.indexOf("</a:gsLst");
292
+ if (gsListStart >= 0 && gsListEnd >= 0) {
293
+ const gsListRegion = region.slice(gsListStart, gsListEnd + 12);
294
+ // OOXML `ST_PositiveFixedPercentage` is `xsd:int` in [0, 100000]
295
+ // — integer by schema — but third-party authors sometimes emit
296
+ // fractional values (e.g. `pos="33333.33"`) that readers tolerate.
297
+ // The previous `\d+`-only regex silently dropped stops with
298
+ // fractional positions, truncating the whole gradient on parse.
299
+ // Match fractional too so we at least preserve the author's intent.
300
+ const gsPosRegex = /<a:gs\s+pos="(-?\d+(?:\.\d+)?)"/g;
301
+ let match;
302
+ const positions = [];
303
+ while ((match = gsPosRegex.exec(gsListRegion)) !== null) {
304
+ positions.push({ pos: parseFloat(match[1]), startIdx: match.index });
305
+ }
306
+ for (let i = 0; i < positions.length; i++) {
307
+ const start = positions[i].startIdx;
308
+ const end = i + 1 < positions.length ? positions[i + 1].startIdx : gsListRegion.length;
309
+ const gsRegion = gsListRegion.slice(start, end);
310
+ const color = parseColorFromXml(gsRegion);
311
+ if (color) {
312
+ stops.push({ position: positions[i].pos / 100000, color });
313
+ }
314
+ }
315
+ }
316
+ // A legal gradient requires at least two stops — `CT_GradientStopList`
317
+ // declares `minOccurs="2"`. Reject single-stop gradients at parse so
318
+ // the writer (which gates `g.stops.length >= 2`) doesn't silently
319
+ // drop the entire `<a:gradFill>` block on round-trip, producing a
320
+ // shape with no fill attribute at all. A user authoring a malformed
321
+ // single-stop gradient is better served by a missing fill that
322
+ // surfaces in testing than by silent truncation at save.
323
+ if (stops.length < 2) {
324
+ return undefined;
325
+ }
326
+ // Parse angle from <a:lin ang="..."> — OOXML stores 60000ths of a
327
+ // degree. The attribute is an xsd:int but we accept fractional
328
+ // values too so libraries that emit millidegrees don't lose data.
329
+ // `scaled` is a sibling boolean attribute on the same element; we
330
+ // capture it only when authored so a default-scaled gradient doesn't
331
+ // round-trip as an explicit `scaled="1"` (matching Excel's emission,
332
+ // which omits the attribute when the implicit default applies).
333
+ let angle;
334
+ let scaled;
335
+ let type;
336
+ const linMatch = /<a:lin\b([^/>]*)\/?>/.exec(region);
337
+ if (linMatch) {
338
+ const linAttrs = linMatch[1];
339
+ const angMatch = /\bang="(-?\d+(?:\.\d+)?)"/.exec(linAttrs);
340
+ if (angMatch) {
341
+ angle = parseFloat(angMatch[1]) / 60000;
342
+ }
343
+ const scaledMatch = /\bscaled="(1|true|0|false)"/.exec(linAttrs);
344
+ if (scaledMatch) {
345
+ scaled = scaledMatch[1] === "1" || scaledMatch[1] === "true";
346
+ }
347
+ type = "linear";
348
+ }
349
+ // Check for path gradient — `<a:path path="circle|rect|shape">`
350
+ // optionally wrapping `<a:fillToRect l t r b/>` focal rectangle
351
+ // (each component in hundredths of a percent).
352
+ const pathMatch = /<a:path\s+path="([^"]+)"/.exec(region);
353
+ let fillToRect;
354
+ if (pathMatch) {
355
+ type = pathMatch[1];
356
+ const fillRectMatch = /<a:fillToRect\b([^/>]*)/.exec(region);
357
+ if (fillRectMatch) {
358
+ const attrs = fillRectMatch[1];
359
+ const pick = (name) => {
360
+ const m = new RegExp(`\\b${name}="(-?\\d+(?:\\.\\d+)?)"`).exec(attrs);
361
+ return m ? parseFloat(m[1]) / 100000 : undefined;
362
+ };
363
+ fillToRect = {
364
+ left: pick("l"),
365
+ top: pick("t"),
366
+ right: pick("r"),
367
+ bottom: pick("b")
368
+ };
369
+ // Drop the object entirely when every component is missing so we
370
+ // don't carry an all-undefined placeholder through the model.
371
+ if (fillToRect.left === undefined &&
372
+ fillToRect.top === undefined &&
373
+ fillToRect.right === undefined &&
374
+ fillToRect.bottom === undefined) {
375
+ fillToRect = undefined;
376
+ }
377
+ }
378
+ }
379
+ return {
380
+ gradient: {
381
+ stops,
382
+ angle,
383
+ type,
384
+ ...(scaled !== undefined ? { scaled } : {}),
385
+ ...(fillToRect ? { fillToRect } : {})
386
+ }
387
+ };
388
+ }
389
+ function parsePatternFill(xml) {
390
+ const pattMatch = /<a:pattFill\s+prst="([^"]+)"/.exec(xml);
391
+ if (!pattMatch) {
392
+ return undefined;
393
+ }
394
+ const preset = pattMatch[1];
395
+ const pattStart = pattMatch.index;
396
+ const pattEnd = xml.indexOf("</a:pattFill", pattStart);
397
+ const region = xml.slice(pattStart, pattEnd > 0 ? pattEnd + 15 : undefined);
398
+ // Slice each colour region by pair-of-tags OR by the range from the
399
+ // current open up to the next known child — matches what a real XML
400
+ // parser would do, and doesn't over-read into the sibling colour
401
+ // when the element happens to be self-closing.
402
+ const sliceChildRegion = (open, close, stopBefore) => {
403
+ const start = region.indexOf(open);
404
+ if (start < 0) {
405
+ return "";
406
+ }
407
+ const end = region.indexOf(close, start);
408
+ if (end >= 0) {
409
+ return region.slice(start, end + close.length + 1);
410
+ }
411
+ // No close tag — element is self-closing or malformed. Stop at
412
+ // the next recognised sibling child so the slice never walks into
413
+ // the neighbouring colour block.
414
+ const nextSibling = region.indexOf(stopBefore, start + open.length);
415
+ return region.slice(start, nextSibling > 0 ? nextSibling : undefined);
416
+ };
417
+ const fgRegion = sliceChildRegion("<a:fgClr", "</a:fgClr", "<a:bgClr");
418
+ const bgRegion = sliceChildRegion("<a:bgClr", "</a:bgClr", "<a:fgClr");
419
+ const foreground = fgRegion ? parseColorFromXml(fgRegion) : undefined;
420
+ const background = bgRegion ? parseColorFromXml(bgRegion) : undefined;
421
+ return { pattern: { preset, foreground, background } };
422
+ }
423
+ /**
424
+ * Remove the FIRST matching `<tag …>…</tag>` (or self-closing
425
+ * `<tag …/>`) block from the input XML, returning the remainder. Used
426
+ * by {@link parseSpPr} to isolate shape-level children (fill / effects)
427
+ * from decorative children that nest inside `<a:ln>` — the line's own
428
+ * `<a:solidFill>` / `<a:noFill/>` / `<a:gradFill>` should not be
429
+ * harvested as the shape's fill.
430
+ *
431
+ * Strips ALL occurrences of `tag` (both self-closing and paired) in
432
+ * one pass. A previous version returned after the earliest match,
433
+ * which failed on inputs like `<a:ln/>…<a:ln>…</a:ln>` — the paired
434
+ * block survived and its inner `<a:solidFill>` was then mistakenly
435
+ * parsed as the shape's fill.
436
+ *
437
+ * Not a general-purpose XML tool — does not handle same-named nested
438
+ * occurrences. Sufficient for DrawingML spPr, where `<a:ln>` never
439
+ * nests another `<a:ln>`.
440
+ */
441
+ function stripOuterElement(xml, tag) {
442
+ const selfCloseRe = new RegExp(`<${tag}\\b[^>]*/>`);
443
+ const openRe = new RegExp(`<${tag}\\b[^>]*(?<!/)>`);
444
+ const closeRe = new RegExp(`</${tag}>`);
445
+ let current = xml;
446
+ // Strip up to 8 occurrences. DrawingML spPr never has more than one
447
+ // `<a:ln>`, so the loop normally exits after the first iteration;
448
+ // the ceiling guards against pathological input causing infinite
449
+ // loops without changing the happy path.
450
+ for (let i = 0; i < 8; i++) {
451
+ const selfCloseMatch = selfCloseRe.exec(current);
452
+ const openMatch = openRe.exec(current);
453
+ const selfCloseIndex = selfCloseMatch ? selfCloseMatch.index : Infinity;
454
+ const openIndex = openMatch ? openMatch.index : Infinity;
455
+ if (selfCloseIndex === Infinity && openIndex === Infinity) {
456
+ break;
457
+ }
458
+ if (selfCloseIndex < openIndex && selfCloseMatch) {
459
+ current =
460
+ current.slice(0, selfCloseMatch.index) +
461
+ current.slice(selfCloseMatch.index + selfCloseMatch[0].length);
462
+ continue;
463
+ }
464
+ if (openMatch) {
465
+ // Find the close tag that pairs with this open — start searching
466
+ // after the open's end to avoid capturing `</tag>` that belongs
467
+ // to a prior unrelated (e.g. self-closing lookalike) open.
468
+ const openEnd = openMatch.index + openMatch[0].length;
469
+ const closeMatch = closeRe.exec(current.slice(openEnd));
470
+ if (!closeMatch) {
471
+ // Malformed — stop stripping to avoid further mutation of
472
+ // input we don't understand.
473
+ break;
474
+ }
475
+ const closeStart = openEnd + closeMatch.index;
476
+ const closeEnd = closeStart + closeMatch[0].length;
477
+ current = current.slice(0, openMatch.index) + current.slice(closeEnd);
478
+ continue;
479
+ }
480
+ break;
481
+ }
482
+ return current;
483
+ }
484
+ // ============================================================================
485
+ // spPr: Read structured properties from raw XML
486
+ // ============================================================================
487
+ /**
488
+ * Extract structured fill and line properties from a raw spPr XML string.
489
+ * Returns the structured ShapeProperties if extraction succeeds.
490
+ */
491
+ function parseSpPr(spPr) {
492
+ const rawXml = getRawXml(spPr);
493
+ if (!rawXml) {
494
+ return spPr; // already structured
495
+ }
496
+ const result = {};
497
+ // The fill parser searches for `<a:solidFill>` at the top level — but
498
+ // `<a:ln>…<a:solidFill>…</a:solidFill></a:ln>` is a common DrawingML
499
+ // pattern where the line itself carries a solid colour. Previously
500
+ // `rawXml.includes("<a:solidFill")` matched the line's inner fill,
501
+ // picked up its colour as `result.fill.solid`, and the writer then
502
+ // emitted a phantom `<a:solidFill>` as a shape fill — silently
503
+ // painting the entire chart area with the border colour on re-save.
504
+ // Excise any `<a:ln>…</a:ln>` block before searching for the shape
505
+ // fill. The line block is parsed separately below, so nothing is
506
+ // lost. Gradient / pattern / noFill have the same issue with respect
507
+ // to `<a:ln>/<a:noFill/>`.
508
+ const fillSearchXml = stripOuterElement(rawXml, "a:ln");
509
+ // Parse fill
510
+ //
511
+ // The open/close tag search must be done defensively: `indexOf` on a
512
+ // missing close tag returns `-1`, so the naïve
513
+ // `fillSearchXml.slice(openIdx, fillSearchXml.indexOf("</a:solidFill") + 20)`
514
+ // picks up position `19` as the upper bound — either truncating the
515
+ // slice to garbage or producing an empty string. Both shapes
516
+ // silently corrupted the fill parser when a `<a:solidFill/>` was
517
+ // self-closed or when the close tag was missing.
518
+ //
519
+ // Prefer the open-tag-or-self-closing form, then only try to capture
520
+ // a close tag when we've seen a proper open tag. If we do not find a
521
+ // valid solid-fill region, fall through to the other fill branches
522
+ // so a `<a:gradFill>` that coexists with a malformed solidFill still
523
+ // gets picked up.
524
+ let fillMatched = false;
525
+ const solidFillSelfClose = /<a:solidFill\s*\/>/.exec(fillSearchXml);
526
+ const solidFillOpenIdx = fillSearchXml.indexOf("<a:solidFill");
527
+ const solidFillNonSelfClose = solidFillOpenIdx >= 0 && !solidFillSelfClose;
528
+ if (solidFillNonSelfClose) {
529
+ const closeIdx = fillSearchXml.indexOf("</a:solidFill>", solidFillOpenIdx);
530
+ if (closeIdx >= 0) {
531
+ const color = parseColorFromXml(fillSearchXml.slice(solidFillOpenIdx, closeIdx + "</a:solidFill>".length));
532
+ if (color) {
533
+ result.fill = { solid: color };
534
+ fillMatched = true;
535
+ }
536
+ }
537
+ // else: malformed solidFill (no close tag) — fall through below.
538
+ }
539
+ else if (solidFillSelfClose) {
540
+ // `<a:solidFill/>` has no child colour; DrawingML schema does not
541
+ // allow this, but some legacy exports emit it. Treat as "unknown
542
+ // fill, do not record" and fall through.
543
+ }
544
+ if (!fillMatched) {
545
+ if (fillSearchXml.includes("<a:noFill")) {
546
+ result.fill = { noFill: true };
547
+ }
548
+ else if (fillSearchXml.includes("<a:gradFill")) {
549
+ result.fill = parseGradientFill(fillSearchXml);
550
+ }
551
+ else if (fillSearchXml.includes("<a:pattFill")) {
552
+ result.fill = parsePatternFill(fillSearchXml);
553
+ }
554
+ }
555
+ // Parse line
556
+ //
557
+ // Anchor the regex on a real `<a:ln ...>` / `<a:ln>` / `<a:ln/>` — the
558
+ // lookahead `(?=[\s/>])` ensures we don't match a neighbouring element
559
+ // like `<a:lnRef>` or `<a:lnB>` (both appear in DrawingML theme /
560
+ // styleLst blocks) and silently walk the wrong region when extracting
561
+ // the stroke colour. We then parse `w` / other attributes separately
562
+ // from the captured opening-tag body — the old `(?:\s+w="(\d+)")?`
563
+ // inline group only captured `w` when it was the FIRST attribute
564
+ // after `<a:ln`, so `<a:ln cap="flat" w="12700">` silently dropped
565
+ // the width.
566
+ const lnMatch = /<a:ln(?=[\s/>])([^>]*)/.exec(rawXml);
567
+ if (lnMatch) {
568
+ // Distinguish `<a:ln/>` (self-closing, no body) from `<a:ln …>…</a:ln>`.
569
+ // The greedy `[^>]*` in the regex captures everything up to (but not
570
+ // including) the closing `>`. For `<a:ln w="12700"/>` the captured
571
+ // group is ` w="12700"/` — the `/` is THE self-close marker. Earlier
572
+ // code walked `rawXml[tokenEnd]` looking for `/`, but `tokenEnd` points
573
+ // at `>`, not `/`, so `selfClosing` was always false and the parser
574
+ // fell through to `indexOf("</a:ln", …)` (which returns -1 for a
575
+ // self-closing tag). That made `lnRegion` span to the end of the
576
+ // rawXml, causing the shape's own `<a:solidFill>` to be picked up as
577
+ // the line colour. Detect self-close by inspecting what the regex
578
+ // already captured — ignore trailing whitespace before the `/`.
579
+ const selfClosing = /\/\s*$/.test(lnMatch[1]);
580
+ const tokenEnd = lnMatch.index + lnMatch[0].length;
581
+ // The match stopped at the byte BEFORE the closing `>`; advance one
582
+ // character so the close-tag-aware slice below includes the `>`.
583
+ const openTagEnd = tokenEnd + 1;
584
+ // Use the full `</a:ln>` terminator (with the trailing `>`) instead
585
+ // of the old `</a:ln` prefix — the prefix also matches `</a:lnRef>`
586
+ // and `</a:lnB>` inside DrawingML styleLst blocks, which would
587
+ // cause the region to stop short of the real line close.
588
+ const lnEnd = selfClosing ? -1 : rawXml.indexOf("</a:ln>", lnMatch.index);
589
+ const lnRegion = selfClosing
590
+ ? rawXml.slice(lnMatch.index, openTagEnd)
591
+ : lnEnd >= 0
592
+ ? rawXml.slice(lnMatch.index, lnEnd + "</a:ln>".length)
593
+ : // Malformed (open tag with no matching close) — clip to the
594
+ // open tag only so we don't walk into unrelated XML. Previous
595
+ // behaviour sliced to `undefined` (rest of the document), which
596
+ // was the root of this bug.
597
+ rawXml.slice(lnMatch.index, openTagEnd);
598
+ const line = {};
599
+ const widthMatch = /\bw="(\d+)"/.exec(lnMatch[1]);
600
+ if (widthMatch) {
601
+ line.width = parseInt(widthMatch[1], 10);
602
+ }
603
+ if (lnRegion.includes("<a:noFill")) {
604
+ line.noFill = true;
605
+ }
606
+ else if (lnRegion.includes("<a:solidFill")) {
607
+ // Scope the colour search to the `<a:solidFill>` body so a line
608
+ // that also carries a gradient / pattern fill (rare but legal —
609
+ // `<a:ln><a:gradFill>…</a:gradFill></a:ln>`) doesn't pollute
610
+ // `parseColorFromXml` with the gradient's first stop colour. The
611
+ // previous code passed the whole `lnRegion` — if the line had
612
+ // both fills `parseColorFromXml` picked up whichever colour it
613
+ // found first in document order, silently mis-rendering the
614
+ // line. For pure-solid lines the result is identical.
615
+ const solidFillMatch = /<a:solidFill>([\s\S]*?)<\/a:solidFill>/.exec(lnRegion);
616
+ line.color = parseColorFromXml(solidFillMatch ? solidFillMatch[1] : lnRegion);
617
+ }
618
+ const dashMatch = /<a:prstDash\s+val="([^"]+)"/.exec(lnRegion);
619
+ if (dashMatch) {
620
+ line.dash = dashMatch[1];
621
+ }
622
+ result.line = line;
623
+ }
624
+ // Parse effect list
625
+ if (rawXml.includes("<a:effectLst") || rawXml.includes("<a:effectDag")) {
626
+ const effects = parseEffectList(rawXml);
627
+ if (effects) {
628
+ result.effectList = effects;
629
+ }
630
+ }
631
+ // Parse 3D scene and shape properties
632
+ if (rawXml.includes("<a:scene3d")) {
633
+ const scene = parseScene3D(rawXml);
634
+ if (scene) {
635
+ result.scene3d = scene;
636
+ }
637
+ }
638
+ if (rawXml.includes("<a:sp3d")) {
639
+ const sp3d = parseSp3D(rawXml);
640
+ if (sp3d) {
641
+ result.sp3d = sp3d;
642
+ }
643
+ }
644
+ // Transform (`a:xfrm`) — position, size, rotation, flips. The regex
645
+ // approach is a deliberate trade-off: a full XML walk would be more
646
+ // robust but also ~4x the code for a field Excel writes in a very
647
+ // constrained shape. If Excel ever nests `a:xfrm` with variants the
648
+ // round-trip raw-XML path still carries them.
649
+ if (rawXml.includes("<a:xfrm")) {
650
+ const transform = parseXfrm(rawXml);
651
+ if (transform) {
652
+ result.transform = transform;
653
+ }
654
+ }
655
+ if (rawXml.includes("<a:prstGeom")) {
656
+ const prst = parsePrstGeom(rawXml);
657
+ if (prst) {
658
+ result.presetGeometry = prst;
659
+ }
660
+ }
661
+ if (rawXml.includes("<a:custGeom")) {
662
+ const cust = parseCustGeom(rawXml);
663
+ if (cust) {
664
+ result.customGeometry = cust;
665
+ }
666
+ }
667
+ return result;
668
+ }
669
+ // ============================================================================
670
+ // Effect list parsing
671
+ // ============================================================================
672
+ // ============================================================================
673
+ /**
674
+ * Parse a single `<a:xfrm>` element out of the shape-properties raw
675
+ * XML blob. Returns `undefined` when the element is absent so callers
676
+ * can simply drop the result into a structural field.
677
+ *
678
+ * Shape: `<a:xfrm rot="…" flipH="1" flipV="1"><a:off x="…" y="…"/><a:ext cx="…" cy="…"/></a:xfrm>`.
679
+ * All five attributes and both children are optional; Excel omits
680
+ * `a:off`/`a:ext` when a shape inherits its parent's automatic
681
+ * layout.
682
+ */
683
+ function parseXfrm(xml) {
684
+ const match = /<a:xfrm\b([^>]*)(?:\/>|>([\s\S]*?)<\/a:xfrm>)/.exec(xml);
685
+ if (!match) {
686
+ return undefined;
687
+ }
688
+ const attrs = match[1] ?? "";
689
+ const inner = match[2] ?? "";
690
+ const result = {};
691
+ const rotAttr = /\brot="(-?\d+)"/.exec(attrs);
692
+ if (rotAttr) {
693
+ result.rotation = parseInt(rotAttr[1], 10);
694
+ }
695
+ if (/\bflipH="1"/.test(attrs)) {
696
+ result.flipHorizontal = true;
697
+ }
698
+ if (/\bflipV="1"/.test(attrs)) {
699
+ result.flipVertical = true;
700
+ }
701
+ const off = /<a:off\b([^/>]*)\/>/.exec(inner);
702
+ if (off) {
703
+ const x = /\bx="(-?\d+)"/.exec(off[1]);
704
+ const y = /\by="(-?\d+)"/.exec(off[1]);
705
+ if (x) {
706
+ result.offsetX = parseInt(x[1], 10);
707
+ }
708
+ if (y) {
709
+ result.offsetY = parseInt(y[1], 10);
710
+ }
711
+ }
712
+ const ext = /<a:ext\b([^/>]*)\/>/.exec(inner);
713
+ if (ext) {
714
+ const cx = /\bcx="(\d+)"/.exec(ext[1]);
715
+ const cy = /\bcy="(\d+)"/.exec(ext[1]);
716
+ if (cx) {
717
+ result.width = parseInt(cx[1], 10);
718
+ }
719
+ if (cy) {
720
+ result.height = parseInt(cy[1], 10);
721
+ }
722
+ }
723
+ return Object.keys(result).length > 0 ? result : undefined;
724
+ }
725
+ /**
726
+ * Parse `<a:prstGeom prst="…"><a:avLst>…</a:avLst></a:prstGeom>`.
727
+ * The `preset` name is mandatory; `adjustments` come from the
728
+ * optional `<a:avLst>` container whose children are `<a:gd name fmla>`
729
+ * triples. We read the raw `fmla` strings because they're a small
730
+ * OOXML sub-language (`"val 10000"` etc.) that callers rarely edit
731
+ * and would need a dedicated parser to structure further.
732
+ */
733
+ function parsePrstGeom(xml) {
734
+ const match = /<a:prstGeom\b([^>]*)(?:\/>|>([\s\S]*?)<\/a:prstGeom>)/.exec(xml);
735
+ if (!match) {
736
+ return undefined;
737
+ }
738
+ const attrs = match[1] ?? "";
739
+ const inner = match[2] ?? "";
740
+ const prstMatch = /\bprst="([^"]+)"/.exec(attrs);
741
+ if (!prstMatch) {
742
+ return undefined;
743
+ }
744
+ const result = { preset: prstMatch[1] };
745
+ const adjustments = parseAdjustmentList(inner);
746
+ if (adjustments.length > 0) {
747
+ result.adjustments = adjustments;
748
+ }
749
+ return result;
750
+ }
751
+ /**
752
+ * Parse `<a:custGeom>` into a {@link CustomGeometry}. The path-data
753
+ * parser is the focal effort: `<a:pathLst><a:path w h fill stroke>…</a:path></a:pathLst>`
754
+ * children enumerate moveTo / lnTo / arcTo / cubicBezTo / quadBezTo /
755
+ * close commands in OOXML's drawing-language flavour.
756
+ */
757
+ function parseCustGeom(xml) {
758
+ const match = /<a:custGeom\b[^>]*>([\s\S]*?)<\/a:custGeom>/.exec(xml);
759
+ if (!match) {
760
+ return undefined;
761
+ }
762
+ const body = match[1];
763
+ const result = {};
764
+ const adjustments = parseAdjustmentList(body);
765
+ if (adjustments.length > 0) {
766
+ result.adjustments = adjustments;
767
+ }
768
+ const paths = [];
769
+ const pathRe = /<a:path\b([^>]*)>([\s\S]*?)<\/a:path>/g;
770
+ let pm;
771
+ while ((pm = pathRe.exec(body)) !== null) {
772
+ const pAttrs = pm[1] ?? "";
773
+ const pBody = pm[2] ?? "";
774
+ const path = { commands: [] };
775
+ const wMatch = /\bw="(\d+)"/.exec(pAttrs);
776
+ const hMatch = /\bh="(\d+)"/.exec(pAttrs);
777
+ if (wMatch) {
778
+ path.w = parseInt(wMatch[1], 10);
779
+ }
780
+ if (hMatch) {
781
+ path.h = parseInt(hMatch[1], 10);
782
+ }
783
+ const fillMatch = /\bfill="([^"]+)"/.exec(pAttrs);
784
+ if (fillMatch) {
785
+ path.fill = fillMatch[1];
786
+ }
787
+ if (/\bstroke="1"/.test(pAttrs)) {
788
+ path.stroke = true;
789
+ }
790
+ else if (/\bstroke="0"/.test(pAttrs)) {
791
+ path.stroke = false;
792
+ }
793
+ path.commands = parseCustGeomCommands(pBody);
794
+ paths.push(path);
795
+ }
796
+ if (paths.length > 0) {
797
+ result.paths = paths;
798
+ }
799
+ return Object.keys(result).length > 0 ? result : undefined;
800
+ }
801
+ function parseAdjustmentList(xml) {
802
+ const avMatch = /<a:avLst\b[^>]*>([\s\S]*?)<\/a:avLst>/.exec(xml);
803
+ if (!avMatch) {
804
+ return [];
805
+ }
806
+ const out = [];
807
+ const gdRe = /<a:gd\b[^>]*\bname="([^"]+)"[^>]*\bfmla="([^"]+)"[^>]*\/>/g;
808
+ let m;
809
+ while ((m = gdRe.exec(avMatch[1])) !== null) {
810
+ out.push({ name: m[1], fmla: m[2] });
811
+ }
812
+ return out;
813
+ }
814
+ function parseCustGeomCommands(body) {
815
+ const commands = [];
816
+ // Walk commands in order — each `<a:moveTo>`/`<a:lnTo>`/… carries
817
+ // one or two `<a:pt x y>` children; `<a:arcTo>` carries explicit
818
+ // attributes instead. A greedy regex + lookahead captures the
819
+ // command block including the closing tag.
820
+ const cmdRe = /<a:(moveTo|lnTo|cubicBezTo|quadBezTo|arcTo|close)\b([^/>]*)(?:\/>|>([\s\S]*?)<\/a:\1>)/g;
821
+ let cm;
822
+ while ((cm = cmdRe.exec(body)) !== null) {
823
+ const kind = cm[1];
824
+ const cmdAttrs = cm[2] ?? "";
825
+ const cmdBody = cm[3] ?? "";
826
+ if (kind === "close") {
827
+ commands.push({ type: "close" });
828
+ continue;
829
+ }
830
+ if (kind === "arcTo") {
831
+ const wR = /\bwR="(-?\d+)"/.exec(cmdAttrs)?.[1];
832
+ const hR = /\bhR="(-?\d+)"/.exec(cmdAttrs)?.[1];
833
+ const stAng = /\bstAng="(-?\d+)"/.exec(cmdAttrs)?.[1];
834
+ const swAng = /\bswAng="(-?\d+)"/.exec(cmdAttrs)?.[1];
835
+ if (wR && hR && stAng && swAng) {
836
+ commands.push({
837
+ type: "arcTo",
838
+ arcParams: {
839
+ wR: parseInt(wR, 10),
840
+ hR: parseInt(hR, 10),
841
+ stAng: parseInt(stAng, 10),
842
+ swAng: parseInt(swAng, 10)
843
+ }
844
+ });
845
+ }
846
+ continue;
847
+ }
848
+ const points = [];
849
+ // Parse `<a:pt x="…" y="…"/>` without requiring a specific
850
+ // attribute order — some authors / writers emit
851
+ // `<a:pt y="100" x="200"/>` or interleave other attributes between
852
+ // `x` and `y`. The previous regex required `x` first, then only
853
+ // whitespace, then `y`, silently dropping all points on a
854
+ // legitimately-authored geometry that used the reversed order.
855
+ const ptRe = /<a:pt\b([^/>]*)\/>/g;
856
+ let pt;
857
+ while ((pt = ptRe.exec(cmdBody)) !== null) {
858
+ const attrs = pt[1];
859
+ const xAttr = /\bx="(-?\d+)"/.exec(attrs);
860
+ const yAttr = /\by="(-?\d+)"/.exec(attrs);
861
+ if (xAttr && yAttr) {
862
+ points.push({ x: parseInt(xAttr[1], 10), y: parseInt(yAttr[1], 10) });
863
+ }
864
+ }
865
+ commands.push({ type: kind, points });
866
+ }
867
+ return commands;
868
+ }
869
+ function parseEffectList(xml) {
870
+ const effStart = xml.indexOf("<a:effectLst");
871
+ const effEnd = xml.indexOf("</a:effectLst");
872
+ if (effStart < 0 || effEnd < 0) {
873
+ return undefined;
874
+ }
875
+ const region = xml.slice(effStart, effEnd + "</a:effectLst>".length);
876
+ const result = {};
877
+ // Blur
878
+ const blurMatch = /<a:blur(\s+[^/>]*)?\s*\/>/.exec(region);
879
+ if (blurMatch) {
880
+ const attrs = parseAttrs(blurMatch[0]);
881
+ result.blur = {};
882
+ if (attrs.rad) {
883
+ result.blur.radius = parseInt(attrs.rad, 10);
884
+ }
885
+ if (attrs.grow === "1") {
886
+ result.blur.grow = true;
887
+ }
888
+ }
889
+ // Outer shadow
890
+ const outerShadow = parseShadowElement(region, "a:outerShdw");
891
+ if (outerShadow) {
892
+ result.outerShadow = outerShadow;
893
+ }
894
+ // Inner shadow
895
+ const innerShadow = parseShadowElement(region, "a:innerShdw");
896
+ if (innerShadow) {
897
+ result.innerShadow = innerShadow;
898
+ }
899
+ // Preset shadow
900
+ const prstMatch = /<a:prstShdw\s+([^>]*)>([\s\S]*?)<\/a:prstShdw>/.exec(region);
901
+ if (prstMatch) {
902
+ const attrs = parseAttrs(prstMatch[0]);
903
+ const color = parseColorFromXml(prstMatch[2]);
904
+ if (attrs.prst && color) {
905
+ result.presetShadow = { preset: attrs.prst, color };
906
+ if (attrs.dist) {
907
+ result.presetShadow.distance = parseInt(attrs.dist, 10);
908
+ }
909
+ if (attrs.dir) {
910
+ result.presetShadow.direction = parseInt(attrs.dir, 10);
911
+ }
912
+ }
913
+ }
914
+ // Glow
915
+ const glowMatch = /<a:glow\s+([^>]*)>([\s\S]*?)<\/a:glow>/.exec(region);
916
+ if (glowMatch) {
917
+ const attrs = parseAttrs(glowMatch[0]);
918
+ const color = parseColorFromXml(glowMatch[2]);
919
+ if (attrs.rad && color) {
920
+ result.glow = { radius: parseInt(attrs.rad, 10), color };
921
+ }
922
+ }
923
+ // Soft edge
924
+ const softEdgeMatch = /<a:softEdge\s+([^/>]*)\s*\/>/.exec(region);
925
+ if (softEdgeMatch) {
926
+ const attrs = parseAttrs(softEdgeMatch[0]);
927
+ if (attrs.rad) {
928
+ result.softEdge = { radius: parseInt(attrs.rad, 10) };
929
+ }
930
+ }
931
+ // Reflection
932
+ const reflMatch = /<a:reflection\s+([^/>]*)\s*\/>/.exec(region);
933
+ if (reflMatch) {
934
+ const attrs = parseAttrs(reflMatch[0]);
935
+ const r = {};
936
+ if (attrs.blurRad) {
937
+ r.blurRadius = parseInt(attrs.blurRad, 10);
938
+ }
939
+ if (attrs.stA) {
940
+ r.startOpacity = parseInt(attrs.stA, 10);
941
+ }
942
+ if (attrs.stPos) {
943
+ r.startPosition = parseInt(attrs.stPos, 10);
944
+ }
945
+ if (attrs.endA) {
946
+ r.endOpacity = parseInt(attrs.endA, 10);
947
+ }
948
+ if (attrs.endPos) {
949
+ r.endPosition = parseInt(attrs.endPos, 10);
950
+ }
951
+ if (attrs.dist) {
952
+ r.distance = parseInt(attrs.dist, 10);
953
+ }
954
+ if (attrs.dir) {
955
+ r.direction = parseInt(attrs.dir, 10);
956
+ }
957
+ if (attrs.fadeDir) {
958
+ r.fadeDirection = parseInt(attrs.fadeDir, 10);
959
+ }
960
+ if (attrs.sx) {
961
+ r.scaleHorizontal = parseInt(attrs.sx, 10);
962
+ }
963
+ if (attrs.sy) {
964
+ r.scaleVertical = parseInt(attrs.sy, 10);
965
+ }
966
+ if (attrs.kx) {
967
+ r.skewHorizontal = parseInt(attrs.kx, 10);
968
+ }
969
+ if (attrs.ky) {
970
+ r.skewVertical = parseInt(attrs.ky, 10);
971
+ }
972
+ if (attrs.algn) {
973
+ r.alignment = attrs.algn;
974
+ }
975
+ if (attrs.rotWithShape === "1") {
976
+ r.rotateWithShape = true;
977
+ }
978
+ result.reflection = r;
979
+ }
980
+ if (Object.keys(result).length === 0) {
981
+ return undefined;
982
+ }
983
+ return result;
984
+ }
985
+ function parseShadowElement(xml, tag) {
986
+ const re = SHADOW_RES[tag] ?? new RegExp(`<${tag}\\s+([^>]*)>([\\s\\S]*?)<\\/${tag}>`);
987
+ const m = re.exec(xml);
988
+ if (!m) {
989
+ return undefined;
990
+ }
991
+ const attrs = parseAttrs(m[0]);
992
+ const color = parseColorFromXml(m[2]);
993
+ if (!color) {
994
+ return undefined;
995
+ }
996
+ const shadow = { color };
997
+ if (attrs.blurRad) {
998
+ shadow.blurRadius = parseInt(attrs.blurRad, 10);
999
+ }
1000
+ if (attrs.dist) {
1001
+ shadow.distance = parseInt(attrs.dist, 10);
1002
+ }
1003
+ if (attrs.dir) {
1004
+ shadow.direction = parseInt(attrs.dir, 10);
1005
+ }
1006
+ if (attrs.algn) {
1007
+ shadow.alignment = attrs.algn;
1008
+ }
1009
+ if (attrs.rotWithShape === "1") {
1010
+ shadow.rotateWithShape = true;
1011
+ }
1012
+ if (attrs.sx) {
1013
+ shadow.scaleHorizontal = parseInt(attrs.sx, 10);
1014
+ }
1015
+ if (attrs.sy) {
1016
+ shadow.scaleVertical = parseInt(attrs.sy, 10);
1017
+ }
1018
+ if (attrs.kx) {
1019
+ shadow.skewHorizontal = parseInt(attrs.kx, 10);
1020
+ }
1021
+ if (attrs.ky) {
1022
+ shadow.skewVertical = parseInt(attrs.ky, 10);
1023
+ }
1024
+ return shadow;
1025
+ }
1026
+ function parseScene3D(xml) {
1027
+ const sceneStart = xml.indexOf("<a:scene3d");
1028
+ const sceneEnd = xml.indexOf("</a:scene3d");
1029
+ if (sceneStart < 0 || sceneEnd < 0) {
1030
+ return undefined;
1031
+ }
1032
+ const region = xml.slice(sceneStart, sceneEnd + 13);
1033
+ const result = {};
1034
+ const cameraMatch = /<a:camera\s+([^>]*)(?:\/|>[\s\S]*?<\/a:camera)>/.exec(region);
1035
+ if (cameraMatch) {
1036
+ const attrs = parseAttrs(cameraMatch[0]);
1037
+ if (attrs.prst) {
1038
+ result.camera = { preset: attrs.prst };
1039
+ if (attrs.fov) {
1040
+ result.camera.fov = parseInt(attrs.fov, 10);
1041
+ }
1042
+ if (attrs.zoom) {
1043
+ result.camera.zoom = parseInt(attrs.zoom, 10);
1044
+ }
1045
+ const rotMatch = /<a:rot\s+([^/>]*)\s*\/>/.exec(cameraMatch[0]);
1046
+ if (rotMatch) {
1047
+ const ra = parseAttrs(rotMatch[0]);
1048
+ if (ra.lat && ra.lon && ra.rev) {
1049
+ result.camera.rotation = {
1050
+ lat: parseInt(ra.lat, 10),
1051
+ lon: parseInt(ra.lon, 10),
1052
+ rev: parseInt(ra.rev, 10)
1053
+ };
1054
+ }
1055
+ }
1056
+ }
1057
+ }
1058
+ const lightRigMatch = /<a:lightRig\s+([^>]*)(?:\/|>[\s\S]*?<\/a:lightRig)>/.exec(region);
1059
+ if (lightRigMatch) {
1060
+ const attrs = parseAttrs(lightRigMatch[0]);
1061
+ if (attrs.rig && attrs.dir) {
1062
+ result.lightRig = { rig: attrs.rig, direction: attrs.dir };
1063
+ }
1064
+ }
1065
+ if (!result.camera && !result.lightRig) {
1066
+ return undefined;
1067
+ }
1068
+ return result;
1069
+ }
1070
+ function parseSp3D(xml) {
1071
+ const spStart = xml.indexOf("<a:sp3d");
1072
+ if (spStart < 0) {
1073
+ return undefined;
1074
+ }
1075
+ // Determine the tag extent using indexOf (no backtracking risk).
1076
+ const selfCloseEnd = xml.indexOf("/>", spStart);
1077
+ const openTagEnd = xml.indexOf(">", spStart);
1078
+ const isSelfClose = selfCloseEnd >= 0 && (openTagEnd < 0 || selfCloseEnd < openTagEnd);
1079
+ let region;
1080
+ if (isSelfClose) {
1081
+ region = xml.slice(spStart, selfCloseEnd + 2);
1082
+ }
1083
+ else if (openTagEnd >= 0) {
1084
+ const closeTag = "</a:sp3d>";
1085
+ const closeIdx = xml.indexOf(closeTag, openTagEnd);
1086
+ region =
1087
+ closeIdx >= 0
1088
+ ? xml.slice(spStart, closeIdx + closeTag.length)
1089
+ : xml.slice(spStart, openTagEnd + 1);
1090
+ }
1091
+ else {
1092
+ region = xml.slice(spStart);
1093
+ }
1094
+ // Only parse attributes from the opening tag itself — NOT from child
1095
+ // elements (e.g. `<a:bevelT w="..." h="..."/>`) which would pollute
1096
+ // the attribute dict with unrelated keys.
1097
+ const firstClose = region.indexOf(">");
1098
+ const openTag = firstClose >= 0 ? region.slice(0, firstClose + 1) : region;
1099
+ const attrs = parseAttrs(openTag);
1100
+ const result = {};
1101
+ if (attrs.z) {
1102
+ result.z = parseInt(attrs.z, 10);
1103
+ }
1104
+ if (attrs.extrusionH) {
1105
+ result.extrusionHeight = parseInt(attrs.extrusionH, 10);
1106
+ }
1107
+ if (attrs.contourW) {
1108
+ result.contourWidth = parseInt(attrs.contourW, 10);
1109
+ }
1110
+ if (attrs.prstMaterial) {
1111
+ result.material = attrs.prstMaterial;
1112
+ }
1113
+ // Bevels — use indexOf to find the self-closing tags within the region
1114
+ const bevelTStart = region.indexOf("<a:bevelT");
1115
+ if (bevelTStart >= 0) {
1116
+ const bevelTEnd = region.indexOf("/>", bevelTStart);
1117
+ if (bevelTEnd >= 0) {
1118
+ result.bevelTop = parseBevelAttrs(region.slice(bevelTStart, bevelTEnd + 2));
1119
+ }
1120
+ }
1121
+ const bevelBStart = region.indexOf("<a:bevelB");
1122
+ if (bevelBStart >= 0) {
1123
+ const bevelBEnd = region.indexOf("/>", bevelBStart);
1124
+ if (bevelBEnd >= 0) {
1125
+ result.bevelBottom = parseBevelAttrs(region.slice(bevelBStart, bevelBEnd + 2));
1126
+ }
1127
+ }
1128
+ // Extrusion / contour colours — only present in open-close form
1129
+ if (!isSelfClose) {
1130
+ const extOpen = "<a:extrusionClr>";
1131
+ const extClose = "</a:extrusionClr>";
1132
+ const extStart = region.indexOf(extOpen);
1133
+ if (extStart >= 0) {
1134
+ const extEnd = region.indexOf(extClose, extStart);
1135
+ if (extEnd >= 0) {
1136
+ const c = parseColorFromXml(region.slice(extStart + extOpen.length, extEnd));
1137
+ if (c) {
1138
+ result.extrusionColor = c;
1139
+ }
1140
+ }
1141
+ }
1142
+ const contOpen = "<a:contourClr>";
1143
+ const contClose = "</a:contourClr>";
1144
+ const contStart = region.indexOf(contOpen);
1145
+ if (contStart >= 0) {
1146
+ const contEnd = region.indexOf(contClose, contStart);
1147
+ if (contEnd >= 0) {
1148
+ const c = parseColorFromXml(region.slice(contStart + contOpen.length, contEnd));
1149
+ if (c) {
1150
+ result.contourColor = c;
1151
+ }
1152
+ }
1153
+ }
1154
+ }
1155
+ return result;
1156
+ }
1157
+ function parseBevelAttrs(tag) {
1158
+ const attrs = parseAttrs(tag);
1159
+ const bevel = {};
1160
+ if (attrs.w) {
1161
+ bevel.width = parseInt(attrs.w, 10);
1162
+ }
1163
+ if (attrs.h) {
1164
+ bevel.height = parseInt(attrs.h, 10);
1165
+ }
1166
+ if (attrs.prst) {
1167
+ bevel.preset = attrs.prst;
1168
+ }
1169
+ return bevel;
1170
+ }
1171
+ function parseAttrs(tag) {
1172
+ const attrs = {};
1173
+ // Manual parser avoids regex backtracking on uncontrolled input.
1174
+ let i = 0;
1175
+ const len = tag.length;
1176
+ while (i < len) {
1177
+ // Skip non-word characters
1178
+ while (i < len && !isWordChar(tag.charCodeAt(i))) {
1179
+ i++;
1180
+ }
1181
+ if (i >= len) {
1182
+ break;
1183
+ }
1184
+ // Read attribute name (word chars only)
1185
+ const nameStart = i;
1186
+ while (i < len && isWordChar(tag.charCodeAt(i))) {
1187
+ i++;
1188
+ }
1189
+ const name = tag.slice(nameStart, i);
1190
+ // Expect `="`
1191
+ if (i >= len || tag.charCodeAt(i) !== 61 /* = */) {
1192
+ continue;
1193
+ }
1194
+ i++;
1195
+ if (i >= len || tag.charCodeAt(i) !== 34 /* " */) {
1196
+ continue;
1197
+ }
1198
+ i++;
1199
+ // Read attribute value until closing quote
1200
+ const valStart = i;
1201
+ while (i < len && tag.charCodeAt(i) !== 34) {
1202
+ i++;
1203
+ }
1204
+ attrs[name] = tag.slice(valStart, i);
1205
+ if (i < len) {
1206
+ i++; // skip closing quote
1207
+ }
1208
+ }
1209
+ return attrs;
1210
+ }
1211
+ /** Check if a char code is a word character [A-Za-z0-9_]. */
1212
+ function isWordChar(c) {
1213
+ return ((c >= 65 && c <= 90) || // A-Z
1214
+ (c >= 97 && c <= 122) || // a-z
1215
+ (c >= 48 && c <= 57) || // 0-9
1216
+ c === 95 // _
1217
+ );
1218
+ }
1219
+ /**
1220
+ * Extract a single attribute value from the first occurrence of `<tagName ...>`
1221
+ * in `xml`. Uses indexOf to locate the tag (no backtracking risk) then a simple
1222
+ * attribute regex on the bounded tag substring.
1223
+ */
1224
+ function findTagAttr(xml, tagName, attrName) {
1225
+ const tagStart = xml.indexOf(`<${tagName}`);
1226
+ if (tagStart < 0) {
1227
+ return undefined;
1228
+ }
1229
+ const tagEnd = xml.indexOf(">", tagStart);
1230
+ if (tagEnd < 0) {
1231
+ return undefined;
1232
+ }
1233
+ const tag = xml.slice(tagStart, tagEnd + 1);
1234
+ const re = new RegExp(`${attrName}="([^"]*)"`);
1235
+ const m = re.exec(tag);
1236
+ return m ? m[1] : undefined;
1237
+ }
1238
+ /**
1239
+ * Get the solid fill color from a ShapeProperties object.
1240
+ * Works for both raw XML and structured models.
1241
+ */
1242
+ function getSpPrFillColor(spPr) {
1243
+ const parsed = isRawXml(spPr) ? parseSpPr(spPr) : spPr;
1244
+ return parsed.fill?.solid;
1245
+ }
1246
+ /**
1247
+ * Get the complete fill (solid / gradient / pattern / noFill) from a
1248
+ * ShapeProperties object. Works for both raw XML and structured models.
1249
+ * Prefer this over {@link getSpPrFillColor} when the caller needs to
1250
+ * distinguish between "no fill", "gradient", etc. — the color-only
1251
+ * accessor collapses all three to `undefined`.
1252
+ */
1253
+ function getSpPrFill(spPr) {
1254
+ const parsed = isRawXml(spPr) ? parseSpPr(spPr) : spPr;
1255
+ return parsed.fill;
1256
+ }
1257
+ /**
1258
+ * Get the line/outline properties from a ShapeProperties object.
1259
+ */
1260
+ function getSpPrLine(spPr) {
1261
+ const parsed = isRawXml(spPr) ? parseSpPr(spPr) : spPr;
1262
+ return parsed.line;
1263
+ }
1264
+ /**
1265
+ * Get the gradient fill from a ShapeProperties object.
1266
+ */
1267
+ function getSpPrGradient(spPr) {
1268
+ const parsed = isRawXml(spPr) ? parseSpPr(spPr) : spPr;
1269
+ return parsed.fill?.gradient;
1270
+ }
1271
+ /**
1272
+ * Get the pattern fill from a ShapeProperties object.
1273
+ */
1274
+ function getSpPrPattern(spPr) {
1275
+ const parsed = isRawXml(spPr) ? parseSpPr(spPr) : spPr;
1276
+ return parsed.fill?.pattern;
1277
+ }
1278
+ // ============================================================================
1279
+ // txPr: Read structured properties from raw XML
1280
+ // ============================================================================
1281
+ /**
1282
+ * Extract structured text properties from a raw txPr XML string.
1283
+ *
1284
+ * Parses the fields the structured {@link ChartTextProperties} model
1285
+ * declares:
1286
+ * - `size`, `bold`, `italic`, `underline`, `strike`, `cap`, `baseline`,
1287
+ * `kern`, `spacing`, `lang` (from the first `<a:defRPr>` / `<a:rPr>`)
1288
+ * - `color` (from `<a:solidFill>` inside the same element)
1289
+ * - `fontFamily`, `eastAsianFamily`, `complexScriptFamily`
1290
+ * (from `<a:latin>` / `<a:ea>` / `<a:cs>` children)
1291
+ * - `rotation` (from `<a:bodyPr/@rot>`)
1292
+ *
1293
+ * Callers that want to preserve every attribute OOXML might carry
1294
+ * (e.g. `spc="100"`, `u="sng"`, `baseline="30000"`) must not rely on
1295
+ * this function round-tripping via structured fields alone — keep the
1296
+ * `_rawXml` on the txPr. This parser is a best-effort structural view
1297
+ * for consumers that want to READ the common properties; `_rawXml`
1298
+ * remains authoritative for write-side fidelity.
1299
+ */
1300
+ function parseTxPr(txPr) {
1301
+ const rawXml = getRawXml(txPr);
1302
+ if (!rawXml) {
1303
+ return txPr; // already structured
1304
+ }
1305
+ const result = {};
1306
+ // Font size (a:sz) — search defRPr first, then rPr
1307
+ const szVal = findTagAttr(rawXml, "a:defRPr", "sz") ?? findTagAttr(rawXml, "a:rPr", "sz");
1308
+ if (szVal) {
1309
+ result.size = parseInt(szVal, 10);
1310
+ }
1311
+ // Bold — accept `"1"` / `"true"` per XSD `xsd:boolean`. Previously
1312
+ // only `"1"` was recognised, so LibreOffice-authored files (which
1313
+ // emit `b="true"`) silently round-tripped bold text as regular.
1314
+ // An explicit `b="0"` / `b="false"` is preserved as `false` rather
1315
+ // than dropped — semantically distinct from the attribute being
1316
+ // absent (which leaves the field undefined so downstream writers
1317
+ // know not to force a value).
1318
+ const bVal = findTagAttr(rawXml, "a:defRPr", "b") ?? findTagAttr(rawXml, "a:rPr", "b");
1319
+ if (bVal) {
1320
+ result.bold = bVal === "1" || bVal === "true";
1321
+ }
1322
+ // Italic — same lenient boolean handling as `b` above.
1323
+ const iVal = findTagAttr(rawXml, "a:defRPr", "i") ?? findTagAttr(rawXml, "a:rPr", "i");
1324
+ if (iVal) {
1325
+ result.italic = iVal === "1" || iVal === "true";
1326
+ }
1327
+ // Underline style (a:rPr/@u). Values are the DrawingML `ST_TextUnderlineType`
1328
+ // enum: "none" | "sng" | "dbl" | "heavy" | "dotted" | "dottedHeavy" |
1329
+ // "dash" | "dashHeavy" | "dashLong" | "dashLongHeavy" | "dotDash" |
1330
+ // "dotDashHeavy" | "dotDotDash" | "dotDotDashHeavy" | "wavy" |
1331
+ // "wavyHeavy" | "wavyDbl".
1332
+ const uVal = findTagAttr(rawXml, "a:defRPr", "u") ?? findTagAttr(rawXml, "a:rPr", "u");
1333
+ if (uVal) {
1334
+ result.underline = uVal;
1335
+ }
1336
+ // Strike-through (a:rPr/@strike). Values: "noStrike" | "sngStrike" |
1337
+ // "dblStrike".
1338
+ const strikeVal = findTagAttr(rawXml, "a:defRPr", "strike") ?? findTagAttr(rawXml, "a:rPr", "strike");
1339
+ if (strikeVal) {
1340
+ result.strike = strikeVal;
1341
+ }
1342
+ // Capitalisation (a:rPr/@cap). Values: "none" | "small" | "all".
1343
+ const capVal = findTagAttr(rawXml, "a:defRPr", "cap") ?? findTagAttr(rawXml, "a:rPr", "cap");
1344
+ if (capVal) {
1345
+ result.cap = capVal;
1346
+ }
1347
+ // Baseline offset (a:rPr/@baseline) — percentage * 1000 per OOXML
1348
+ // (signed; positive = superscript, negative = subscript).
1349
+ const baselineVal = findTagAttr(rawXml, "a:defRPr", "baseline") ?? findTagAttr(rawXml, "a:rPr", "baseline");
1350
+ if (baselineVal) {
1351
+ result.baseline = parseInt(baselineVal, 10);
1352
+ }
1353
+ // Character kerning cut-off (a:rPr/@kern) — hundredths of a point.
1354
+ const kernVal = findTagAttr(rawXml, "a:defRPr", "kern") ?? findTagAttr(rawXml, "a:rPr", "kern");
1355
+ if (kernVal) {
1356
+ result.kern = parseInt(kernVal, 10);
1357
+ }
1358
+ // Character spacing (a:rPr/@spc) — hundredths of a point.
1359
+ const spcVal = findTagAttr(rawXml, "a:defRPr", "spc") ?? findTagAttr(rawXml, "a:rPr", "spc");
1360
+ if (spcVal) {
1361
+ result.spacing = parseInt(spcVal, 10);
1362
+ }
1363
+ // Language (a:rPr/@lang) — BCP 47 language tag (e.g. "en-US", "ja-JP").
1364
+ // Wider character class than `\w+` because tags can include hyphens
1365
+ // and digits ("zh-Hant-TW").
1366
+ const langVal = findTagAttr(rawXml, "a:defRPr", "lang") ?? findTagAttr(rawXml, "a:rPr", "lang");
1367
+ if (langVal) {
1368
+ result.lang = langVal;
1369
+ }
1370
+ // Font color. Try the paragraph-level default (`<a:defRPr>…`) first,
1371
+ // then fall back to the first run-property block (`<a:rPr>…`). Chart
1372
+ // titles / data-label rich text often carry colour on `<a:rPr>` (per
1373
+ // run), not on `<a:defRPr>` — the old implementation only checked the
1374
+ // former and silently dropped colour on round-trip.
1375
+ const extractColorFrom = (openTag, closeTag) => {
1376
+ const start = rawXml.indexOf(openTag);
1377
+ if (start < 0) {
1378
+ return undefined;
1379
+ }
1380
+ const end = rawXml.indexOf(closeTag, start);
1381
+ const region = rawXml.slice(start, end > 0 ? end + closeTag.length : undefined);
1382
+ if (!region.includes("<a:solidFill")) {
1383
+ return undefined;
1384
+ }
1385
+ return parseColorFromXml(region);
1386
+ };
1387
+ result.color =
1388
+ extractColorFrom("<a:defRPr", "</a:defRPr>") ?? extractColorFrom("<a:rPr", "</a:rPr>");
1389
+ // Latin font family (a:latin/@typeface) — structured default.
1390
+ const latinMatch = /<a:latin\s+typeface="([^"]+)"/.exec(rawXml);
1391
+ if (latinMatch) {
1392
+ result.fontFamily = latinMatch[1];
1393
+ }
1394
+ // East Asian font family (a:ea/@typeface) — used for CJK characters
1395
+ // when the primary Latin font doesn't cover them. Dropping this
1396
+ // field on round-trip made CJK-labelled charts reflow on reload.
1397
+ const eaMatch = /<a:ea\s+typeface="([^"]+)"/.exec(rawXml);
1398
+ if (eaMatch) {
1399
+ result.eastAsianFamily = eaMatch[1];
1400
+ }
1401
+ // Complex-script font family (a:cs/@typeface) — used for Arabic /
1402
+ // Hebrew / Thai fallbacks.
1403
+ const csMatch = /<a:cs\s+typeface="([^"]+)"/.exec(rawXml);
1404
+ if (csMatch) {
1405
+ result.complexScriptFamily = csMatch[1];
1406
+ }
1407
+ // Rotation (on bodyPr)
1408
+ const rotVal = findTagAttr(rawXml, "a:bodyPr", "rot");
1409
+ if (rotVal) {
1410
+ result.rotation = parseInt(rotVal, 10);
1411
+ }
1412
+ return result;
1413
+ }
1414
+ /**
1415
+ * Get font size from a ChartTextProperties object (returns points, e.g. 10).
1416
+ */
1417
+ function getTxPrFontSize(txPr) {
1418
+ const parsed = isRawXml(txPr) ? parseTxPr(txPr) : txPr;
1419
+ return parsed.size !== undefined ? parsed.size / 100 : undefined;
1420
+ }
1421
+ /**
1422
+ * Get font color from a ChartTextProperties object.
1423
+ */
1424
+ function getTxPrColor(txPr) {
1425
+ const parsed = isRawXml(txPr) ? parseTxPr(txPr) : txPr;
1426
+ return parsed.color;
1427
+ }
1428
+ /**
1429
+ * Get the font family (typeface) declared on `<a:latin>` / `<a:cs>`
1430
+ * within a `txPr` raw or structured object. Returns `undefined` if the
1431
+ * properties do not carry a typeface, in which case renderers should
1432
+ * use their own default.
1433
+ */
1434
+ function getTxPrFontFamily(txPr) {
1435
+ const parsed = isRawXml(txPr) ? parseTxPr(txPr) : txPr;
1436
+ return parsed.fontFamily;
1437
+ }
1438
+ /**
1439
+ * Get the boolean bold flag from a `txPr`'s first `a:defRPr`/`a:rPr`.
1440
+ */
1441
+ function getTxPrBold(txPr) {
1442
+ const parsed = isRawXml(txPr) ? parseTxPr(txPr) : txPr;
1443
+ return parsed.bold;
1444
+ }
1445
+ /**
1446
+ * Get the boolean italic flag from a `txPr`'s first `a:defRPr`/`a:rPr`.
1447
+ */
1448
+ function getTxPrItalic(txPr) {
1449
+ const parsed = isRawXml(txPr) ? parseTxPr(txPr) : txPr;
1450
+ return parsed.italic;
1451
+ }
1452
+ // ============================================================================
1453
+ // Build structured spPr / txPr models
1454
+ // ============================================================================
1455
+ //
1456
+ // Previously this module also produced raw DrawingML XML for spPr / txPr via
1457
+ // a `colorToXml` helper. That path was removed because the chart writer
1458
+ // (`chart-space-xform._renderSpPr` / `_renderTxPr` / `_renderColor`) emits
1459
+ // the XML directly from structured data, and returning raw XML here forced
1460
+ // callers to rebuild `buildTxPr` after every mutation. The helper was dead
1461
+ // code and has been deleted — see the note on `buildTxPr` below.
1462
+ /**
1463
+ * Build a structured ShapeProperties object, preserving every field that
1464
+ * `parseSpPr` can produce (fill, line, effectList, scene3d, sp3d, transform,
1465
+ * presetGeometry, customGeometry, bwMode).
1466
+ *
1467
+ * Previous versions only copied a five-field subset, which caused
1468
+ * `setSpPrFill` / `setSpPrLine` to silently strip `xfrm` / `prstGeom` /
1469
+ * `custGeom` off the returned spPr whenever the input had been parsed from
1470
+ * raw XML. The earlier `_rawXml` round-trip path was dropped because it lost
1471
+ * effectList/scene3d/sp3d; we now keep all structured fields and intentionally
1472
+ * omit `_rawXml` so that `_renderSpPr` (chart-space-xform) re-emits the spPr
1473
+ * from the structured data.
1474
+ */
1475
+ function buildSpPr(props) {
1476
+ const result = {};
1477
+ if (props.fill) {
1478
+ result.fill = props.fill;
1479
+ }
1480
+ if (props.line) {
1481
+ result.line = props.line;
1482
+ }
1483
+ if (props.effectList) {
1484
+ result.effectList = props.effectList;
1485
+ }
1486
+ if (props.scene3d) {
1487
+ result.scene3d = props.scene3d;
1488
+ }
1489
+ if (props.sp3d) {
1490
+ result.sp3d = props.sp3d;
1491
+ }
1492
+ if (props.transform) {
1493
+ result.transform = props.transform;
1494
+ }
1495
+ if (props.presetGeometry) {
1496
+ result.presetGeometry = props.presetGeometry;
1497
+ }
1498
+ if (props.customGeometry) {
1499
+ result.customGeometry = props.customGeometry;
1500
+ }
1501
+ return result;
1502
+ }
1503
+ /**
1504
+ * Build a structured {@link ChartTextProperties} object.
1505
+ *
1506
+ * Returns a plain structured copy (no `_rawXml`) so downstream mutations
1507
+ * (`props.size = 1400`) take effect when the txPr is later serialised.
1508
+ * The writer (`_renderTxPr` / `_renderRunProperties` in
1509
+ * `chart-space-xform.ts`) fully supports structured txPr data and only
1510
+ * falls back to raw XML pass-through when `_rawXml` is present; returning
1511
+ * `_rawXml` here would freeze the txPr and silently discard subsequent
1512
+ * edits, which is a trap API.
1513
+ */
1514
+ function buildTxPr(props) {
1515
+ const result = {};
1516
+ if (props.size !== undefined) {
1517
+ result.size = props.size;
1518
+ }
1519
+ if (props.bold !== undefined) {
1520
+ result.bold = props.bold;
1521
+ }
1522
+ if (props.italic !== undefined) {
1523
+ result.italic = props.italic;
1524
+ }
1525
+ if (props.underline !== undefined) {
1526
+ result.underline = props.underline;
1527
+ }
1528
+ if (props.strike !== undefined) {
1529
+ result.strike = props.strike;
1530
+ }
1531
+ if (props.rotation !== undefined) {
1532
+ result.rotation = props.rotation;
1533
+ }
1534
+ if (props.baseline !== undefined) {
1535
+ result.baseline = props.baseline;
1536
+ }
1537
+ if (props.kern !== undefined) {
1538
+ result.kern = props.kern;
1539
+ }
1540
+ if (props.spacing !== undefined) {
1541
+ result.spacing = props.spacing;
1542
+ }
1543
+ if (props.cap !== undefined) {
1544
+ result.cap = props.cap;
1545
+ }
1546
+ if (props.lang !== undefined) {
1547
+ result.lang = props.lang;
1548
+ }
1549
+ if (props.color) {
1550
+ result.color = props.color;
1551
+ }
1552
+ if (props.fontFamily) {
1553
+ result.fontFamily = props.fontFamily;
1554
+ }
1555
+ if (props.eastAsianFamily) {
1556
+ result.eastAsianFamily = props.eastAsianFamily;
1557
+ }
1558
+ if (props.complexScriptFamily) {
1559
+ result.complexScriptFamily = props.complexScriptFamily;
1560
+ }
1561
+ return result;
1562
+ }
1563
+ /**
1564
+ * Modify a property on an existing spPr (raw or structured).
1565
+ * Returns a new ShapeProperties object with the modification applied.
1566
+ */
1567
+ function setSpPrFill(spPr, fill) {
1568
+ const parsed = spPr && isRawXml(spPr) ? parseSpPr(spPr) : (spPr ?? {});
1569
+ return buildSpPr({ ...parsed, fill });
1570
+ }
1571
+ /**
1572
+ * Modify line properties on an existing spPr.
1573
+ */
1574
+ function setSpPrLine(spPr, line) {
1575
+ const parsed = spPr && isRawXml(spPr) ? parseSpPr(spPr) : (spPr ?? {});
1576
+ return buildSpPr({ ...parsed, line });
1577
+ }