@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,2128 @@
1
+ "use strict";
2
+ /**
3
+ * Chart / chartEx internal structure check.
4
+ *
5
+ * Classic charts (`xl/charts/chartN.xml`) must contain both `c:chart` and
6
+ * `c:plotArea`. ChartEx charts must contain `cx:chart`, `cx:plotArea`
7
+ * and at least one `cx:series`; series must carry `layoutId` and their
8
+ * `dataId`/`axisId` back-references must resolve inside the chart.
9
+ * `cx:externalData` nodes must refer to a declared relationship.
10
+ *
11
+ * In addition we catch five chartEx schema-violation patterns that
12
+ * cause Excel 2016+ to drop the whole chartEx part with "Removed Part:
13
+ * /xl/drawings/drawingN.xml (Drawing shape)":
14
+ *
15
+ * - `<cx:series>` with more than one `<cx:dataId>` child
16
+ * (`CT_Series/dataId` has `maxOccurs="1"`; multi-dim series must
17
+ * use a single `<cx:data>` wrapper with multiple strDim/numDim).
18
+ * - `<cx:axisId>N</cx:axisId>`, `<cx:dataId>N</cx:dataId>`,
19
+ * `<cx:binCount>N</cx:binCount>`, `<cx:binSize>N</cx:binSize>`
20
+ * emitted as text content instead of `val="N"` attribute. The
21
+ * underlying types are `CT_UnsignedInteger`/`CT_Double`, which
22
+ * Excel's strict loader only accepts via the attribute form.
23
+ * - `<cx:auto/>` element anywhere in the chartEx. Auto binning is
24
+ * expressed by the ABSENCE of `binSize`/`binCount`, not a
25
+ * dedicated `<cx:auto/>` tag. The tag is schema-invalid.
26
+ * - `<cx:paretoLine>` child of `<cx:layoutPr>`. Not in the
27
+ * CT_SeriesLayoutProperties schema. A real pareto chart adds a
28
+ * second series with `layoutId="paretoLine"`.
29
+ * - `<cx:title>` with a direct `<cx:layout>` child. Title layout
30
+ * belongs in `extLst`-based extensions.
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.checkChart = checkChart;
34
+ const xml_utils_1 = require("./xml-utils");
35
+ const CHART_PATH_RE = /^xl\/charts\/chart\d+\.xml$/;
36
+ const CHARTEX_PATH_RE = /^xl\/charts\/chartEx\d+\.xml$/;
37
+ function checkChart(ctx) {
38
+ for (const [path, entry] of ctx.files()) {
39
+ if (ctx.reporter.capped) {
40
+ return;
41
+ }
42
+ if (entry.type === "directory") {
43
+ continue;
44
+ }
45
+ if (CHART_PATH_RE.test(path)) {
46
+ checkClassicChart(ctx, path);
47
+ }
48
+ else if (CHARTEX_PATH_RE.test(path)) {
49
+ checkChartEx(ctx, path);
50
+ }
51
+ }
52
+ }
53
+ function checkClassicChart(ctx, path) {
54
+ const dom = ctx.readDom(path);
55
+ if (!dom) {
56
+ return;
57
+ }
58
+ const root = dom.root;
59
+ if (!(0, xml_utils_1.hasDescendantLocal)(root, "chart")) {
60
+ ctx.reporter.error("chart-missing-chart", `${path}: missing c:chart`, path);
61
+ }
62
+ if (!(0, xml_utils_1.hasDescendantLocal)(root, "plotArea")) {
63
+ ctx.reporter.error("chart-missing-plotArea", `${path}: missing c:plotArea`, path);
64
+ }
65
+ // Schema-conformance pass: verifies child-element order, required
66
+ // child counts, enumerated attribute values and numeric ranges
67
+ // against ECMA-376 Part 1 §21.2.x / Microsoft OpenXML SDK
68
+ // ChildElementInfo. See the tables below.
69
+ checkClassicChartSchema(ctx, path, root);
70
+ }
71
+ const CT_CHART_TYPE_TAGS = [
72
+ "areaChart",
73
+ "area3DChart",
74
+ "lineChart",
75
+ "line3DChart",
76
+ "stockChart",
77
+ "radarChart",
78
+ "scatterChart",
79
+ "pieChart",
80
+ "pie3DChart",
81
+ "doughnutChart",
82
+ "barChart",
83
+ "bar3DChart",
84
+ "ofPieChart",
85
+ "surfaceChart",
86
+ "surface3DChart",
87
+ "bubbleChart"
88
+ ];
89
+ const CT_AXIS_TAGS = ["catAx", "valAx", "dateAx", "serAx"];
90
+ const CLASSIC_ORDER_RULES = [
91
+ // CT_ChartSpace (§21.2.2.29)
92
+ {
93
+ parent: "chartSpace",
94
+ order: [
95
+ "lang",
96
+ "roundedCorners",
97
+ "style",
98
+ "clrMapOvr",
99
+ "pivotSource",
100
+ "protection",
101
+ "chart",
102
+ "spPr",
103
+ "txPr",
104
+ "externalData",
105
+ "printSettings",
106
+ "userShapes",
107
+ "extLst"
108
+ ]
109
+ },
110
+ // CT_Chart (§21.2.2.27)
111
+ {
112
+ parent: "chart",
113
+ order: [
114
+ "title",
115
+ "autoTitleDeleted",
116
+ "pivotFmts",
117
+ "view3D",
118
+ "floor",
119
+ "sideWall",
120
+ "backWall",
121
+ "plotArea",
122
+ "legend",
123
+ "plotVisOnly",
124
+ "dispBlanksAs",
125
+ "showDLblsOverMax",
126
+ "extLst"
127
+ ]
128
+ },
129
+ // CT_PlotArea (§21.2.2.145). Two `<xsd:choice maxOccurs="unbounded">`
130
+ // groups — chart-type elements and axis elements — collapse into
131
+ // bucket placeholders.
132
+ {
133
+ parent: "plotArea",
134
+ order: ["layout", "__CHART_TYPES__", "__AXES__", "dTable", "spPr", "extLst"],
135
+ choiceGroups: [CT_CHART_TYPE_TAGS, CT_AXIS_TAGS]
136
+ },
137
+ // CT_DLbls (§21.2.2.49) — the biggest historical offender.
138
+ // Separator MUST come before showLeaderLines / leaderLines.
139
+ {
140
+ parent: "dLbls",
141
+ order: [
142
+ "dLbl",
143
+ "delete",
144
+ "numFmt",
145
+ "spPr",
146
+ "txPr",
147
+ "dLblPos",
148
+ "showLegendKey",
149
+ "showVal",
150
+ "showCatName",
151
+ "showSerName",
152
+ "showPercent",
153
+ "showBubbleSize",
154
+ "separator",
155
+ "showLeaderLines",
156
+ "leaderLines",
157
+ "extLst"
158
+ ]
159
+ },
160
+ // CT_DLbl (§21.2.2.47). The `delete` branch is mutually exclusive
161
+ // with the display-flag branch but we allow the tag here for
162
+ // ordering purposes; the choice violation is caught separately by
163
+ // `checkClassicDLblChoice` below.
164
+ {
165
+ parent: "dLbl",
166
+ order: [
167
+ "idx",
168
+ "delete",
169
+ "layout",
170
+ "tx",
171
+ "numFmt",
172
+ "spPr",
173
+ "txPr",
174
+ "dLblPos",
175
+ "showLegendKey",
176
+ "showVal",
177
+ "showCatName",
178
+ "showSerName",
179
+ "showPercent",
180
+ "showBubbleSize",
181
+ "separator",
182
+ "extLst"
183
+ ]
184
+ },
185
+ // CT_Scaling (§21.2.2.195). `max` precedes `min`.
186
+ { parent: "scaling", order: ["logBase", "orientation", "max", "min", "extLst"] },
187
+ // CT_CatAx (§21.2.2.25)
188
+ {
189
+ parent: "catAx",
190
+ order: [
191
+ "axId",
192
+ "scaling",
193
+ "delete",
194
+ "axPos",
195
+ "majorGridlines",
196
+ "minorGridlines",
197
+ "title",
198
+ "numFmt",
199
+ "majorTickMark",
200
+ "minorTickMark",
201
+ "tickLblPos",
202
+ "spPr",
203
+ "txPr",
204
+ "crossAx",
205
+ "crosses",
206
+ "crossesAt",
207
+ "auto",
208
+ "lblAlgn",
209
+ "lblOffset",
210
+ "tickLblSkip",
211
+ "tickMarkSkip",
212
+ "noMultiLvlLbl",
213
+ "extLst"
214
+ ]
215
+ },
216
+ // CT_ValAx (§21.2.2.226)
217
+ {
218
+ parent: "valAx",
219
+ order: [
220
+ "axId",
221
+ "scaling",
222
+ "delete",
223
+ "axPos",
224
+ "majorGridlines",
225
+ "minorGridlines",
226
+ "title",
227
+ "numFmt",
228
+ "majorTickMark",
229
+ "minorTickMark",
230
+ "tickLblPos",
231
+ "spPr",
232
+ "txPr",
233
+ "crossAx",
234
+ "crosses",
235
+ "crossesAt",
236
+ "crossBetween",
237
+ "majorUnit",
238
+ "minorUnit",
239
+ "dispUnits",
240
+ "extLst"
241
+ ]
242
+ },
243
+ // CT_DateAx (§21.2.2.39)
244
+ {
245
+ parent: "dateAx",
246
+ order: [
247
+ "axId",
248
+ "scaling",
249
+ "delete",
250
+ "axPos",
251
+ "majorGridlines",
252
+ "minorGridlines",
253
+ "title",
254
+ "numFmt",
255
+ "majorTickMark",
256
+ "minorTickMark",
257
+ "tickLblPos",
258
+ "spPr",
259
+ "txPr",
260
+ "crossAx",
261
+ "crosses",
262
+ "crossesAt",
263
+ "auto",
264
+ "lblOffset",
265
+ "baseTimeUnit",
266
+ "majorUnit",
267
+ "majorTimeUnit",
268
+ "minorUnit",
269
+ "minorTimeUnit",
270
+ "extLst"
271
+ ]
272
+ },
273
+ // CT_SerAx (§21.2.2.175)
274
+ {
275
+ parent: "serAx",
276
+ order: [
277
+ "axId",
278
+ "scaling",
279
+ "delete",
280
+ "axPos",
281
+ "majorGridlines",
282
+ "minorGridlines",
283
+ "title",
284
+ "numFmt",
285
+ "majorTickMark",
286
+ "minorTickMark",
287
+ "tickLblPos",
288
+ "spPr",
289
+ "txPr",
290
+ "crossAx",
291
+ "crosses",
292
+ "crossesAt",
293
+ "tickLblSkip",
294
+ "tickMarkSkip",
295
+ "extLst"
296
+ ]
297
+ },
298
+ // CT_Trendline (§21.2.2.211)
299
+ {
300
+ parent: "trendline",
301
+ order: [
302
+ "name",
303
+ "spPr",
304
+ "trendlineType",
305
+ "order",
306
+ "period",
307
+ "forward",
308
+ "backward",
309
+ "intercept",
310
+ "dispRSqr",
311
+ "dispEq",
312
+ "trendlineLbl",
313
+ "extLst"
314
+ ]
315
+ },
316
+ // CT_ErrBars (§21.2.2.55)
317
+ {
318
+ parent: "errBars",
319
+ order: [
320
+ "errDir",
321
+ "errBarType",
322
+ "errValType",
323
+ "noEndCap",
324
+ "plus",
325
+ "minus",
326
+ "val",
327
+ "spPr",
328
+ "extLst"
329
+ ]
330
+ },
331
+ // CT_View3D (§21.2.2.228)
332
+ {
333
+ parent: "view3D",
334
+ order: ["rotX", "hPercent", "rotY", "depthPercent", "rAngAx", "perspective", "extLst"]
335
+ },
336
+ // CT_Legend (§21.2.2.93)
337
+ {
338
+ parent: "legend",
339
+ order: ["legendPos", "legendEntry", "layout", "overlay", "spPr", "txPr", "extLst"]
340
+ },
341
+ // CT_Title (§21.2.2.210)
342
+ { parent: "title", order: ["tx", "layout", "overlay", "spPr", "txPr", "extLst"] },
343
+ // ---------------------------------------------------------------------------
344
+ // Chart-type elements (§21.2.2.4 — §21.2.2.198). Each plotArea
345
+ // child must list its children in the canonical sequence. Excel
346
+ // tolerates many mis-orderings but LibreOffice strict mode
347
+ // rejects them; third-party OOXML validators (Microsoft's SDK,
348
+ // Calligra, xmllint + XSD) refuse too.
349
+ // ---------------------------------------------------------------------------
350
+ // CT_AreaChart (§21.2.2.5)
351
+ {
352
+ parent: "areaChart",
353
+ order: ["grouping", "varyColors", "ser", "dLbls", "dropLines", "axId", "extLst"]
354
+ },
355
+ // CT_Area3DChart (§21.2.2.4)
356
+ {
357
+ parent: "area3DChart",
358
+ order: ["grouping", "varyColors", "ser", "dLbls", "dropLines", "gapDepth", "axId", "extLst"]
359
+ },
360
+ // CT_BarChart (§21.2.2.16)
361
+ {
362
+ parent: "barChart",
363
+ order: [
364
+ "barDir",
365
+ "grouping",
366
+ "varyColors",
367
+ "ser",
368
+ "dLbls",
369
+ "gapWidth",
370
+ "overlap",
371
+ "serLines",
372
+ "axId",
373
+ "extLst"
374
+ ]
375
+ },
376
+ // CT_Bar3DChart (§21.2.2.15)
377
+ {
378
+ parent: "bar3DChart",
379
+ order: [
380
+ "barDir",
381
+ "grouping",
382
+ "varyColors",
383
+ "ser",
384
+ "dLbls",
385
+ "gapWidth",
386
+ "gapDepth",
387
+ "shape",
388
+ "axId",
389
+ "extLst"
390
+ ]
391
+ },
392
+ // CT_LineChart (§21.2.2.97)
393
+ {
394
+ parent: "lineChart",
395
+ order: [
396
+ "grouping",
397
+ "varyColors",
398
+ "ser",
399
+ "dLbls",
400
+ "dropLines",
401
+ "hiLowLines",
402
+ "upDownBars",
403
+ "marker",
404
+ "smooth",
405
+ "axId",
406
+ "extLst"
407
+ ]
408
+ },
409
+ // CT_Line3DChart (§21.2.2.96)
410
+ {
411
+ parent: "line3DChart",
412
+ order: ["grouping", "varyColors", "ser", "dLbls", "dropLines", "gapDepth", "axId", "extLst"]
413
+ },
414
+ // CT_PieChart (§21.2.2.141)
415
+ { parent: "pieChart", order: ["varyColors", "ser", "dLbls", "firstSliceAng", "extLst"] },
416
+ // CT_Pie3DChart (§21.2.2.140) — no firstSliceAng, no holeSize.
417
+ { parent: "pie3DChart", order: ["varyColors", "ser", "dLbls", "extLst"] },
418
+ // CT_DoughnutChart (§21.2.2.50)
419
+ {
420
+ parent: "doughnutChart",
421
+ order: ["varyColors", "ser", "dLbls", "firstSliceAng", "holeSize", "extLst"]
422
+ },
423
+ // CT_OfPieChart (§21.2.2.126)
424
+ {
425
+ parent: "ofPieChart",
426
+ order: [
427
+ "ofPieType",
428
+ "varyColors",
429
+ "ser",
430
+ "dLbls",
431
+ "gapWidth",
432
+ "splitType",
433
+ "splitPos",
434
+ "custSplit",
435
+ "secondPieSize",
436
+ "serLines",
437
+ "extLst"
438
+ ]
439
+ },
440
+ // CT_ScatterChart (§21.2.2.161)
441
+ {
442
+ parent: "scatterChart",
443
+ order: ["scatterStyle", "varyColors", "ser", "dLbls", "axId", "extLst"]
444
+ },
445
+ // CT_BubbleChart (§21.2.2.20)
446
+ {
447
+ parent: "bubbleChart",
448
+ order: [
449
+ "varyColors",
450
+ "ser",
451
+ "dLbls",
452
+ "bubble3D",
453
+ "bubbleScale",
454
+ "showNegBubbles",
455
+ "sizeRepresents",
456
+ "axId",
457
+ "extLst"
458
+ ]
459
+ },
460
+ // CT_RadarChart (§21.2.2.153)
461
+ {
462
+ parent: "radarChart",
463
+ order: ["radarStyle", "varyColors", "ser", "dLbls", "axId", "extLst"]
464
+ },
465
+ // CT_StockChart (§21.2.2.198)
466
+ {
467
+ parent: "stockChart",
468
+ order: ["ser", "dLbls", "dropLines", "hiLowLines", "upDownBars", "axId", "extLst"]
469
+ },
470
+ // CT_SurfaceChart (§21.2.2.193) / CT_Surface3DChart
471
+ { parent: "surfaceChart", order: ["wireframe", "ser", "bandFmts", "axId", "extLst"] },
472
+ { parent: "surface3DChart", order: ["wireframe", "ser", "bandFmts", "axId", "extLst"] },
473
+ // ---------------------------------------------------------------------------
474
+ // Auxiliary complex types (§21.2.2.x). Sequences that appear
475
+ // throughout the chart graph — getting them out of order is a
476
+ // common bug source (and historically Excel tolerates it while
477
+ // LibreOffice strict refuses the file).
478
+ // ---------------------------------------------------------------------------
479
+ // CT_DPt (§21.2.2.52)
480
+ {
481
+ parent: "dPt",
482
+ order: [
483
+ "idx",
484
+ "invertIfNegative",
485
+ "marker",
486
+ "bubble3D",
487
+ "explosion",
488
+ "spPr",
489
+ "pictureOptions",
490
+ "extLst"
491
+ ]
492
+ },
493
+ // CT_Marker (§21.2.2.106)
494
+ { parent: "marker", order: ["symbol", "size", "spPr", "extLst"] },
495
+ // CT_UpDownBars (§21.2.2.218)
496
+ { parent: "upDownBars", order: ["gapWidth", "upBars", "downBars", "extLst"] },
497
+ // CT_NumRef / CT_StrRef / CT_MultiLvlStrRef (§21.2.2.121 / .189 / .113)
498
+ { parent: "numRef", order: ["f", "numCache", "extLst"] },
499
+ { parent: "strRef", order: ["f", "strCache", "extLst"] },
500
+ { parent: "multiLvlStrRef", order: ["f", "multiLvlStrCache", "extLst"] },
501
+ // CT_NumData / CT_StrData (§21.2.2.122 / .188)
502
+ { parent: "numCache", order: ["formatCode", "ptCount", "pt", "extLst"] },
503
+ { parent: "strCache", order: ["ptCount", "pt", "extLst"] },
504
+ { parent: "multiLvlStrCache", order: ["ptCount", "lvl", "extLst"] },
505
+ // CT_NumLit / CT_StrLit
506
+ { parent: "numLit", order: ["formatCode", "ptCount", "pt", "extLst"] },
507
+ { parent: "strLit", order: ["ptCount", "pt", "extLst"] },
508
+ // CT_Pt (§21.2.2.146): v element; idx is an attribute.
509
+ { parent: "pt", order: ["v"] },
510
+ // CT_Layout (§21.2.2.88) / CT_ManualLayout (§21.2.2.105)
511
+ { parent: "layout", order: ["manualLayout", "extLst"] },
512
+ {
513
+ parent: "manualLayout",
514
+ order: ["layoutTarget", "xMode", "yMode", "wMode", "hMode", "x", "y", "w", "h", "extLst"]
515
+ },
516
+ // CT_DTable (§21.2.2.54)
517
+ {
518
+ parent: "dTable",
519
+ order: ["showHorzBorder", "showVertBorder", "showOutline", "showKeys", "spPr", "txPr", "extLst"]
520
+ },
521
+ // CT_BandFormats (§21.2.2.12) / CT_BandFormat (§21.2.2.11)
522
+ { parent: "bandFmts", order: ["bandFmt"] },
523
+ { parent: "bandFmt", order: ["idx", "spPr"] },
524
+ // CT_TrendlineLbl (§21.2.2.212) — layout? tx? numFmt? spPr? txPr? extLst?
525
+ {
526
+ parent: "trendlineLbl",
527
+ order: ["layout", "tx", "numFmt", "spPr", "txPr", "extLst"]
528
+ },
529
+ // CT_PictureOptions (§21.2.2.144)
530
+ {
531
+ parent: "pictureOptions",
532
+ order: ["applyToFront", "applyToSides", "applyToEnd", "pictureFormat", "pictureStackUnit"]
533
+ }
534
+ ];
535
+ const SERIES_ORDER_RULES = [
536
+ // CT_BarSer (§21.2.2.17)
537
+ {
538
+ chartTypes: ["barChart", "bar3DChart"],
539
+ order: [
540
+ "idx",
541
+ "order",
542
+ "tx",
543
+ "spPr",
544
+ "invertIfNegative",
545
+ "pictureOptions",
546
+ "dPt",
547
+ "dLbls",
548
+ "trendline",
549
+ "errBars",
550
+ "cat",
551
+ "val",
552
+ "shape",
553
+ "extLst"
554
+ ]
555
+ },
556
+ // CT_LineSer (§21.2.2.99) — line3D uses same structure.
557
+ {
558
+ chartTypes: ["lineChart", "line3DChart", "stockChart"],
559
+ order: [
560
+ "idx",
561
+ "order",
562
+ "tx",
563
+ "spPr",
564
+ "marker",
565
+ "dPt",
566
+ "dLbls",
567
+ "trendline",
568
+ "errBars",
569
+ "cat",
570
+ "val",
571
+ "smooth",
572
+ "extLst"
573
+ ]
574
+ },
575
+ // CT_PieSer (§21.2.2.149) — pie / pie3D / doughnut / ofPie share.
576
+ {
577
+ chartTypes: ["pieChart", "pie3DChart", "doughnutChart", "ofPieChart"],
578
+ order: ["idx", "order", "tx", "spPr", "explosion", "dPt", "dLbls", "cat", "val", "extLst"]
579
+ },
580
+ // CT_AreaSer (§21.2.2.3)
581
+ {
582
+ chartTypes: ["areaChart", "area3DChart"],
583
+ order: [
584
+ "idx",
585
+ "order",
586
+ "tx",
587
+ "spPr",
588
+ "pictureOptions",
589
+ "dPt",
590
+ "dLbls",
591
+ "trendline",
592
+ "errBars",
593
+ "cat",
594
+ "val",
595
+ "extLst"
596
+ ]
597
+ },
598
+ // CT_ScatterSer (§21.2.2.167)
599
+ {
600
+ chartTypes: ["scatterChart"],
601
+ order: [
602
+ "idx",
603
+ "order",
604
+ "tx",
605
+ "spPr",
606
+ "marker",
607
+ "dPt",
608
+ "dLbls",
609
+ "trendline",
610
+ "errBars",
611
+ "xVal",
612
+ "yVal",
613
+ "smooth",
614
+ "extLst"
615
+ ]
616
+ },
617
+ // CT_BubbleSer (§21.2.2.19)
618
+ {
619
+ chartTypes: ["bubbleChart"],
620
+ order: [
621
+ "idx",
622
+ "order",
623
+ "tx",
624
+ "spPr",
625
+ "invertIfNegative",
626
+ "dPt",
627
+ "dLbls",
628
+ "trendline",
629
+ "errBars",
630
+ "xVal",
631
+ "yVal",
632
+ "bubbleSize",
633
+ "bubble3D",
634
+ "extLst"
635
+ ]
636
+ },
637
+ // CT_RadarSer (§21.2.2.153)
638
+ {
639
+ chartTypes: ["radarChart"],
640
+ order: ["idx", "order", "tx", "spPr", "marker", "dPt", "dLbls", "cat", "val", "extLst"]
641
+ },
642
+ // CT_SurfaceSer (§21.2.2.191)
643
+ {
644
+ chartTypes: ["surfaceChart", "surface3DChart"],
645
+ order: ["idx", "order", "tx", "spPr", "cat", "val", "extLst"]
646
+ }
647
+ ];
648
+ const CLASSIC_REQUIRED_CHILDREN = [
649
+ // Chart types that plot against a Cartesian coordinate system
650
+ // reference their axes by `c:axId`. 2-D variants need exactly two
651
+ // axis references, 3-D variants need three (X / Y / Z / series).
652
+ { parent: "barChart", child: "axId", min: 2, max: 2 },
653
+ { parent: "barChart", child: "barDir", min: 1, max: 1 },
654
+ { parent: "bar3DChart", child: "axId", min: 3, max: 3 },
655
+ { parent: "bar3DChart", child: "barDir", min: 1, max: 1 },
656
+ { parent: "lineChart", child: "axId", min: 2, max: 2 },
657
+ { parent: "lineChart", child: "grouping", min: 1, max: 1 },
658
+ { parent: "line3DChart", child: "axId", min: 3, max: 3 },
659
+ { parent: "line3DChart", child: "grouping", min: 1, max: 1 },
660
+ { parent: "areaChart", child: "axId", min: 2, max: 2 },
661
+ { parent: "area3DChart", child: "axId", min: 3, max: 3 },
662
+ { parent: "scatterChart", child: "axId", min: 2, max: 2 },
663
+ { parent: "scatterChart", child: "scatterStyle", min: 1, max: 1 },
664
+ { parent: "bubbleChart", child: "axId", min: 2, max: 2 },
665
+ { parent: "radarChart", child: "axId", min: 2, max: 2 },
666
+ { parent: "radarChart", child: "radarStyle", min: 1, max: 1 },
667
+ { parent: "stockChart", child: "axId", min: 2, max: 2 },
668
+ { parent: "surfaceChart", child: "axId", min: 3, max: 3 },
669
+ { parent: "surface3DChart", child: "axId", min: 3, max: 3 },
670
+ { parent: "ofPieChart", child: "ofPieType", min: 1, max: 1 },
671
+ // Axes require axId / scaling / axPos / crossAx.
672
+ { parent: "catAx", child: "axId", min: 1, max: 1 },
673
+ { parent: "catAx", child: "scaling", min: 1, max: 1 },
674
+ { parent: "catAx", child: "axPos", min: 1, max: 1 },
675
+ { parent: "catAx", child: "crossAx", min: 1, max: 1 },
676
+ { parent: "valAx", child: "axId", min: 1, max: 1 },
677
+ { parent: "valAx", child: "scaling", min: 1, max: 1 },
678
+ { parent: "valAx", child: "axPos", min: 1, max: 1 },
679
+ { parent: "valAx", child: "crossAx", min: 1, max: 1 },
680
+ { parent: "dateAx", child: "axId", min: 1, max: 1 },
681
+ { parent: "dateAx", child: "scaling", min: 1, max: 1 },
682
+ { parent: "dateAx", child: "axPos", min: 1, max: 1 },
683
+ { parent: "dateAx", child: "crossAx", min: 1, max: 1 },
684
+ { parent: "serAx", child: "axId", min: 1, max: 1 },
685
+ { parent: "serAx", child: "scaling", min: 1, max: 1 },
686
+ { parent: "serAx", child: "axPos", min: 1, max: 1 },
687
+ { parent: "serAx", child: "crossAx", min: 1, max: 1 },
688
+ // Every series carries idx + order.
689
+ { parent: "ser", child: "idx", min: 1, max: 1 },
690
+ { parent: "ser", child: "order", min: 1, max: 1 },
691
+ // Trendline / errBars / dPt / dLbl header attributes.
692
+ { parent: "trendline", child: "trendlineType", min: 1, max: 1 },
693
+ { parent: "errBars", child: "errBarType", min: 1, max: 1 },
694
+ { parent: "errBars", child: "errValType", min: 1, max: 1 },
695
+ { parent: "dPt", child: "idx", min: 1, max: 1 },
696
+ { parent: "dLbl", child: "idx", min: 1, max: 1 }
697
+ ];
698
+ const CLASSIC_ENUM_RULES = [
699
+ { element: "barDir", attr: "val", allowed: ["bar", "col"] },
700
+ {
701
+ element: "grouping",
702
+ attr: "val",
703
+ allowed: ["standard", "stacked", "percentStacked", "clustered"]
704
+ },
705
+ { element: "orientation", attr: "val", allowed: ["minMax", "maxMin"] },
706
+ { element: "ofPieType", attr: "val", allowed: ["pie", "bar"] },
707
+ {
708
+ element: "dLblPos",
709
+ attr: "val",
710
+ allowed: ["b", "bestFit", "ctr", "inBase", "inEnd", "l", "outEnd", "r", "t"]
711
+ },
712
+ { element: "legendPos", attr: "val", allowed: ["b", "l", "r", "t", "tr"] },
713
+ {
714
+ element: "scatterStyle",
715
+ attr: "val",
716
+ allowed: ["none", "line", "lineMarker", "marker", "smooth", "smoothMarker"]
717
+ },
718
+ { element: "radarStyle", attr: "val", allowed: ["standard", "marker", "filled"] },
719
+ { element: "dispBlanksAs", attr: "val", allowed: ["span", "gap", "zero"] },
720
+ { element: "splitType", attr: "val", allowed: ["auto", "cust", "percent", "pos", "val"] },
721
+ {
722
+ element: "shape",
723
+ attr: "val",
724
+ allowed: ["cone", "coneToMax", "box", "cylinder", "pyramid", "pyramidToMax"]
725
+ },
726
+ { element: "crosses", attr: "val", allowed: ["autoZero", "min", "max"] },
727
+ { element: "crossBetween", attr: "val", allowed: ["between", "midCat"] },
728
+ { element: "lblAlgn", attr: "val", allowed: ["ctr", "l", "r"] },
729
+ { element: "axPos", attr: "val", allowed: ["b", "l", "r", "t"] },
730
+ { element: "majorTickMark", attr: "val", allowed: ["cross", "in", "none", "out"] },
731
+ { element: "minorTickMark", attr: "val", allowed: ["cross", "in", "none", "out"] },
732
+ { element: "tickLblPos", attr: "val", allowed: ["high", "low", "nextTo", "none"] },
733
+ { element: "baseTimeUnit", attr: "val", allowed: ["days", "months", "years"] },
734
+ { element: "majorTimeUnit", attr: "val", allowed: ["days", "months", "years"] },
735
+ { element: "minorTimeUnit", attr: "val", allowed: ["days", "months", "years"] },
736
+ {
737
+ element: "trendlineType",
738
+ attr: "val",
739
+ allowed: ["exp", "linear", "log", "movingAvg", "poly", "power"]
740
+ },
741
+ { element: "errDir", attr: "val", allowed: ["x", "y"] },
742
+ { element: "errBarType", attr: "val", allowed: ["both", "minus", "plus"] },
743
+ {
744
+ element: "errValType",
745
+ attr: "val",
746
+ allowed: ["cust", "fixedVal", "percentage", "stdDev", "stdErr"]
747
+ },
748
+ {
749
+ element: "symbol",
750
+ attr: "val",
751
+ allowed: [
752
+ "auto",
753
+ "circle",
754
+ "dash",
755
+ "diamond",
756
+ "dot",
757
+ "none",
758
+ "picture",
759
+ "plus",
760
+ "square",
761
+ "star",
762
+ "triangle",
763
+ "x"
764
+ ]
765
+ },
766
+ { element: "sizeRepresents", attr: "val", allowed: ["area", "w"] },
767
+ // DrawingML theme-palette slots — `<a:schemeClr val>` must be one
768
+ // of the 17 canonical slot names per ECMA-376 §20.1.10.54
769
+ // (`ST_SchemeColorVal`). Typos here either inherit Excel's
770
+ // "Accent 1" default or strip the fill entirely depending on
771
+ // build.
772
+ {
773
+ element: "schemeClr",
774
+ attr: "val",
775
+ allowed: [
776
+ "bg1",
777
+ "bg2",
778
+ "tx1",
779
+ "tx2",
780
+ "accent1",
781
+ "accent2",
782
+ "accent3",
783
+ "accent4",
784
+ "accent5",
785
+ "accent6",
786
+ "hlink",
787
+ "folHlink",
788
+ "phClr",
789
+ "dk1",
790
+ "dk2",
791
+ "lt1",
792
+ "lt2"
793
+ ]
794
+ }
795
+ ];
796
+ const CLASSIC_RANGE_RULES = [
797
+ { element: "holeSize", attr: "val", min: 10, max: 90 },
798
+ { element: "firstSliceAng", attr: "val", min: 0, max: 360 },
799
+ { element: "overlap", attr: "val", min: -100, max: 100 },
800
+ { element: "gapWidth", attr: "val", min: 0, max: 500 },
801
+ { element: "gapDepth", attr: "val", min: 0, max: 500 },
802
+ { element: "rotX", attr: "val", min: -90, max: 90 },
803
+ { element: "rotY", attr: "val", min: 0, max: 360 },
804
+ { element: "perspective", attr: "val", min: 0, max: 240 },
805
+ { element: "hPercent", attr: "val", min: 5, max: 500 },
806
+ { element: "depthPercent", attr: "val", min: 20, max: 2000 },
807
+ { element: "bubbleScale", attr: "val", min: 0, max: 300 },
808
+ { element: "secondPieSize", attr: "val", min: 5, max: 200 },
809
+ // Axis units must be strictly positive. `Number.EPSILON` is a
810
+ // close-to-zero sentinel that rejects 0 and negatives while
811
+ // permitting the smallest finite positive a double can express.
812
+ { element: "majorUnit", attr: "val", min: Number.EPSILON, max: Number.MAX_VALUE },
813
+ { element: "minorUnit", attr: "val", min: Number.EPSILON, max: Number.MAX_VALUE },
814
+ // Tick-label / tick-mark skip: 1 = every tick, so >= 1 per schema
815
+ // (CT_Skip uses `xsd:unsignedInt` with a required minimum of 1).
816
+ { element: "tickLblSkip", attr: "val", min: 1, max: Number.MAX_SAFE_INTEGER },
817
+ { element: "tickMarkSkip", attr: "val", min: 1, max: Number.MAX_SAFE_INTEGER },
818
+ // DrawingML `<a:alpha val>` is CT_PositiveFixedPercentage
819
+ // (0 to 100000 representing 0% to 100%).
820
+ { element: "alpha", attr: "val", min: 0, max: 100000 }
821
+ ];
822
+ function checkClassicChartSchema(ctx, path, root) {
823
+ checkClassicChildOrder(ctx, path, root);
824
+ checkClassicRequiredChildren(ctx, path, root);
825
+ checkClassicEnumValues(ctx, path, root);
826
+ checkClassicNumericRanges(ctx, path, root);
827
+ checkClassicDLblChoice(ctx, path, root);
828
+ checkContextAwareChartRules(ctx, path, root);
829
+ checkDataReferenceStructure(ctx, path, root);
830
+ checkSeriesChildOrder(ctx, path, root);
831
+ checkAxIdResolution(ctx, path, root);
832
+ checkErrBarsConditionalChildren(ctx, path, root);
833
+ checkTxChoice(ctx, path, root);
834
+ checkSeriesChildWhitelist(ctx, path, root);
835
+ checkSrgbClrFormat(ctx, path, root);
836
+ checkNumFmtFormatCode(ctx, path, root);
837
+ checkRichStructure(ctx, path, root);
838
+ // Cross-part reference checks — these reach into `xl/theme/theme1.xml`
839
+ // and `xl/workbook.xml` via ctx.readDom (cached).
840
+ checkThemeSchemeColorSlots(ctx, path, root);
841
+ checkFormulaSyntax(ctx, path, root);
842
+ checkDefinedNameResolution(ctx, path, root);
843
+ }
844
+ function checkClassicChildOrder(ctx, path, root) {
845
+ for (const rule of CLASSIC_ORDER_RULES) {
846
+ for (const parent of (0, xml_utils_1.collectDescendantsLocal)(root, rule.parent)) {
847
+ if (ctx.reporter.capped) {
848
+ return;
849
+ }
850
+ const children = parent.children.filter(c => c.type === "element");
851
+ const rankOf = (tag) => {
852
+ if (rule.choiceGroups) {
853
+ for (let i = 0; i < rule.choiceGroups.length; i++) {
854
+ if (rule.choiceGroups[i].includes(tag)) {
855
+ // Every tag in the same choice group maps to the same
856
+ // virtual bucket ("__CHART_TYPES__" / "__AXES__") so
857
+ // they compare equal in sibling-order checks.
858
+ return rule.order.indexOf(`__${i === 0 ? "CHART_TYPES" : "AXES"}__`);
859
+ }
860
+ }
861
+ }
862
+ return rule.order.indexOf(tag);
863
+ };
864
+ let lastRank = -1;
865
+ let lastTag = "";
866
+ for (const child of children) {
867
+ const name = (0, xml_utils_1.localName)(child.name);
868
+ const rank = rankOf(name);
869
+ if (rank < 0) {
870
+ continue;
871
+ }
872
+ if (rank < lastRank) {
873
+ ctx.reporter.error("chart-child-out-of-order", `${path}: <c:${rule.parent}> child <c:${name}> appears after <c:${lastTag}> — ECMA-376 requires it before per CT_${capitalise(rule.parent)}.`, path);
874
+ }
875
+ if (rank >= lastRank) {
876
+ lastRank = rank;
877
+ lastTag = name;
878
+ }
879
+ }
880
+ }
881
+ }
882
+ }
883
+ function checkClassicRequiredChildren(ctx, path, root) {
884
+ for (const rule of CLASSIC_REQUIRED_CHILDREN) {
885
+ for (const parent of (0, xml_utils_1.collectDescendantsLocal)(root, rule.parent)) {
886
+ if (ctx.reporter.capped) {
887
+ return;
888
+ }
889
+ const n = (0, xml_utils_1.findChildrenLocal)(parent, rule.child).length;
890
+ if (n < rule.min) {
891
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:${rule.parent}> has ${n} <c:${rule.child}> child(ren); schema requires at least ${rule.min}.`, path);
892
+ }
893
+ if (rule.max !== undefined && n > rule.max) {
894
+ ctx.reporter.error("chart-wrong-child-count", `${path}: <c:${rule.parent}> has ${n} <c:${rule.child}> child(ren); schema permits at most ${rule.max}.`, path);
895
+ }
896
+ }
897
+ }
898
+ }
899
+ function checkClassicEnumValues(ctx, path, root) {
900
+ for (const rule of CLASSIC_ENUM_RULES) {
901
+ for (const el of (0, xml_utils_1.collectDescendantsLocal)(root, rule.element)) {
902
+ if (ctx.reporter.capped) {
903
+ return;
904
+ }
905
+ const val = (0, xml_utils_1.attrByLocalName)(el, rule.attr);
906
+ if (val === undefined) {
907
+ continue;
908
+ }
909
+ if (!rule.allowed.includes(val)) {
910
+ ctx.reporter.error("chart-invalid-enum-value", `${path}: <c:${rule.element} ${rule.attr}="${val}"> — ${val} is not in {${rule.allowed.join(", ")}}.`, path);
911
+ }
912
+ }
913
+ }
914
+ }
915
+ function checkClassicNumericRanges(ctx, path, root) {
916
+ for (const rule of CLASSIC_RANGE_RULES) {
917
+ for (const el of (0, xml_utils_1.collectDescendantsLocal)(root, rule.element)) {
918
+ if (ctx.reporter.capped) {
919
+ return;
920
+ }
921
+ const raw = (0, xml_utils_1.attrByLocalName)(el, rule.attr);
922
+ if (raw === undefined) {
923
+ continue;
924
+ }
925
+ const num = parseFloat(raw);
926
+ if (!Number.isFinite(num)) {
927
+ ctx.reporter.error("chart-value-out-of-range", `${path}: <c:${rule.element} ${rule.attr}="${raw}"> is not a finite number.`, path);
928
+ continue;
929
+ }
930
+ if (num < rule.min || num > rule.max) {
931
+ ctx.reporter.error("chart-value-out-of-range", `${path}: <c:${rule.element} ${rule.attr}="${num}"> outside [${rule.min}, ${rule.max}].`, path);
932
+ }
933
+ }
934
+ }
935
+ }
936
+ /**
937
+ * `CT_DLbl` is `idx, choice(delete | (layout, tx, numFmt, spPr,
938
+ * txPr, dLblPos, show*..., separator)), extLst?`. The two choice
939
+ * branches are mutually exclusive — emitting `delete` alongside
940
+ * any display-flag child is a schema violation that Excel's
941
+ * loader has been observed to handle inconsistently (some builds
942
+ * strip the label wholesale, others silently drop `delete`).
943
+ */
944
+ function checkClassicDLblChoice(ctx, path, root) {
945
+ const displayBranchTags = new Set([
946
+ "layout",
947
+ "tx",
948
+ "numFmt",
949
+ "spPr",
950
+ "txPr",
951
+ "dLblPos",
952
+ "showLegendKey",
953
+ "showVal",
954
+ "showCatName",
955
+ "showSerName",
956
+ "showPercent",
957
+ "showBubbleSize",
958
+ "separator"
959
+ ]);
960
+ for (const dLbl of (0, xml_utils_1.collectDescendantsLocal)(root, "dLbl")) {
961
+ if (ctx.reporter.capped) {
962
+ return;
963
+ }
964
+ const hasDelete = (0, xml_utils_1.findChildLocal)(dLbl, "delete") !== undefined;
965
+ if (!hasDelete) {
966
+ continue;
967
+ }
968
+ const conflictingChild = dLbl.children.find(c => c.type === "element" && displayBranchTags.has((0, xml_utils_1.localName)(c.name)));
969
+ if (conflictingChild) {
970
+ ctx.reporter.error("chart-child-out-of-order", `${path}: <c:dLbl> has both <c:delete> and <c:${(0, xml_utils_1.localName)(conflictingChild.name)}>; CT_DLbl's choice group requires one branch or the other, never both.`, path);
971
+ }
972
+ }
973
+ }
974
+ function capitalise(s) {
975
+ return s.length === 0 ? s : s.charAt(0).toUpperCase() + s.slice(1);
976
+ }
977
+ // -----------------------------------------------------------------------------
978
+ // Context-aware rules — chart-type-specific restrictions that the
979
+ // generic schema tables above cannot express. Each rule scopes itself
980
+ // to one or more `c:*Chart` parents so the same child element gets
981
+ // validated differently based on where it lives.
982
+ // -----------------------------------------------------------------------------
983
+ /**
984
+ * Per-chart-type `c:dLblPos` allow-list. Although ECMA-376 `ST_DLblPos`
985
+ * permits all nine values globally, Excel's reader applies a stricter
986
+ * per-context filter that mirrors the "Label Position" picker in the
987
+ * Format Data Labels panel. Emitting a value outside the allow-list
988
+ * triggers "Repaired Records: Drawing" on open, and — for doughnut —
989
+ * causes the entire `drawing*.xml` part to be stripped.
990
+ *
991
+ * - `doughnut`: Excel's UI exposes no position choices at all; any
992
+ * `c:dLblPos` in a doughnut chart's `c:dLbls` causes the drawing
993
+ * part to be removed on open.
994
+ * - `bar` / `bar3D`: only the four "in/out/base/centre" positions.
995
+ * `inBase` is unique to bar and anchors the label to the axis end.
996
+ * - `line`, `line3D`, `scatter`, `bubble`, `radar`, `stock`: only the
997
+ * five cartesian positions (centre, above, below, left, right).
998
+ * - `pie`, `pie3D`, `ofPie`: the pie label set — bestFit is Excel's
999
+ * default and the only value that lets Excel place labels with
1000
+ * automatic leader lines.
1001
+ * - `area`, `area3D`: Excel only accepts `ctr` for area fills.
1002
+ * - `surface`, `surface3D`: data labels are forbidden entirely (see
1003
+ * `FORBIDDEN_CHILDREN_BY_CHART_TYPE` below).
1004
+ */
1005
+ const VALID_DLBL_POSITIONS_BY_CHART_TYPE = {
1006
+ barChart: new Set(["ctr", "inBase", "inEnd", "outEnd"]),
1007
+ bar3DChart: new Set(["ctr", "inBase", "inEnd", "outEnd"]),
1008
+ lineChart: new Set(["ctr", "l", "r", "t", "b"]),
1009
+ line3DChart: new Set(["ctr", "l", "r", "t", "b"]),
1010
+ scatterChart: new Set(["ctr", "l", "r", "t", "b"]),
1011
+ bubbleChart: new Set(["ctr", "l", "r", "t", "b"]),
1012
+ radarChart: new Set(["ctr", "l", "r", "t", "b"]),
1013
+ stockChart: new Set(["ctr", "l", "r", "t", "b"]),
1014
+ pieChart: new Set(["bestFit", "ctr", "inEnd", "outEnd"]),
1015
+ pie3DChart: new Set(["bestFit", "ctr", "inEnd", "outEnd"]),
1016
+ ofPieChart: new Set(["bestFit", "ctr", "inEnd", "outEnd"]),
1017
+ doughnutChart: new Set(),
1018
+ areaChart: new Set(["ctr"]),
1019
+ area3DChart: new Set(["ctr"])
1020
+ };
1021
+ /**
1022
+ * `c:trendline` and `c:errBars` are forbidden inside pie-family
1023
+ * series (`CT_PieSer` has neither slot per schema). They are also
1024
+ * forbidden on surface series. Emitting one produces a series Excel
1025
+ * refuses to render. `c:dataLabels` is forbidden on surface series.
1026
+ */
1027
+ const FORBIDDEN_CHILDREN_BY_CHART_TYPE = {
1028
+ pieChart: new Set(["trendline", "errBars"]),
1029
+ pie3DChart: new Set(["trendline", "errBars"]),
1030
+ doughnutChart: new Set(["trendline", "errBars"]),
1031
+ ofPieChart: new Set(["trendline", "errBars"]),
1032
+ surfaceChart: new Set(["trendline", "errBars", "dLbls", "marker"]),
1033
+ surface3DChart: new Set(["trendline", "errBars", "dLbls", "marker"])
1034
+ };
1035
+ /**
1036
+ * `c:errBars` maxOccurs per series, per parent chart type.
1037
+ *
1038
+ * Scatter and bubble series use `CT_ScatterSer` / `CT_BubbleSer` whose
1039
+ * `errBars` element has `maxOccurs="2"` — one for direction `x`, one
1040
+ * for direction `y`. Every other series type caps at 1. Two entries
1041
+ * with the same `c:errDir` inside the same series are a schema
1042
+ * violation; Excel silently drops the duplicate (first one wins).
1043
+ */
1044
+ const ERRBARS_MAX_BY_CHART_TYPE = {
1045
+ scatterChart: 2,
1046
+ bubbleChart: 2,
1047
+ barChart: 1,
1048
+ bar3DChart: 1,
1049
+ lineChart: 1,
1050
+ line3DChart: 1,
1051
+ areaChart: 1,
1052
+ area3DChart: 1,
1053
+ radarChart: 1,
1054
+ stockChart: 1
1055
+ };
1056
+ /**
1057
+ * Required series count per chart type. `stockChart` needs 3 or 4
1058
+ * series (HLC or OHLC); everything else needs at least 1.
1059
+ */
1060
+ const SERIES_COUNT_BY_CHART_TYPE = {
1061
+ barChart: { min: 1 },
1062
+ bar3DChart: { min: 1 },
1063
+ lineChart: { min: 1 },
1064
+ line3DChart: { min: 1 },
1065
+ areaChart: { min: 1 },
1066
+ area3DChart: { min: 1 },
1067
+ scatterChart: { min: 1 },
1068
+ bubbleChart: { min: 1 },
1069
+ radarChart: { min: 1 },
1070
+ pieChart: { min: 1 },
1071
+ pie3DChart: { min: 1 },
1072
+ doughnutChart: { min: 1 },
1073
+ ofPieChart: { min: 1 },
1074
+ surfaceChart: { min: 1 },
1075
+ surface3DChart: { min: 1 },
1076
+ stockChart: { min: 3, max: 4 }
1077
+ };
1078
+ /**
1079
+ * Walk each chart-type group in the plot area and apply the
1080
+ * context-sensitive rules above:
1081
+ * - `c:dLblPos` value matches the allow-list for this type.
1082
+ * - `c:trendline` / `c:errBars` not present when forbidden.
1083
+ * - `c:errBars` cardinality + `c:errDir` uniqueness.
1084
+ * - Series count within the schema-permitted range.
1085
+ * - Series `c:idx` / `c:order` values unique inside the group.
1086
+ */
1087
+ function checkContextAwareChartRules(ctx, path, root) {
1088
+ for (const chartType of Object.keys(VALID_DLBL_POSITIONS_BY_CHART_TYPE)) {
1089
+ for (const group of (0, xml_utils_1.collectDescendantsLocal)(root, chartType)) {
1090
+ if (ctx.reporter.capped) {
1091
+ return;
1092
+ }
1093
+ checkDLblPosForChartType(ctx, path, group, chartType);
1094
+ checkForbiddenSeriesChildren(ctx, path, group, chartType);
1095
+ checkErrBarsCardinality(ctx, path, group, chartType);
1096
+ checkSeriesIdxOrderUnique(ctx, path, group, chartType);
1097
+ checkSeriesCount(ctx, path, group, chartType);
1098
+ }
1099
+ }
1100
+ // Surface / surface3D only participate in series-count + forbidden-
1101
+ // children checks — no dLblPos allow-list because Excel rejects
1102
+ // data labels on them wholesale.
1103
+ for (const chartType of ["surfaceChart", "surface3DChart"]) {
1104
+ for (const group of (0, xml_utils_1.collectDescendantsLocal)(root, chartType)) {
1105
+ if (ctx.reporter.capped) {
1106
+ return;
1107
+ }
1108
+ checkForbiddenSeriesChildren(ctx, path, group, chartType);
1109
+ checkSeriesCount(ctx, path, group, chartType);
1110
+ checkSeriesIdxOrderUnique(ctx, path, group, chartType);
1111
+ }
1112
+ }
1113
+ }
1114
+ function checkDLblPosForChartType(ctx, path, group, chartType) {
1115
+ const allowed = VALID_DLBL_POSITIONS_BY_CHART_TYPE[chartType];
1116
+ if (!allowed) {
1117
+ return;
1118
+ }
1119
+ for (const pos of (0, xml_utils_1.collectDescendantsLocal)(group, "dLblPos")) {
1120
+ if (ctx.reporter.capped) {
1121
+ return;
1122
+ }
1123
+ const val = (0, xml_utils_1.attrByLocalName)(pos, "val");
1124
+ if (val === undefined) {
1125
+ continue;
1126
+ }
1127
+ if (!allowed.has(val)) {
1128
+ const allowedList = allowed.size === 0
1129
+ ? "(none — this chart type does not accept c:dLblPos)"
1130
+ : [...allowed].sort().join(", ");
1131
+ ctx.reporter.error("chart-invalid-enum-value", `${path}: <c:dLblPos val="${val}"> inside <c:${chartType}> — Excel only accepts {${allowedList}} for this chart type.`, path);
1132
+ }
1133
+ }
1134
+ }
1135
+ function checkForbiddenSeriesChildren(ctx, path, group, chartType) {
1136
+ const forbidden = FORBIDDEN_CHILDREN_BY_CHART_TYPE[chartType];
1137
+ if (!forbidden || forbidden.size === 0) {
1138
+ return;
1139
+ }
1140
+ for (const series of (0, xml_utils_1.findChildrenLocal)(group, "ser")) {
1141
+ for (const child of series.children) {
1142
+ if (ctx.reporter.capped) {
1143
+ return;
1144
+ }
1145
+ if (child.type !== "element") {
1146
+ continue;
1147
+ }
1148
+ const name = (0, xml_utils_1.localName)(child.name);
1149
+ if (forbidden.has(name)) {
1150
+ ctx.reporter.error("chart-forbidden-child", `${path}: <c:ser> inside <c:${chartType}> contains <c:${name}>, which is not allowed for this chart type per ECMA-376.`, path);
1151
+ }
1152
+ }
1153
+ }
1154
+ // Surface charts forbid dLbls at the GROUP level too.
1155
+ if (forbidden.has("dLbls")) {
1156
+ for (const dLbls of (0, xml_utils_1.findChildrenLocal)(group, "dLbls")) {
1157
+ if (ctx.reporter.capped) {
1158
+ return;
1159
+ }
1160
+ void dLbls;
1161
+ ctx.reporter.error("chart-forbidden-child", `${path}: <c:${chartType}> contains group-level <c:dLbls>, which is not allowed for this chart type.`, path);
1162
+ }
1163
+ }
1164
+ }
1165
+ function checkErrBarsCardinality(ctx, path, group, chartType) {
1166
+ const max = ERRBARS_MAX_BY_CHART_TYPE[chartType];
1167
+ if (max === undefined) {
1168
+ return;
1169
+ }
1170
+ for (const series of (0, xml_utils_1.findChildrenLocal)(group, "ser")) {
1171
+ if (ctx.reporter.capped) {
1172
+ return;
1173
+ }
1174
+ const errBars = (0, xml_utils_1.findChildrenLocal)(series, "errBars");
1175
+ if (errBars.length > max) {
1176
+ ctx.reporter.error("chart-wrong-child-count", `${path}: <c:ser> inside <c:${chartType}> has ${errBars.length} <c:errBars> children; schema permits at most ${max}.`, path);
1177
+ }
1178
+ // When maxOccurs=2 (scatter/bubble), the two entries must carry
1179
+ // distinct `c:errDir` values.
1180
+ if (errBars.length === 2) {
1181
+ const dirs = errBars.map(eb => {
1182
+ const dirEl = (0, xml_utils_1.findChildLocal)(eb, "errDir");
1183
+ return dirEl ? (0, xml_utils_1.attrByLocalName)(dirEl, "val") : undefined;
1184
+ });
1185
+ if (dirs[0] !== undefined && dirs[1] !== undefined && dirs[0] === dirs[1]) {
1186
+ ctx.reporter.error("chart-duplicate-errBars-direction", `${path}: <c:ser> inside <c:${chartType}> has two <c:errBars> with the same <c:errDir val="${dirs[0]}"> — schema requires distinct directions (x + y).`, path);
1187
+ }
1188
+ }
1189
+ }
1190
+ }
1191
+ function checkSeriesIdxOrderUnique(ctx, path, group, chartType) {
1192
+ const series = (0, xml_utils_1.findChildrenLocal)(group, "ser");
1193
+ const seenIdx = new Set();
1194
+ const seenOrder = new Set();
1195
+ for (const s of series) {
1196
+ if (ctx.reporter.capped) {
1197
+ return;
1198
+ }
1199
+ const idxEl = (0, xml_utils_1.findChildLocal)(s, "idx");
1200
+ const orderEl = (0, xml_utils_1.findChildLocal)(s, "order");
1201
+ const idx = idxEl ? (0, xml_utils_1.attrByLocalName)(idxEl, "val") : undefined;
1202
+ const order = orderEl ? (0, xml_utils_1.attrByLocalName)(orderEl, "val") : undefined;
1203
+ if (idx !== undefined) {
1204
+ if (seenIdx.has(idx)) {
1205
+ ctx.reporter.error("chart-duplicate-series-idx", `${path}: <c:${chartType}> has two <c:ser> entries with <c:idx val="${idx}">; idx must be unique within a chart-type group.`, path);
1206
+ }
1207
+ seenIdx.add(idx);
1208
+ }
1209
+ if (order !== undefined) {
1210
+ if (seenOrder.has(order)) {
1211
+ ctx.reporter.error("chart-duplicate-series-order", `${path}: <c:${chartType}> has two <c:ser> entries with <c:order val="${order}">; order must be unique within a chart-type group.`, path);
1212
+ }
1213
+ seenOrder.add(order);
1214
+ }
1215
+ }
1216
+ }
1217
+ function checkSeriesCount(ctx, path, group, chartType) {
1218
+ const bounds = SERIES_COUNT_BY_CHART_TYPE[chartType];
1219
+ if (!bounds) {
1220
+ return;
1221
+ }
1222
+ const count = (0, xml_utils_1.findChildrenLocal)(group, "ser").length;
1223
+ if (count < bounds.min) {
1224
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:${chartType}> has ${count} <c:ser> children; schema requires at least ${bounds.min}${bounds.max !== undefined ? ` (and at most ${bounds.max})` : ""}.`, path);
1225
+ }
1226
+ if (bounds.max !== undefined && count > bounds.max) {
1227
+ ctx.reporter.error("chart-wrong-child-count", `${path}: <c:${chartType}> has ${count} <c:ser> children; schema permits at most ${bounds.max}.`, path);
1228
+ }
1229
+ }
1230
+ // -----------------------------------------------------------------------------
1231
+ // Data-reference structural checks — `c:numRef` / `c:strRef` /
1232
+ // `c:multiLvlStrRef` require `c:f`; their caches require `c:ptCount`;
1233
+ // every `c:pt` inside a cache needs `@idx` and a `c:v` child; `c:pt
1234
+ // idx` must stay inside the declared cache range.
1235
+ // -----------------------------------------------------------------------------
1236
+ const REF_ELEMENTS = ["numRef", "strRef", "multiLvlStrRef"];
1237
+ const LIT_ELEMENTS = ["numLit", "strLit"];
1238
+ const CACHE_ELEMENTS = ["numCache", "strCache", "multiLvlStrCache"];
1239
+ function checkDataReferenceStructure(ctx, path, root) {
1240
+ // `c:numRef`, `c:strRef`, `c:multiLvlStrRef` must carry `c:f`.
1241
+ for (const refName of REF_ELEMENTS) {
1242
+ for (const ref of (0, xml_utils_1.collectDescendantsLocal)(root, refName)) {
1243
+ if (ctx.reporter.capped) {
1244
+ return;
1245
+ }
1246
+ if (!(0, xml_utils_1.findChildLocal)(ref, "f")) {
1247
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:${refName}> is missing the required <c:f> formula child.`, path);
1248
+ }
1249
+ }
1250
+ }
1251
+ // `c:numLit` / `c:strLit` should carry `c:ptCount`.
1252
+ for (const litName of LIT_ELEMENTS) {
1253
+ for (const lit of (0, xml_utils_1.collectDescendantsLocal)(root, litName)) {
1254
+ if (ctx.reporter.capped) {
1255
+ return;
1256
+ }
1257
+ if (!(0, xml_utils_1.findChildLocal)(lit, "ptCount")) {
1258
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:${litName}> is missing the required <c:ptCount> child.`, path);
1259
+ }
1260
+ }
1261
+ }
1262
+ // Caches + `c:pt` integrity.
1263
+ for (const cacheName of CACHE_ELEMENTS) {
1264
+ for (const cache of (0, xml_utils_1.collectDescendantsLocal)(root, cacheName)) {
1265
+ if (ctx.reporter.capped) {
1266
+ return;
1267
+ }
1268
+ const ptCountEl = (0, xml_utils_1.findChildLocal)(cache, "ptCount");
1269
+ const ptCountVal = ptCountEl ? parseInt((0, xml_utils_1.attrByLocalName)(ptCountEl, "val") ?? "", 10) : NaN;
1270
+ const points = (0, xml_utils_1.findChildrenLocal)(cache, "pt");
1271
+ for (const pt of points) {
1272
+ const idxRaw = (0, xml_utils_1.attrByLocalName)(pt, "idx");
1273
+ if (idxRaw === undefined) {
1274
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:pt> inside <c:${cacheName}> is missing the required idx attribute.`, path);
1275
+ continue;
1276
+ }
1277
+ const idx = parseInt(idxRaw, 10);
1278
+ if (Number.isFinite(ptCountVal) && (idx < 0 || idx >= ptCountVal)) {
1279
+ ctx.reporter.error("chart-pt-idx-out-of-range", `${path}: <c:pt idx="${idx}"> outside declared range [0, ${ptCountVal - 1}] (from <c:ptCount val="${ptCountVal}">).`, path);
1280
+ }
1281
+ // `numCache` / `strCache` points need a `c:v` child carrying
1282
+ // the cached value.
1283
+ if (cacheName !== "multiLvlStrCache" && !(0, xml_utils_1.findChildLocal)(pt, "v")) {
1284
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:pt idx="${idx}"> inside <c:${cacheName}> is missing the required <c:v> value child.`, path);
1285
+ }
1286
+ }
1287
+ }
1288
+ }
1289
+ }
1290
+ // -----------------------------------------------------------------------------
1291
+ // End of classic chart schema conformance
1292
+ // -----------------------------------------------------------------------------
1293
+ function checkChartEx(ctx, path) {
1294
+ const dom = ctx.readDom(path);
1295
+ if (!dom) {
1296
+ return;
1297
+ }
1298
+ const root = dom.root;
1299
+ if (!(0, xml_utils_1.hasDescendantLocal)(root, "chart")) {
1300
+ ctx.reporter.error("chartEx-missing-chart", `${path}: missing cx:chart`, path);
1301
+ }
1302
+ if (!(0, xml_utils_1.hasDescendantLocal)(root, "plotArea")) {
1303
+ ctx.reporter.error("chartEx-missing-plotArea", `${path}: missing cx:plotArea`, path);
1304
+ }
1305
+ const seriesList = (0, xml_utils_1.collectDescendantsLocal)(root, "series");
1306
+ if (seriesList.length === 0) {
1307
+ ctx.reporter.error("chartEx-missing-series", `${path}: missing cx:series`, path);
1308
+ return;
1309
+ }
1310
+ const dataIds = new Set((0, xml_utils_1.collectDescendantsLocal)(root, "data")
1311
+ .map(el => parseInt((0, xml_utils_1.attrByLocalName)(el, "id") ?? "", 10))
1312
+ .filter(Number.isFinite));
1313
+ const axisIds = new Set((0, xml_utils_1.collectDescendantsLocal)(root, "axis")
1314
+ .map(el => parseInt((0, xml_utils_1.attrByLocalName)(el, "id") ?? "", 10))
1315
+ .filter(Number.isFinite));
1316
+ for (const series of seriesList) {
1317
+ if (!(0, xml_utils_1.attrByLocalName)(series, "layoutId")) {
1318
+ ctx.reporter.error("chartEx-series-missing-layoutId", `${path}: cx:series missing layoutId`, path);
1319
+ }
1320
+ const dataIdChildren = (0, xml_utils_1.findChildrenLocal)(series, "dataId");
1321
+ // Schema cardinality: `CT_Series/dataId` has `maxOccurs="1"`.
1322
+ // Multi-dimensional series (box-whisker, sunburst, treemap) must
1323
+ // point at a single `<cx:data>` entry that holds every strDim /
1324
+ // numDim they need; emitting multiple dataIds tells Excel the
1325
+ // series references multiple data entries which is the "Removed
1326
+ // Part: drawingN.xml" trigger.
1327
+ if (dataIdChildren.length > 1) {
1328
+ ctx.reporter.error("chartEx-series-too-many-dataId", `${path}: cx:series has ${dataIdChildren.length} <cx:dataId> children; schema permits at most 1. ` +
1329
+ `Consolidate the referenced <cx:data> entries into a single entry.`, path);
1330
+ }
1331
+ for (const dataId of dataIdChildren) {
1332
+ const id = parseInt((0, xml_utils_1.attrByLocalName)(dataId, "val") ?? "", 10);
1333
+ if (!dataIds.has(id)) {
1334
+ ctx.reporter.error("chartEx-series-missing-data-id", `${path}: cx:series references missing cx:data id ${(0, xml_utils_1.attrByLocalName)(dataId, "val")}`, path);
1335
+ }
1336
+ }
1337
+ for (const axisId of (0, xml_utils_1.findChildrenLocal)(series, "axisId")) {
1338
+ const id = parseInt((0, xml_utils_1.attrByLocalName)(axisId, "val") ?? "", 10);
1339
+ if (!axisIds.has(id)) {
1340
+ ctx.reporter.error("chartEx-series-missing-axis-id", `${path}: cx:series references missing cx:axis id ${(0, xml_utils_1.attrByLocalName)(axisId, "val")}`, path);
1341
+ }
1342
+ }
1343
+ }
1344
+ // externalData (e.g. cx:externalData r:id="...") must resolve in the chart's rels.
1345
+ const externalDataRids = (0, xml_utils_1.collectDescendantsLocal)(root, "externalData")
1346
+ .map(el => (0, xml_utils_1.attrByLocalName)(el, "id"))
1347
+ .filter((id) => !!id);
1348
+ if (externalDataRids.length > 0) {
1349
+ const relsPath = chartRelsPath(path);
1350
+ const rels = ctx.readRels(relsPath);
1351
+ for (const rid of externalDataRids) {
1352
+ if (!rels.byId.has(rid)) {
1353
+ ctx.reporter.error("chartEx-externalData-missing-rel", `${path}: cx:externalData references missing relationship ${rid}`, path);
1354
+ }
1355
+ }
1356
+ }
1357
+ // Schema-conformance checks: text-form violations of typed elements,
1358
+ // invalid `<cx:auto/>` element, `<cx:paretoLine>` in layoutPr, and
1359
+ // direct `<cx:layout>` child of `<cx:title>`.
1360
+ checkTypedElementAttrForm(ctx, path, root);
1361
+ checkInvalidAutoElement(ctx, path, root);
1362
+ checkParetoLineInLayoutPr(ctx, path, root);
1363
+ checkTitleDirectLayoutChild(ctx, path, root);
1364
+ // Tier-2 semantic checks.
1365
+ checkAxisPosAndType(ctx, path, root);
1366
+ checkSeriesFDefinedName(ctx, path, root);
1367
+ checkWaterfallSubtotals(ctx, path, root);
1368
+ }
1369
+ /**
1370
+ * `<cx:axisId>`, `<cx:dataId>`, `<cx:binCount>`, `<cx:binSize>` and
1371
+ * their siblings use the `val="N"` attribute form. Earlier writer
1372
+ * revisions serialised them as text content (`<cx:axisId>2</cx:axisId>`),
1373
+ * which Excel's strict loader rejects. Flag every occurrence so the
1374
+ * output never regresses to the broken shape.
1375
+ */
1376
+ const TYPED_ATTR_ONLY_ELEMENTS = ["axisId", "dataId", "binCount", "binSize"];
1377
+ function checkTypedElementAttrForm(ctx, path, root) {
1378
+ for (const name of TYPED_ATTR_ONLY_ELEMENTS) {
1379
+ for (const el of (0, xml_utils_1.collectDescendantsLocal)(root, name)) {
1380
+ if (ctx.reporter.capped) {
1381
+ return;
1382
+ }
1383
+ const val = (0, xml_utils_1.attrByLocalName)(el, "val");
1384
+ const text = directTextContent(el).trim();
1385
+ // Missing `val` AND present non-empty text = the broken text-form.
1386
+ if (val === undefined && text.length > 0) {
1387
+ ctx.reporter.error("chartEx-typed-element-text-form", `${path}: <cx:${name}>${text}</cx:${name}> uses text-content form; schema requires val="${text}" attribute.`, path);
1388
+ }
1389
+ }
1390
+ }
1391
+ }
1392
+ /**
1393
+ * `<cx:auto/>` is NOT a valid element — auto binning is expressed by
1394
+ * the absence of both `binSize` and `binCount` inside `<cx:binning>`.
1395
+ * A literal `<cx:auto/>` tag anywhere in the chartEx makes Excel drop
1396
+ * the part on load.
1397
+ */
1398
+ function checkInvalidAutoElement(ctx, path, root) {
1399
+ for (const _el of (0, xml_utils_1.collectDescendantsLocal)(root, "auto")) {
1400
+ if (ctx.reporter.capped) {
1401
+ return;
1402
+ }
1403
+ ctx.reporter.error("chartEx-invalid-auto-element", `${path}: <cx:auto/> element is not in the chartEx schema. ` +
1404
+ `Auto binning is expressed by omitting both <cx:binSize> and <cx:binCount>.`, path);
1405
+ }
1406
+ }
1407
+ /**
1408
+ * `<cx:paretoLine>` is not a child of `<cx:layoutPr>` in the schema.
1409
+ * A real pareto chart expresses the line as a second `<cx:series>` with
1410
+ * `layoutId="paretoLine"`. The mis-placed child made earlier Excel
1411
+ * builds reject the chartEx.
1412
+ */
1413
+ function checkParetoLineInLayoutPr(ctx, path, root) {
1414
+ for (const lp of (0, xml_utils_1.collectDescendantsLocal)(root, "layoutPr")) {
1415
+ if (ctx.reporter.capped) {
1416
+ return;
1417
+ }
1418
+ const pl = (0, xml_utils_1.findChildLocal)(lp, "paretoLine");
1419
+ if (pl) {
1420
+ ctx.reporter.error("chartEx-paretoLine-in-layoutPr", `${path}: <cx:paretoLine> is not a valid child of <cx:layoutPr>. ` +
1421
+ `Add a second <cx:series layoutId="paretoLine"/> instead.`, path);
1422
+ }
1423
+ }
1424
+ }
1425
+ /**
1426
+ * `<cx:title><cx:layout/></cx:title>` is schema-invalid. Title layout
1427
+ * lives in `extLst`-based extensions or (in some clients) `<cx:offset>`
1428
+ * — never as a direct `<cx:layout>` child.
1429
+ */
1430
+ function checkTitleDirectLayoutChild(ctx, path, root) {
1431
+ for (const title of (0, xml_utils_1.collectDescendantsLocal)(root, "title")) {
1432
+ if (ctx.reporter.capped) {
1433
+ return;
1434
+ }
1435
+ const layout = (0, xml_utils_1.findChildLocal)(title, "layout");
1436
+ if (layout) {
1437
+ ctx.reporter.error("chartEx-title-direct-layout", `${path}: <cx:title> has a direct <cx:layout> child. Title layout ` +
1438
+ `information belongs in extLst-based extensions.`, path);
1439
+ }
1440
+ }
1441
+ }
1442
+ /**
1443
+ * Concatenate direct text/cdata children of an element, ignoring any
1444
+ * nested elements. Useful for "typed element with stray text content"
1445
+ * detection where a nested element's text should NOT count as the
1446
+ * offending text form.
1447
+ */
1448
+ function directTextContent(el) {
1449
+ let out = "";
1450
+ for (const child of el.children) {
1451
+ if (child.type === "text" || child.type === "cdata") {
1452
+ out += child.value;
1453
+ }
1454
+ }
1455
+ return out;
1456
+ }
1457
+ // -----------------------------------------------------------------------------
1458
+ // Tier-2 semantic checks
1459
+ // -----------------------------------------------------------------------------
1460
+ /**
1461
+ * `<cx:axis>` must declare its axis role — either via a structural
1462
+ * `<cx:catScaling>` / `<cx:valScaling>` CHILD element (the form Excel
1463
+ * itself emits; the role is inferred from which scaling child is
1464
+ * present) OR via legacy `pos` / `type` attributes. When NONE of
1465
+ * these are present, Excel's loader cannot disambiguate the axis
1466
+ * role and drops the whole `<cx:chartSpace>` on open, cascading
1467
+ * into "Removed Part: /xl/charts/chartExN.xml".
1468
+ *
1469
+ * Verified against Excel 2021's own output (`tmp/aaaaa.xlsx`,
1470
+ * `tmp/ttttt.xlsx`): every `<cx:axis>` it emits omits the
1471
+ * `pos` / `type` attributes and relies on the scaling child.
1472
+ */
1473
+ function checkAxisPosAndType(ctx, path, root) {
1474
+ for (const axis of (0, xml_utils_1.collectDescendantsLocal)(root, "axis")) {
1475
+ if (ctx.reporter.capped) {
1476
+ return;
1477
+ }
1478
+ const pos = (0, xml_utils_1.attrByLocalName)(axis, "pos");
1479
+ const type = (0, xml_utils_1.attrByLocalName)(axis, "type");
1480
+ const id = (0, xml_utils_1.attrByLocalName)(axis, "id") ?? "?";
1481
+ // Accept either legacy attribute form OR the schema-native
1482
+ // `<cx:catScaling>` / `<cx:valScaling>` child.
1483
+ const hasCatScaling = axis.children.some(c => c.type === "element" && (0, xml_utils_1.matchesLocal)(c.name, "catScaling"));
1484
+ const hasValScaling = axis.children.some(c => c.type === "element" && (0, xml_utils_1.matchesLocal)(c.name, "valScaling"));
1485
+ if (pos === undefined && type === undefined && !hasCatScaling && !hasValScaling) {
1486
+ ctx.reporter.error("chartEx-axis-missing-pos-and-type", `${path}: <cx:axis id="${id}"> has no role marker — emit either a ` +
1487
+ `<cx:catScaling>/<cx:valScaling> child (preferred, matches Excel) ` +
1488
+ `or a pos/type attribute. Excel's loader drops the chartEx otherwise.`, path);
1489
+ }
1490
+ }
1491
+ }
1492
+ /**
1493
+ * `<cx:f>` formulas must point at hidden defined names (the
1494
+ * `_xlchart.v1.0`, `_xlchart.v1.1`, … convention Excel itself uses),
1495
+ * NOT directly at worksheet ranges. A bare `<cx:f>Sheet1!$A$1:$A$3</cx:f>`
1496
+ * is rejected on open with "Removed Part: /xl/drawings/drawingN.xml".
1497
+ *
1498
+ * Detection heuristic: a formula body that contains `!$` or `!` followed
1499
+ * by absolute cell references is a direct sheet reference. Defined-name
1500
+ * references are bare identifiers like `_xlchart.v1.0` (no `!`).
1501
+ */
1502
+ function checkSeriesFDefinedName(ctx, path, root) {
1503
+ for (const f of (0, xml_utils_1.collectDescendantsLocal)(root, "f")) {
1504
+ if (ctx.reporter.capped) {
1505
+ return;
1506
+ }
1507
+ const formula = directTextContent(f).trim();
1508
+ if (formula === "") {
1509
+ continue;
1510
+ }
1511
+ // Heuristic for a direct sheet-qualified range:
1512
+ // - Contains "!" (sheet qualifier), AND
1513
+ // - Does NOT start with `_xl` or other defined-name prefix.
1514
+ if (!formula.includes("!")) {
1515
+ continue; // bare defined name like `_xlchart.v1.0`
1516
+ }
1517
+ if (formula.startsWith("_xlchart.") || formula.startsWith("_xlfn.")) {
1518
+ continue; // defined-name-qualified alias
1519
+ }
1520
+ // Looks like `Sheet1!$A$1:$A$3` or `'Some Name'!$A$1`.
1521
+ ctx.reporter.error("chartEx-f-uses-direct-range-not-defined-name", `${path}: <cx:f>${formula}</cx:f> points at a worksheet range directly. ` +
1522
+ `ChartEx requires an indirection through hidden defined names ` +
1523
+ `(e.g. _xlchart.v1.0) — otherwise Excel 2016+ drops the chartEx part on load.`, path);
1524
+ }
1525
+ }
1526
+ /**
1527
+ * Waterfall charts must have `layoutPr.subtotals` on their series —
1528
+ * even empty `<cx:subtotals/>` is meaningful: it marks the plot as
1529
+ * subtotals-aware. Without it Excel falls back to generic series
1530
+ * rendering and has been observed to reject the chartEx as malformed
1531
+ * at load time.
1532
+ */
1533
+ function checkWaterfallSubtotals(ctx, path, root) {
1534
+ for (const series of (0, xml_utils_1.collectDescendantsLocal)(root, "series")) {
1535
+ if (ctx.reporter.capped) {
1536
+ return;
1537
+ }
1538
+ const layoutId = (0, xml_utils_1.attrByLocalName)(series, "layoutId");
1539
+ if (layoutId !== "waterfall") {
1540
+ continue;
1541
+ }
1542
+ const layoutPr = (0, xml_utils_1.findChildLocal)(series, "layoutPr");
1543
+ const hasSubtotals = !!layoutPr && (0, xml_utils_1.findChildLocal)(layoutPr, "subtotals") !== undefined;
1544
+ if (!hasSubtotals) {
1545
+ ctx.reporter.error("chartEx-waterfall-missing-subtotals", `${path}: waterfall series has no <cx:layoutPr><cx:subtotals/> marker. ` +
1546
+ `Emit the element (even empty) so Excel renders the series as ` +
1547
+ `waterfall-aware instead of rejecting the chartEx.`, path);
1548
+ }
1549
+ }
1550
+ }
1551
+ // -----------------------------------------------------------------------------
1552
+ // Series child order — context-aware, since `c:ser` has a different
1553
+ // content model under each chart-type element (CT_BarSer, CT_LineSer,
1554
+ // CT_PieSer, CT_AreaSer, CT_ScatterSer, CT_BubbleSer, CT_RadarSer,
1555
+ // CT_SurfaceSer). See {@link SERIES_ORDER_RULES} for the table.
1556
+ // -----------------------------------------------------------------------------
1557
+ function checkSeriesChildOrder(ctx, path, root) {
1558
+ for (const rule of SERIES_ORDER_RULES) {
1559
+ for (const chartType of rule.chartTypes) {
1560
+ for (const group of (0, xml_utils_1.collectDescendantsLocal)(root, chartType)) {
1561
+ for (const series of (0, xml_utils_1.findChildrenLocal)(group, "ser")) {
1562
+ if (ctx.reporter.capped) {
1563
+ return;
1564
+ }
1565
+ const children = series.children.filter(c => c.type === "element");
1566
+ let lastRank = -1;
1567
+ let lastTag = "";
1568
+ for (const child of children) {
1569
+ const name = (0, xml_utils_1.localName)(child.name);
1570
+ const rank = rule.order.indexOf(name);
1571
+ if (rank < 0) {
1572
+ continue;
1573
+ }
1574
+ if (rank < lastRank) {
1575
+ ctx.reporter.error("chart-child-out-of-order", `${path}: <c:ser> inside <c:${chartType}> has <c:${name}> after <c:${lastTag}>; CT_${seriesTypeNameFor(chartType)}Ser requires <c:${name}> earlier in the sequence.`, path);
1576
+ }
1577
+ if (rank >= lastRank) {
1578
+ lastRank = rank;
1579
+ lastTag = name;
1580
+ }
1581
+ }
1582
+ }
1583
+ }
1584
+ }
1585
+ }
1586
+ }
1587
+ /** Map a chart-type tag to the series content-type short name. */
1588
+ function seriesTypeNameFor(chartType) {
1589
+ if (chartType.startsWith("bar")) {
1590
+ return "Bar";
1591
+ }
1592
+ if (chartType.startsWith("line") || chartType === "stockChart") {
1593
+ return "Line";
1594
+ }
1595
+ if (chartType.startsWith("pie") || chartType === "doughnutChart" || chartType === "ofPieChart") {
1596
+ return "Pie";
1597
+ }
1598
+ if (chartType.startsWith("area")) {
1599
+ return "Area";
1600
+ }
1601
+ if (chartType === "scatterChart") {
1602
+ return "Scatter";
1603
+ }
1604
+ if (chartType === "bubbleChart") {
1605
+ return "Bubble";
1606
+ }
1607
+ if (chartType === "radarChart") {
1608
+ return "Radar";
1609
+ }
1610
+ if (chartType.startsWith("surface")) {
1611
+ return "Surface";
1612
+ }
1613
+ return chartType;
1614
+ }
1615
+ // -----------------------------------------------------------------------------
1616
+ // axId cross-reference resolution — every `c:axId` inside a chart-type
1617
+ // element must match one of the axis `c:axId` values in the enclosing
1618
+ // plot area; every axis `c:crossAx` must reference another axis in
1619
+ // the same plot area. Unresolved references are schema-valid (they
1620
+ // parse) but produce charts Excel renders with phantom / missing
1621
+ // axes — a common symptom when combo charts are hand-edited.
1622
+ // -----------------------------------------------------------------------------
1623
+ const ALL_CHART_TYPE_NAMES = new Set(CT_CHART_TYPE_TAGS);
1624
+ const ALL_AXIS_NAMES = new Set(CT_AXIS_TAGS);
1625
+ function checkAxIdResolution(ctx, path, root) {
1626
+ for (const plotArea of (0, xml_utils_1.collectDescendantsLocal)(root, "plotArea")) {
1627
+ if (ctx.reporter.capped) {
1628
+ return;
1629
+ }
1630
+ // Gather every axis axId declared in this plot area.
1631
+ const axisIds = new Set();
1632
+ for (const child of plotArea.children) {
1633
+ if (child.type !== "element") {
1634
+ continue;
1635
+ }
1636
+ const name = (0, xml_utils_1.localName)(child.name);
1637
+ if (!ALL_AXIS_NAMES.has(name)) {
1638
+ continue;
1639
+ }
1640
+ const axIdEl = (0, xml_utils_1.findChildLocal)(child, "axId");
1641
+ const val = axIdEl ? (0, xml_utils_1.attrByLocalName)(axIdEl, "val") : undefined;
1642
+ if (val !== undefined) {
1643
+ axisIds.add(val);
1644
+ }
1645
+ }
1646
+ // Chart-type groups must reference an axis that exists.
1647
+ for (const child of plotArea.children) {
1648
+ if (child.type !== "element") {
1649
+ continue;
1650
+ }
1651
+ const name = (0, xml_utils_1.localName)(child.name);
1652
+ if (!ALL_CHART_TYPE_NAMES.has(name)) {
1653
+ continue;
1654
+ }
1655
+ for (const axIdEl of (0, xml_utils_1.findChildrenLocal)(child, "axId")) {
1656
+ const val = (0, xml_utils_1.attrByLocalName)(axIdEl, "val");
1657
+ if (val === undefined) {
1658
+ continue;
1659
+ }
1660
+ if (!axisIds.has(val)) {
1661
+ ctx.reporter.error("chart-axid-unresolved", `${path}: <c:${name}> references <c:axId val="${val}"> but no matching axis exists in the enclosing <c:plotArea>.`, path);
1662
+ }
1663
+ }
1664
+ }
1665
+ // Each axis's `crossAx` must resolve to another axis in the
1666
+ // same plot area.
1667
+ for (const child of plotArea.children) {
1668
+ if (child.type !== "element") {
1669
+ continue;
1670
+ }
1671
+ const name = (0, xml_utils_1.localName)(child.name);
1672
+ if (!ALL_AXIS_NAMES.has(name)) {
1673
+ continue;
1674
+ }
1675
+ const crossAxEl = (0, xml_utils_1.findChildLocal)(child, "crossAx");
1676
+ const val = crossAxEl ? (0, xml_utils_1.attrByLocalName)(crossAxEl, "val") : undefined;
1677
+ if (val !== undefined && !axisIds.has(val)) {
1678
+ ctx.reporter.error("chart-axid-unresolved", `${path}: <c:${name}> has <c:crossAx val="${val}"> but no matching axis exists in the enclosing <c:plotArea>.`, path);
1679
+ }
1680
+ }
1681
+ }
1682
+ }
1683
+ // -----------------------------------------------------------------------------
1684
+ // ErrBars conditional children — `c:val` is required when
1685
+ // `c:errValType` is NOT "cust", and forbidden when it IS. `c:plus`
1686
+ // and `c:minus` are required for custom error bars and forbidden
1687
+ // otherwise. stdErr allows `c:val` to be absent (Excel defaults to
1688
+ // 1) so we skip the required-child check for that type.
1689
+ // -----------------------------------------------------------------------------
1690
+ function checkErrBarsConditionalChildren(ctx, path, root) {
1691
+ for (const eb of (0, xml_utils_1.collectDescendantsLocal)(root, "errBars")) {
1692
+ if (ctx.reporter.capped) {
1693
+ return;
1694
+ }
1695
+ const typeEl = (0, xml_utils_1.findChildLocal)(eb, "errValType");
1696
+ const type = typeEl ? (0, xml_utils_1.attrByLocalName)(typeEl, "val") : undefined;
1697
+ const hasVal = (0, xml_utils_1.findChildLocal)(eb, "val") !== undefined;
1698
+ const hasPlus = (0, xml_utils_1.findChildLocal)(eb, "plus") !== undefined;
1699
+ const hasMinus = (0, xml_utils_1.findChildLocal)(eb, "minus") !== undefined;
1700
+ if (type === "cust") {
1701
+ if (!hasPlus || !hasMinus) {
1702
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:errBars> with <c:errValType val="cust"> requires both <c:plus> and <c:minus> children.`, path);
1703
+ }
1704
+ if (hasVal) {
1705
+ ctx.reporter.error("chart-forbidden-child", `${path}: <c:errBars> with <c:errValType val="cust"> must not contain <c:val>; use <c:plus> / <c:minus> for custom bounds.`, path);
1706
+ }
1707
+ }
1708
+ else if (type === "fixedVal" || type === "percentage" || type === "stdDev") {
1709
+ if (!hasVal) {
1710
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:errBars> with <c:errValType val="${type}"> requires a <c:val> child.`, path);
1711
+ }
1712
+ if (hasPlus || hasMinus) {
1713
+ ctx.reporter.error("chart-forbidden-child", `${path}: <c:errBars> with <c:errValType val="${type}"> must not contain <c:plus> or <c:minus> — those belong to "cust" only.`, path);
1714
+ }
1715
+ }
1716
+ // `stdErr` leaves `val` optional and disallows plus/minus — enforce
1717
+ // the disallowed side only.
1718
+ if (type === "stdErr" && (hasPlus || hasMinus)) {
1719
+ ctx.reporter.error("chart-forbidden-child", `${path}: <c:errBars> with <c:errValType val="stdErr"> must not contain <c:plus> or <c:minus>.`, path);
1720
+ }
1721
+ }
1722
+ }
1723
+ // -----------------------------------------------------------------------------
1724
+ // CT_Tx / CT_SerTx choice exclusivity — `c:tx` is
1725
+ // `choice(strRef | rich)` at chart / axis / legend-entry level and
1726
+ // `choice(strRef | v)` at series level. Having more than one branch
1727
+ // is a schema violation; Excel silently keeps the first and drops
1728
+ // the rest, so the feature authors intended gets lost on save.
1729
+ // -----------------------------------------------------------------------------
1730
+ function checkTxChoice(ctx, path, root) {
1731
+ for (const tx of (0, xml_utils_1.collectDescendantsLocal)(root, "tx")) {
1732
+ if (ctx.reporter.capped) {
1733
+ return;
1734
+ }
1735
+ const hasStrRef = (0, xml_utils_1.findChildLocal)(tx, "strRef") !== undefined;
1736
+ const hasRich = (0, xml_utils_1.findChildLocal)(tx, "rich") !== undefined;
1737
+ const hasV = (0, xml_utils_1.findChildLocal)(tx, "v") !== undefined;
1738
+ const branches = [hasStrRef, hasRich, hasV].filter(Boolean).length;
1739
+ // Zero branches is tolerated by Excel (auto-generated title / blank
1740
+ // series name) — we intentionally don't flag it to avoid noise on
1741
+ // round-tripped files. More than one branch is a real schema
1742
+ // violation.
1743
+ if (branches > 1) {
1744
+ ctx.reporter.error("chart-child-out-of-order", `${path}: <c:tx> must contain at most one of <c:strRef>, <c:rich>, or <c:v>; found ${branches} branches.`, path);
1745
+ }
1746
+ }
1747
+ }
1748
+ // -----------------------------------------------------------------------------
1749
+ // Series-child whitelist — every `c:ser` element may only contain
1750
+ // children declared in its per-chart-type CT_*Ser content model.
1751
+ // Elements from the global "known chart child" set that aren't
1752
+ // declared for this parent are schema violations even though the
1753
+ // tag name is otherwise valid OOXML. Catches e.g. `<c:bubbleSize>`
1754
+ // inside a `<c:barChart>` series, `<c:explosion>` inside a line
1755
+ // series, or `<c:smooth>` on a bar series.
1756
+ // -----------------------------------------------------------------------------
1757
+ /**
1758
+ * Union of every element name that appears in at least one
1759
+ * `SERIES_ORDER_RULES` entry. A series child inside this set that
1760
+ * isn't in the current chart type's allow-list is a schema
1761
+ * violation; a child outside this set is probably a vendor
1762
+ * extension we should leave alone.
1763
+ */
1764
+ const ALL_KNOWN_SERIES_CHILDREN = new Set(SERIES_ORDER_RULES.flatMap(r => r.order));
1765
+ function checkSeriesChildWhitelist(ctx, path, root) {
1766
+ for (const rule of SERIES_ORDER_RULES) {
1767
+ const allowed = new Set(rule.order);
1768
+ for (const chartType of rule.chartTypes) {
1769
+ for (const group of (0, xml_utils_1.collectDescendantsLocal)(root, chartType)) {
1770
+ for (const series of (0, xml_utils_1.findChildrenLocal)(group, "ser")) {
1771
+ if (ctx.reporter.capped) {
1772
+ return;
1773
+ }
1774
+ for (const child of series.children) {
1775
+ if (child.type !== "element") {
1776
+ continue;
1777
+ }
1778
+ const name = (0, xml_utils_1.localName)(child.name);
1779
+ if (!ALL_KNOWN_SERIES_CHILDREN.has(name)) {
1780
+ continue; // unknown tag — vendor extension, leave alone
1781
+ }
1782
+ if (!allowed.has(name)) {
1783
+ ctx.reporter.error("chart-forbidden-child", `${path}: <c:ser> inside <c:${chartType}> contains <c:${name}>, which is not in CT_${seriesTypeNameFor(chartType)}Ser's schema.`, path);
1784
+ }
1785
+ }
1786
+ }
1787
+ }
1788
+ }
1789
+ }
1790
+ }
1791
+ // -----------------------------------------------------------------------------
1792
+ // `<a:srgbClr val>` — CT_SRgbColor requires a 6-hex-digit value.
1793
+ // Excel reliably ignores malformed colours; callers pay the cost of
1794
+ // a silently-grey series. Matches uppercase and lowercase hex.
1795
+ // -----------------------------------------------------------------------------
1796
+ const SRGB_HEX_RE = /^[0-9A-Fa-f]{6}$/;
1797
+ function checkSrgbClrFormat(ctx, path, root) {
1798
+ for (const el of (0, xml_utils_1.collectDescendantsLocal)(root, "srgbClr")) {
1799
+ if (ctx.reporter.capped) {
1800
+ return;
1801
+ }
1802
+ const val = (0, xml_utils_1.attrByLocalName)(el, "val");
1803
+ if (val === undefined) {
1804
+ ctx.reporter.error("chart-missing-required-child", `${path}: <a:srgbClr> is missing the required val attribute.`, path);
1805
+ continue;
1806
+ }
1807
+ if (!SRGB_HEX_RE.test(val)) {
1808
+ ctx.reporter.error("chart-invalid-enum-value", `${path}: <a:srgbClr val="${val}"> must be a 6-digit hex colour (e.g. "4472C4").`, path);
1809
+ }
1810
+ }
1811
+ }
1812
+ // -----------------------------------------------------------------------------
1813
+ // `<c:numFmt formatCode>` is required by CT_NumFmt. The OOXML
1814
+ // serialiser always emits it, but round-tripped / hand-edited files
1815
+ // sometimes drop the attribute; Excel falls back to "General" and
1816
+ // loses the author's intended format.
1817
+ // -----------------------------------------------------------------------------
1818
+ function checkNumFmtFormatCode(ctx, path, root) {
1819
+ for (const el of (0, xml_utils_1.collectDescendantsLocal)(root, "numFmt")) {
1820
+ if (ctx.reporter.capped) {
1821
+ return;
1822
+ }
1823
+ const formatCode = (0, xml_utils_1.attrByLocalName)(el, "formatCode");
1824
+ if (formatCode === undefined) {
1825
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:numFmt> is missing the required formatCode attribute.`, path);
1826
+ }
1827
+ }
1828
+ }
1829
+ // -----------------------------------------------------------------------------
1830
+ // `<c:rich>` wraps a DrawingML `CT_TextBody`: required children are
1831
+ // `<a:bodyPr>` (first, exactly 1) and `<a:p>` (1+). The list style
1832
+ // `<a:lstStyle>` is optional and goes between them. Without
1833
+ // `<a:bodyPr>` or `<a:p>` Excel renders the title / label blank.
1834
+ // -----------------------------------------------------------------------------
1835
+ function checkRichStructure(ctx, path, root) {
1836
+ for (const rich of (0, xml_utils_1.collectDescendantsLocal)(root, "rich")) {
1837
+ if (ctx.reporter.capped) {
1838
+ return;
1839
+ }
1840
+ const hasBodyPr = (0, xml_utils_1.findChildLocal)(rich, "bodyPr") !== undefined;
1841
+ const paragraphs = (0, xml_utils_1.findChildrenLocal)(rich, "p").length;
1842
+ if (!hasBodyPr) {
1843
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:rich> is missing the required <a:bodyPr> child (CT_TextBody requires it first).`, path);
1844
+ }
1845
+ if (paragraphs === 0) {
1846
+ ctx.reporter.error("chart-missing-required-child", `${path}: <c:rich> has no <a:p> children; CT_TextBody requires at least one paragraph.`, path);
1847
+ }
1848
+ }
1849
+ }
1850
+ // -----------------------------------------------------------------------------
1851
+ // Cross-part references
1852
+ //
1853
+ // These checks leave the chart XML boundary and validate links
1854
+ // against sibling parts in the xlsx package:
1855
+ // - `<a:schemeClr val>` must reference a colour slot actually
1856
+ // declared in `xl/theme/theme1.xml`'s `<a:clrScheme>`.
1857
+ // - `<c:f>` formula bodies must parse as a valid cell reference,
1858
+ // range, or defined-name identifier.
1859
+ // - `<c:f>` defined-name references must resolve against
1860
+ // `xl/workbook.xml`'s `<definedNames>` or be a reserved
1861
+ // Excel-internal name (`_xlnm.*`, `_xlchart.*`, `_xlfn.*`).
1862
+ // -----------------------------------------------------------------------------
1863
+ /**
1864
+ * Theme's `<a:clrScheme>` declares twelve colour slots under the
1865
+ * short names `dk1, lt1, dk2, lt2, accent1..6, hlink, folHlink`. The
1866
+ * four workbook-facing aliases (`bg1, tx1, bg2, tx2`) resolve through
1867
+ * `<a:clrMap>` — the default Office map is `bg1=lt1, tx1=dk1,
1868
+ * bg2=lt2, tx2=dk2`. `phClr` is a run-time placeholder that's always
1869
+ * valid. Anything else is theme-missing.
1870
+ */
1871
+ const SCHEME_COLOR_ALIASES = {
1872
+ bg1: "lt1",
1873
+ tx1: "dk1",
1874
+ bg2: "lt2",
1875
+ tx2: "dk2"
1876
+ };
1877
+ function collectThemeColorSlots(ctx) {
1878
+ const dom = ctx.readDom("xl/theme/theme1.xml");
1879
+ if (!dom) {
1880
+ return undefined;
1881
+ }
1882
+ const clrScheme = findFirstDescendantLocal(dom.root, "clrScheme");
1883
+ if (!clrScheme) {
1884
+ return undefined;
1885
+ }
1886
+ const slots = new Set();
1887
+ for (const child of clrScheme.children) {
1888
+ if (child.type === "element") {
1889
+ slots.add((0, xml_utils_1.localName)(child.name));
1890
+ }
1891
+ }
1892
+ return slots;
1893
+ }
1894
+ function findFirstDescendantLocal(root, local) {
1895
+ const hits = (0, xml_utils_1.collectDescendantsLocal)(root, local);
1896
+ return hits.length > 0 ? hits[0] : undefined;
1897
+ }
1898
+ function checkThemeSchemeColorSlots(ctx, path, root) {
1899
+ const slots = collectThemeColorSlots(ctx);
1900
+ // Skip silently when the theme is absent or doesn't declare a
1901
+ // `<a:clrScheme>`: either situation is flagged by the content-
1902
+ // types / relationships checkers and we'd just produce duplicate
1903
+ // noise here. We also skip when the slot set is empty — that
1904
+ // would reject every `schemeClr` reference as "missing" which
1905
+ // isn't the author's mistake.
1906
+ if (!slots || slots.size === 0) {
1907
+ return;
1908
+ }
1909
+ for (const el of (0, xml_utils_1.collectDescendantsLocal)(root, "schemeClr")) {
1910
+ if (ctx.reporter.capped) {
1911
+ return;
1912
+ }
1913
+ const val = (0, xml_utils_1.attrByLocalName)(el, "val");
1914
+ if (!val) {
1915
+ continue;
1916
+ }
1917
+ if (val === "phClr") {
1918
+ continue; // placeholder colour — always valid at run time
1919
+ }
1920
+ const resolved = SCHEME_COLOR_ALIASES[val] ?? val;
1921
+ if (!slots.has(resolved)) {
1922
+ ctx.reporter.error("chart-theme-missing-schemeClr-slot", `${path}: <a:schemeClr val="${val}"> references theme slot <a:${resolved}> which is not declared in xl/theme/theme1.xml's <a:clrScheme>.`, path);
1923
+ }
1924
+ }
1925
+ }
1926
+ /**
1927
+ * `<c:f>` bodies used by classic charts come in several flavours:
1928
+ * - `Sheet1!$A$1[:$B$2]` — qualified cell / range
1929
+ * - `'Quoted Sheet'!$A$1` — quoted sheet with spaces / specials
1930
+ * - `DefinedName` — bare defined-name identifier
1931
+ * - `Sheet1!LocalName` — sheet-qualified defined name
1932
+ * - `TableName[ColumnName]` — Excel structured reference
1933
+ * - `TableName[[#Headers],[Col]]` — structured ref with specifier
1934
+ * - `(f1,f2)` — multi-range (scatter / combo)
1935
+ * - `SUM(A1:A10)` — function call (rare but valid)
1936
+ * - `_xl*.*` — reserved Excel-internal prefix
1937
+ * (`_xlnm.Print_Area`, `_xlchart.v1.0`, `_xlfn.IFS`…)
1938
+ *
1939
+ * Full formula parsing would require the `@formula` tokenizer;
1940
+ * instead we apply a structural sanity check (balanced brackets /
1941
+ * parens / quotes, non-empty body) plus quick classification for
1942
+ * the two common forms that route into the defined-name resolver
1943
+ * (`bare identifier` and `Sheet!identifier`). Everything else is
1944
+ * assumed to be a valid complex expression — false-negatives here
1945
+ * are preferable to flagging legitimate structured references like
1946
+ * `Transactions[Revenue]`.
1947
+ */
1948
+ /** Cell or range reference like `A1`, `$A$1`, or `A1:B10`. */
1949
+ const A1_REF_RE = /^\$?[A-Z]+\$?\d+(?::\$?[A-Z]+\$?\d+)?$/;
1950
+ /** Unicode-aware identifier regex matching Excel defined-name rules. */
1951
+ const IDENTIFIER_RE = /^[A-Za-z_\\\u00C0-\uFFFF][A-Za-z0-9_.\\\u00C0-\uFFFF]*$/;
1952
+ /**
1953
+ * Balanced-bracket / paren / quote check — returns `false` when
1954
+ * the formula is syntactically broken (unclosed bracket, orphan
1955
+ * quote, etc.). Excel silently swallows such formulas on open; the
1956
+ * chart loses its backing data.
1957
+ */
1958
+ function isFormulaBalanced(body) {
1959
+ let parens = 0;
1960
+ let brackets = 0;
1961
+ let inQuote = false;
1962
+ for (let i = 0; i < body.length; i++) {
1963
+ const c = body[i];
1964
+ if (c === "'") {
1965
+ inQuote = !inQuote;
1966
+ continue;
1967
+ }
1968
+ if (inQuote) {
1969
+ continue;
1970
+ }
1971
+ if (c === "(") {
1972
+ parens++;
1973
+ }
1974
+ else if (c === ")") {
1975
+ parens--;
1976
+ }
1977
+ else if (c === "[") {
1978
+ brackets++;
1979
+ }
1980
+ else if (c === "]") {
1981
+ brackets--;
1982
+ }
1983
+ if (parens < 0 || brackets < 0) {
1984
+ return false;
1985
+ }
1986
+ }
1987
+ return parens === 0 && brackets === 0 && !inQuote;
1988
+ }
1989
+ function parseCFBody(raw) {
1990
+ let body = raw.trim();
1991
+ if (body.startsWith("=")) {
1992
+ body = body.substring(1).trim();
1993
+ }
1994
+ if (body === "") {
1995
+ return { kind: "invalid" };
1996
+ }
1997
+ if (!isFormulaBalanced(body)) {
1998
+ return { kind: "invalid" };
1999
+ }
2000
+ // `_xl`-prefixed names are reserved: `_xlnm.*`, `_xlchart.*`,
2001
+ // `_xlfn.*`. Always treat as valid without cross-reference.
2002
+ if (body.startsWith("_xl")) {
2003
+ return { kind: "special" };
2004
+ }
2005
+ // Expressions wrapped in parens cover multi-range references
2006
+ // (`(Sheet1!$A$1:$A$5,Sheet1!$C$1:$C$5)` on scatter / combo charts)
2007
+ // and function-call formulas (`SUM(A1:A10)`). The balanced-bracket
2008
+ // check above already caught unclosed parens; the full inner
2009
+ // grammar is out of scope for this schema check, so trust the
2010
+ // author and skip.
2011
+ if (body.startsWith("(")) {
2012
+ return { kind: "special" };
2013
+ }
2014
+ // Bare defined-name identifier (no punctuation, no !).
2015
+ if (IDENTIFIER_RE.test(body)) {
2016
+ return { kind: "name", name: body };
2017
+ }
2018
+ // Sheet-qualified form `Sheet!xxx`. Only classify as a defined-
2019
+ // name reference when the RHS is a pure identifier — structured
2020
+ // refs like `Table[Col]` or cell ranges like `$A$1:$B$10` route
2021
+ // through the generic "special" bucket so the defined-name check
2022
+ // skips them.
2023
+ const bangIdx = body.indexOf("!");
2024
+ if (bangIdx >= 0) {
2025
+ const sheet = body.substring(0, bangIdx);
2026
+ const ref = body.substring(bangIdx + 1);
2027
+ const sheetValid = (sheet.startsWith("'") && sheet.endsWith("'") && sheet.length >= 3) ||
2028
+ IDENTIFIER_RE.test(sheet);
2029
+ if (!sheetValid || ref === "") {
2030
+ return { kind: "invalid" };
2031
+ }
2032
+ if (A1_REF_RE.test(ref)) {
2033
+ return { kind: ref.includes(":") ? "range" : "cell" };
2034
+ }
2035
+ // Reserved `_xl*` names also appear sheet-qualified
2036
+ // (`Sheet1!_xlchart.v1.0`). Treat them as special regardless of
2037
+ // which side of the `!` they sit on.
2038
+ if (ref.startsWith("_xl")) {
2039
+ return { kind: "special" };
2040
+ }
2041
+ if (IDENTIFIER_RE.test(ref)) {
2042
+ return { kind: "name", name: ref };
2043
+ }
2044
+ // Anything else (structured table ref, function call, complex
2045
+ // expression) — assume valid, skip further validation.
2046
+ return { kind: "special" };
2047
+ }
2048
+ // Unqualified and not a bare identifier: could be a structured
2049
+ // reference (`Table[Col]`, `Table[#All]`) or an expression. Both
2050
+ // legal in `<c:f>`; accept without further validation.
2051
+ return { kind: "special" };
2052
+ }
2053
+ function extractTextContent(el) {
2054
+ let out = "";
2055
+ for (const child of el.children) {
2056
+ if (child.type === "text" || child.type === "cdata") {
2057
+ out += child.value;
2058
+ }
2059
+ }
2060
+ return out;
2061
+ }
2062
+ function checkFormulaSyntax(ctx, path, root) {
2063
+ for (const f of (0, xml_utils_1.collectDescendantsLocal)(root, "f")) {
2064
+ if (ctx.reporter.capped) {
2065
+ return;
2066
+ }
2067
+ const body = extractTextContent(f);
2068
+ const parsed = parseCFBody(body);
2069
+ if (parsed.kind === "invalid") {
2070
+ ctx.reporter.error("chart-f-invalid-syntax", `${path}: <c:f>${body}</c:f> is not a valid cell reference, range, or defined name.`, path);
2071
+ }
2072
+ }
2073
+ }
2074
+ /**
2075
+ * Collect every defined-name declared in `xl/workbook.xml`, plus the
2076
+ * well-known built-in reserved names that don't appear in the file
2077
+ * but Excel always recognises (`_xlnm.*` family).
2078
+ */
2079
+ function collectWorkbookDefinedNames(ctx) {
2080
+ const names = new Set();
2081
+ // Built-in reserved names Excel treats as always-defined.
2082
+ names.add("_xlnm.Print_Area");
2083
+ names.add("_xlnm.Print_Titles");
2084
+ names.add("_xlnm.Database");
2085
+ names.add("_xlnm.Criteria");
2086
+ names.add("_xlnm.Extract");
2087
+ names.add("_xlnm.Sheet_Title");
2088
+ names.add("_xlnm._FilterDatabase");
2089
+ names.add("_xlnm.Auto_Open");
2090
+ names.add("_xlnm.Auto_Close");
2091
+ const dom = ctx.readDom("xl/workbook.xml");
2092
+ if (!dom) {
2093
+ return names;
2094
+ }
2095
+ for (const dn of (0, xml_utils_1.collectDescendantsLocal)(dom.root, "definedName")) {
2096
+ const name = (0, xml_utils_1.attrByLocalName)(dn, "name");
2097
+ if (name) {
2098
+ names.add(name);
2099
+ }
2100
+ }
2101
+ return names;
2102
+ }
2103
+ function checkDefinedNameResolution(ctx, path, root) {
2104
+ let names;
2105
+ for (const f of (0, xml_utils_1.collectDescendantsLocal)(root, "f")) {
2106
+ if (ctx.reporter.capped) {
2107
+ return;
2108
+ }
2109
+ const body = extractTextContent(f);
2110
+ const parsed = parseCFBody(body);
2111
+ if (parsed.kind !== "name" || !parsed.name) {
2112
+ continue;
2113
+ }
2114
+ // Lazily load the workbook's defined names on first need.
2115
+ if (!names) {
2116
+ names = collectWorkbookDefinedNames(ctx);
2117
+ }
2118
+ if (!names.has(parsed.name)) {
2119
+ ctx.reporter.error("chart-f-undefined-name", `${path}: <c:f>${body}</c:f> references defined name "${parsed.name}" but no matching <definedName> exists in xl/workbook.xml.`, path);
2120
+ }
2121
+ }
2122
+ }
2123
+ function chartRelsPath(chartPath) {
2124
+ const slash = chartPath.lastIndexOf("/");
2125
+ const dir = slash >= 0 ? chartPath.slice(0, slash) : "";
2126
+ const name = slash >= 0 ? chartPath.slice(slash + 1) : chartPath;
2127
+ return dir ? `${dir}/_rels/${name}.rels` : `_rels/${name}.rels`;
2128
+ }