ooxml-core 1.8.4 → 1.10.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 (347) hide show
  1. package/dist/PptxHandler-5UURGJEV.mjs +2 -0
  2. package/dist/{PptxHandler-BL4B7CZO.mjs → PptxHandler-ADEFY476.mjs} +2 -2
  3. package/dist/PptxHandler-U5XB2HUE.cjs +11 -0
  4. package/dist/automation/index.cjs +7239 -4037
  5. package/dist/automation/index.mjs +7239 -4037
  6. package/dist/chunk-3N6XMMTT.cjs +87913 -0
  7. package/dist/{chunk-TTPZITQN.mjs → chunk-5NVJN4E6.mjs} +30 -2
  8. package/dist/{chunk-ZAP5WLEN.mjs → chunk-A6P7G3UK.mjs} +1 -1
  9. package/dist/{chunk-CPKNMQLX.cjs → chunk-AWIDASUW.cjs} +25 -2
  10. package/dist/{chunk-SVQZXP3F.mjs → chunk-CBNKBVX5.mjs} +25 -2
  11. package/dist/{chunk-GAGSCAR3.mjs → chunk-CCHYFCPD.mjs} +1199 -348
  12. package/dist/chunk-R6KSBNKX.mjs +44133 -0
  13. package/dist/chunk-S6DOCMQC.cjs +44451 -0
  14. package/dist/{chunk-Z7IQR4S4.mjs → chunk-WUE5ZHU3.mjs} +269 -21
  15. package/dist/chunk-ZE53K7DH.mjs +87907 -0
  16. package/dist/{chunk-NIHPA63A.mjs → chunk-ZOUGMAZG.mjs} +54 -37
  17. package/dist/docx/block-parser.d.ts.map +1 -1
  18. package/dist/docx/cell-blocks.d.ts +4 -0
  19. package/dist/docx/cell-blocks.d.ts.map +1 -0
  20. package/dist/docx/document-paragraphs.d.ts.map +1 -1
  21. package/dist/docx/document-parts.d.ts +2 -0
  22. package/dist/docx/document-parts.d.ts.map +1 -1
  23. package/dist/docx/embedded.cjs +189 -20
  24. package/dist/docx/embedded.mjs +189 -20
  25. package/dist/docx/index.cjs +219 -24
  26. package/dist/docx/index.mjs +219 -24
  27. package/dist/docx/layout/adapt-table.d.ts +2 -2
  28. package/dist/docx/layout/adapt-table.d.ts.map +1 -1
  29. package/dist/docx/layout/adapter.d.ts.map +1 -1
  30. package/dist/docx/layout/flow-paragraph.d.ts +5 -0
  31. package/dist/docx/layout/flow-paragraph.d.ts.map +1 -1
  32. package/dist/docx/layout/flow-table.d.ts +2 -1
  33. package/dist/docx/layout/flow-table.d.ts.map +1 -1
  34. package/dist/docx/layout/footnote-columns.d.ts +22 -0
  35. package/dist/docx/layout/footnote-columns.d.ts.map +1 -0
  36. package/dist/docx/layout/footnote-flow.d.ts +27 -0
  37. package/dist/docx/layout/footnote-flow.d.ts.map +1 -0
  38. package/dist/docx/layout/footnote-split.d.ts +7 -0
  39. package/dist/docx/layout/footnote-split.d.ts.map +1 -0
  40. package/dist/docx/layout/index.cjs +1528 -119
  41. package/dist/docx/layout/index.mjs +1528 -120
  42. package/dist/docx/layout/input.d.ts +17 -1
  43. package/dist/docx/layout/input.d.ts.map +1 -1
  44. package/dist/docx/layout/legacy-footnote-flow.d.ts +18 -0
  45. package/dist/docx/layout/legacy-footnote-flow.d.ts.map +1 -0
  46. package/dist/docx/layout/line-metrics.d.ts.map +1 -1
  47. package/dist/docx/layout/nested-frame-profile.d.ts +9 -0
  48. package/dist/docx/layout/nested-frame-profile.d.ts.map +1 -0
  49. package/dist/docx/layout/page-cursor.d.ts +15 -8
  50. package/dist/docx/layout/page-cursor.d.ts.map +1 -1
  51. package/dist/docx/layout/page-flow.d.ts.map +1 -1
  52. package/dist/docx/layout/paragraph-layout.d.ts.map +1 -1
  53. package/dist/docx/layout/paragraph-tokens.d.ts +2 -0
  54. package/dist/docx/layout/paragraph-tokens.d.ts.map +1 -1
  55. package/dist/docx/layout/reference-footnotes.d.ts +7 -0
  56. package/dist/docx/layout/reference-footnotes.d.ts.map +1 -0
  57. package/dist/docx/layout/result.d.ts +44 -0
  58. package/dist/docx/layout/result.d.ts.map +1 -1
  59. package/dist/docx/layout/section-flow.d.ts +2 -0
  60. package/dist/docx/layout/section-flow.d.ts.map +1 -1
  61. package/dist/docx/layout/table-border-layout.d.ts +16 -0
  62. package/dist/docx/layout/table-border-layout.d.ts.map +1 -0
  63. package/dist/docx/layout/table-cell-layout.d.ts +12 -0
  64. package/dist/docx/layout/table-cell-layout.d.ts.map +1 -0
  65. package/dist/docx/layout/table-content.d.ts +4 -0
  66. package/dist/docx/layout/table-content.d.ts.map +1 -0
  67. package/dist/docx/layout/table-footnotes.d.ts +32 -0
  68. package/dist/docx/layout/table-footnotes.d.ts.map +1 -0
  69. package/dist/docx/layout/table-frames.d.ts +4 -0
  70. package/dist/docx/layout/table-frames.d.ts.map +1 -0
  71. package/dist/docx/layout/table-layout.d.ts +16 -5
  72. package/dist/docx/layout/table-layout.d.ts.map +1 -1
  73. package/dist/docx/layout/table-note-completion.d.ts +5 -0
  74. package/dist/docx/layout/table-note-completion.d.ts.map +1 -0
  75. package/dist/docx/layout/table-note-stories.d.ts +6 -0
  76. package/dist/docx/layout/table-note-stories.d.ts.map +1 -0
  77. package/dist/docx/load/index.cjs +194 -25
  78. package/dist/docx/load/index.mjs +194 -25
  79. package/dist/docx/model-run.d.ts +2 -0
  80. package/dist/docx/model-run.d.ts.map +1 -1
  81. package/dist/docx/model.d.ts +7 -0
  82. package/dist/docx/model.d.ts.map +1 -1
  83. package/dist/docx/notes.d.ts +5 -0
  84. package/dist/docx/notes.d.ts.map +1 -1
  85. package/dist/docx/parse-table.d.ts.map +1 -1
  86. package/dist/docx/parse.d.ts.map +1 -1
  87. package/dist/docx/save.d.ts.map +1 -1
  88. package/dist/docx/section-model.d.ts +2 -0
  89. package/dist/docx/section-model.d.ts.map +1 -1
  90. package/dist/docx/sections.d.ts.map +1 -1
  91. package/dist/docx/settings.d.ts +2 -0
  92. package/dist/docx/settings.d.ts.map +1 -1
  93. package/dist/docx/table-model.d.ts +3 -1
  94. package/dist/docx/table-model.d.ts.map +1 -1
  95. package/dist/docx/ui/index.cjs +55 -0
  96. package/dist/docx/ui/index.d.ts +1 -0
  97. package/dist/docx/ui/index.d.ts.map +1 -1
  98. package/dist/docx/ui/index.mjs +55 -1
  99. package/dist/docx/ui/table-structure-guard.d.ts +4 -0
  100. package/dist/docx/ui/table-structure-guard.d.ts.map +1 -0
  101. package/dist/docx/write-footnote-columns.d.ts +3 -0
  102. package/dist/docx/write-footnote-columns.d.ts.map +1 -0
  103. package/dist/docx/write-notes.d.ts.map +1 -1
  104. package/dist/docx/write-run.d.ts.map +1 -1
  105. package/dist/docx/write-sections.d.ts.map +1 -1
  106. package/dist/index.cjs +8 -5
  107. package/dist/index.mjs +8 -5
  108. package/dist/opc/clone-part-graph.d.ts +4 -0
  109. package/dist/opc/clone-part-graph.d.ts.map +1 -1
  110. package/dist/opc/index.cjs +8 -5
  111. package/dist/opc/index.mjs +8 -5
  112. package/dist/pptx/automation/index.cjs +1156 -389
  113. package/dist/pptx/automation/index.d.ts +4 -4
  114. package/dist/pptx/automation/index.mjs +5 -5
  115. package/dist/pptx/chunks/{index-CKIUurnd.d.ts → index-Cuxtr76Y.d.ts} +29 -10
  116. package/dist/pptx/chunks/index-Cuxtr76Y.d.ts.map +1 -0
  117. package/dist/pptx/chunks/{index-Cn-GzYGp.d.ts → index-DUCGeZh7.d.ts} +94 -5
  118. package/dist/pptx/chunks/index-DUCGeZh7.d.ts.map +1 -0
  119. package/dist/pptx/chunks/{smart-art-Q2kZQtHh.d.ts → smart-art-D-sXa_Nb.d.ts} +11 -1
  120. package/dist/pptx/chunks/smart-art-D-sXa_Nb.d.ts.map +1 -0
  121. package/dist/pptx/chunks/{text-operations-BHfAm5K9.d.ts → text-operations-BqHmLaLA.d.ts} +54 -13
  122. package/dist/pptx/chunks/text-operations-BqHmLaLA.d.ts.map +1 -0
  123. package/dist/pptx/cli/index.cjs +1157 -395
  124. package/dist/pptx/cli/index.d.ts +1 -1
  125. package/dist/pptx/cli/index.mjs +4 -4
  126. package/dist/pptx/converter/index.cjs +54 -36
  127. package/dist/pptx/converter/index.d.ts +1 -1
  128. package/dist/pptx/converter/index.mjs +2 -2
  129. package/dist/pptx/editor/render/collaboration-live-patch-target.cjs +2 -2
  130. package/dist/pptx/editor/render/collaboration-live-patch-target.mjs +1 -1
  131. package/dist/pptx/editor/render/find-replace.cjs +416 -45
  132. package/dist/pptx/editor/render/find-replace.d.ts +35 -4
  133. package/dist/pptx/editor/render/find-replace.d.ts.map +1 -1
  134. package/dist/pptx/editor/render/find-replace.mjs +416 -46
  135. package/dist/pptx/editor/render/remap-text.cjs +2 -2
  136. package/dist/pptx/editor/render/remap-text.d.ts.map +1 -1
  137. package/dist/pptx/editor/render/remap-text.mjs +1 -1
  138. package/dist/pptx/editor/render/slide-operations.cjs +87 -0
  139. package/dist/pptx/editor/render/slide-operations.d.ts +17 -1
  140. package/dist/pptx/editor/render/slide-operations.d.ts.map +1 -1
  141. package/dist/pptx/editor/render/slide-operations.mjs +83 -1
  142. package/dist/pptx/editor/render/slide-search.cjs +6 -10
  143. package/dist/pptx/editor/render/slide-search.d.ts +1 -1
  144. package/dist/pptx/editor/render/slide-search.mjs +6 -10
  145. package/dist/pptx/editor/render/template-editing.d.ts +1 -1
  146. package/dist/pptx/editor/render/template-editing.d.ts.map +1 -1
  147. package/dist/pptx/index.cjs +1651 -419
  148. package/dist/pptx/index.d.ts +5 -5
  149. package/dist/pptx/index.mjs +5 -5
  150. package/dist/pptx/smartart-layouts/index.d.ts +1 -1
  151. package/dist/teams/index.cjs +965 -34
  152. package/dist/teams/index.mjs +965 -34
  153. package/dist/visio/accessibility.d.ts +10 -0
  154. package/dist/visio/accessibility.d.ts.map +1 -0
  155. package/dist/visio/cell-formula.d.ts +2 -0
  156. package/dist/visio/cell-formula.d.ts.map +1 -1
  157. package/dist/visio/connector-curve-aligned.d.ts +5 -0
  158. package/dist/visio/connector-curve-aligned.d.ts.map +1 -0
  159. package/dist/visio/connector-curve-spans.d.ts +14 -0
  160. package/dist/visio/connector-curve-spans.d.ts.map +1 -0
  161. package/dist/visio/connector-jumps.d.ts +5 -0
  162. package/dist/visio/connector-jumps.d.ts.map +1 -0
  163. package/dist/visio/connector-route-walk.d.ts +2 -1
  164. package/dist/visio/connector-route-walk.d.ts.map +1 -1
  165. package/dist/visio/date-cache.d.ts +3 -0
  166. package/dist/visio/date-cache.d.ts.map +1 -0
  167. package/dist/visio/edit-alt-text-scope.d.ts +5 -0
  168. package/dist/visio/edit-alt-text-scope.d.ts.map +1 -0
  169. package/dist/visio/edit-alt-text.d.ts +3 -0
  170. package/dist/visio/edit-alt-text.d.ts.map +1 -0
  171. package/dist/visio/edit-commands.d.ts +7 -2
  172. package/dist/visio/edit-commands.d.ts.map +1 -1
  173. package/dist/visio/edit-formatting-commands.d.ts +5 -0
  174. package/dist/visio/edit-formatting-commands.d.ts.map +1 -1
  175. package/dist/visio/edit-formatting-paint.d.ts.map +1 -1
  176. package/dist/visio/edit-formatting-scope.d.ts.map +1 -1
  177. package/dist/visio/edit-line-jump-cache.d.ts +4 -0
  178. package/dist/visio/edit-line-jump-cache.d.ts.map +1 -0
  179. package/dist/visio/edit-master-index.d.ts.map +1 -1
  180. package/dist/visio/edit-metadata-commands.d.ts +10 -2
  181. package/dist/visio/edit-metadata-commands.d.ts.map +1 -1
  182. package/dist/visio/edit-metadata.d.ts +3 -1
  183. package/dist/visio/edit-metadata.d.ts.map +1 -1
  184. package/dist/visio/edit-page-alt-text.d.ts +4 -0
  185. package/dist/visio/edit-page-alt-text.d.ts.map +1 -0
  186. package/dist/visio/edit-page-layout.d.ts.map +1 -1
  187. package/dist/visio/edit-page-rename.d.ts.map +1 -1
  188. package/dist/visio/edit-page-setup-commands.d.ts +7 -1
  189. package/dist/visio/edit-page-setup-commands.d.ts.map +1 -1
  190. package/dist/visio/edit-page-size.d.ts.map +1 -1
  191. package/dist/visio/edit-pages.d.ts.map +1 -1
  192. package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
  193. package/dist/visio/edit-scope.d.ts.map +1 -1
  194. package/dist/visio/edit-shape-create.d.ts.map +1 -1
  195. package/dist/visio/edit-stencil-connector-write.d.ts.map +1 -1
  196. package/dist/visio/edit-style-admission.d.ts.map +1 -1
  197. package/dist/visio/edit-text-field.d.ts.map +1 -1
  198. package/dist/visio/edit-text.d.ts.map +1 -1
  199. package/dist/visio/edit.d.ts +1 -1
  200. package/dist/visio/edit.d.ts.map +1 -1
  201. package/dist/visio/index.cjs +1215 -248
  202. package/dist/visio/index.d.ts +2 -1
  203. package/dist/visio/index.d.ts.map +1 -1
  204. package/dist/visio/index.mjs +1215 -249
  205. package/dist/visio/line-jumps.d.ts +1 -5
  206. package/dist/visio/line-jumps.d.ts.map +1 -1
  207. package/dist/visio/model.d.ts +13 -0
  208. package/dist/visio/model.d.ts.map +1 -1
  209. package/dist/visio/page-layout.d.ts +11 -2
  210. package/dist/visio/page-layout.d.ts.map +1 -1
  211. package/dist/visio/parser.d.ts.map +1 -1
  212. package/dist/visio/shape-metadata.d.ts +6 -0
  213. package/dist/visio/shape-metadata.d.ts.map +1 -1
  214. package/dist/visio/shapes.d.ts.map +1 -1
  215. package/dist/visio/text-field-case.d.ts +2 -0
  216. package/dist/visio/text-field-case.d.ts.map +1 -0
  217. package/dist/visio/text-field-display.d.ts.map +1 -1
  218. package/dist/visio/text-field-fraction.d.ts +3 -0
  219. package/dist/visio/text-field-fraction.d.ts.map +1 -0
  220. package/dist/visio/text-field-numeric.d.ts +4 -0
  221. package/dist/visio/text-field-numeric.d.ts.map +1 -0
  222. package/dist/visio/text-field-system-date.d.ts +4 -0
  223. package/dist/visio/text-field-system-date.d.ts.map +1 -0
  224. package/dist/visio/text-fields.d.ts +1 -0
  225. package/dist/visio/text-fields.d.ts.map +1 -1
  226. package/dist/visio/ui/connector-preview.d.ts +1 -1
  227. package/dist/visio/ui/connector-preview.d.ts.map +1 -1
  228. package/dist/visio/ui/data-graphic-rules.d.ts +2 -0
  229. package/dist/visio/ui/data-graphic-rules.d.ts.map +1 -1
  230. package/dist/visio/ui/data-graphics.d.ts +3 -2
  231. package/dist/visio/ui/data-graphics.d.ts.map +1 -1
  232. package/dist/visio/ui/edit-commands.d.ts.map +1 -1
  233. package/dist/visio/ui/index.cjs +19310 -18157
  234. package/dist/visio/ui/index.mjs +19310 -18158
  235. package/dist/visio/ui/scene-details.d.ts.map +1 -1
  236. package/dist/visio/ui/scene-validation.d.ts.map +1 -1
  237. package/dist/visio/ui/snapshot-scene.d.ts +2 -1
  238. package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
  239. package/dist/visio/ui/text-field-catalog.d.ts.map +1 -1
  240. package/dist/visio/xml-attribute-whitespace.d.ts +5 -0
  241. package/dist/visio/xml-attribute-whitespace.d.ts.map +1 -0
  242. package/dist/xlsx/edit/index.d.ts +1 -0
  243. package/dist/xlsx/edit/index.d.ts.map +1 -1
  244. package/dist/xlsx/edit/insert-guard.d.ts.map +1 -1
  245. package/dist/xlsx/edit/merge.d.ts.map +1 -1
  246. package/dist/xlsx/edit/page-breaks.d.ts +5 -0
  247. package/dist/xlsx/edit/page-breaks.d.ts.map +1 -0
  248. package/dist/xlsx/edit/pivots.d.ts +8 -0
  249. package/dist/xlsx/edit/pivots.d.ts.map +1 -0
  250. package/dist/xlsx/edit/print-titles.d.ts +7 -0
  251. package/dist/xlsx/edit/print-titles.d.ts.map +1 -0
  252. package/dist/xlsx/edit/session.d.ts.map +1 -1
  253. package/dist/xlsx/edit/sheets.d.ts.map +1 -1
  254. package/dist/xlsx/edit/shift-formulas.d.ts.map +1 -1
  255. package/dist/xlsx/edit/shift-sheet.d.ts.map +1 -1
  256. package/dist/xlsx/edit/sparkline-ranges.d.ts +11 -0
  257. package/dist/xlsx/edit/sparkline-ranges.d.ts.map +1 -0
  258. package/dist/xlsx/edit/sparkline-xml.d.ts +13 -0
  259. package/dist/xlsx/edit/sparkline-xml.d.ts.map +1 -0
  260. package/dist/xlsx/edit/sparklines.d.ts +16 -0
  261. package/dist/xlsx/edit/sparklines.d.ts.map +1 -0
  262. package/dist/xlsx/edit/table-edits.d.ts.map +1 -1
  263. package/dist/xlsx/edit/tables.d.ts.map +1 -1
  264. package/dist/xlsx/edit/types.d.ts +22 -1
  265. package/dist/xlsx/edit/types.d.ts.map +1 -1
  266. package/dist/xlsx/formula/functions/text-regex.d.ts.map +1 -1
  267. package/dist/xlsx/index.cjs +3638 -1199
  268. package/dist/xlsx/index.d.ts +1 -0
  269. package/dist/xlsx/index.d.ts.map +1 -1
  270. package/dist/xlsx/index.mjs +3619 -1200
  271. package/dist/xlsx/layout/cell-view.d.ts +2 -0
  272. package/dist/xlsx/layout/cell-view.d.ts.map +1 -1
  273. package/dist/xlsx/layout/header-footer.d.ts +58 -0
  274. package/dist/xlsx/layout/header-footer.d.ts.map +1 -0
  275. package/dist/xlsx/layout/index.d.ts +5 -0
  276. package/dist/xlsx/layout/index.d.ts.map +1 -1
  277. package/dist/xlsx/layout/print-breaks.d.ts +11 -0
  278. package/dist/xlsx/layout/print-breaks.d.ts.map +1 -0
  279. package/dist/xlsx/layout/print-layout.d.ts +34 -0
  280. package/dist/xlsx/layout/print-layout.d.ts.map +1 -0
  281. package/dist/xlsx/layout/print-merges.d.ts +18 -0
  282. package/dist/xlsx/layout/print-merges.d.ts.map +1 -0
  283. package/dist/xlsx/layout/print-repeat.d.ts +12 -0
  284. package/dist/xlsx/layout/print-repeat.d.ts.map +1 -0
  285. package/dist/xlsx/layout/print-titles.d.ts +20 -0
  286. package/dist/xlsx/layout/print-titles.d.ts.map +1 -0
  287. package/dist/xlsx/layout/sparkline-data.d.ts.map +1 -1
  288. package/dist/xlsx/layout/sparkline-view.d.ts.map +1 -1
  289. package/dist/xlsx/load/index.cjs +8165 -6945
  290. package/dist/xlsx/load/index.mjs +8165 -6945
  291. package/dist/xlsx/model-pivots.d.ts +67 -0
  292. package/dist/xlsx/model-pivots.d.ts.map +1 -0
  293. package/dist/xlsx/model.d.ts +5 -0
  294. package/dist/xlsx/model.d.ts.map +1 -1
  295. package/dist/xlsx/pivot/admission.d.ts +5 -0
  296. package/dist/xlsx/pivot/admission.d.ts.map +1 -0
  297. package/dist/xlsx/pivot/aggregate.d.ts +21 -0
  298. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -0
  299. package/dist/xlsx/pivot/cache-xml.d.ts +9 -0
  300. package/dist/xlsx/pivot/cache-xml.d.ts.map +1 -0
  301. package/dist/xlsx/pivot/data.d.ts +12 -0
  302. package/dist/xlsx/pivot/data.d.ts.map +1 -0
  303. package/dist/xlsx/pivot/hierarchy-first.d.ts +21 -0
  304. package/dist/xlsx/pivot/hierarchy-first.d.ts.map +1 -0
  305. package/dist/xlsx/pivot/hierarchy.d.ts +5 -0
  306. package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -0
  307. package/dist/xlsx/pivot/index.d.ts +3 -0
  308. package/dist/xlsx/pivot/index.d.ts.map +1 -0
  309. package/dist/xlsx/pivot/measures.d.ts +13 -0
  310. package/dist/xlsx/pivot/measures.d.ts.map +1 -0
  311. package/dist/xlsx/pivot/read.d.ts +5 -0
  312. package/dist/xlsx/pivot/read.d.ts.map +1 -0
  313. package/dist/xlsx/pivot/table-xml.d.ts +5 -0
  314. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -0
  315. package/dist/xlsx/pivot/values-axis.d.ts +9 -0
  316. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -0
  317. package/dist/xlsx/pivot/write.d.ts +11 -0
  318. package/dist/xlsx/pivot/write.d.ts.map +1 -0
  319. package/dist/xlsx/read/load.d.ts.map +1 -1
  320. package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
  321. package/dist/xlsx/ui/commands/i18n/index.d.ts.map +1 -1
  322. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
  323. package/dist/xlsx/ui/commands/i18n/pivots.d.ts +3 -0
  324. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -0
  325. package/dist/xlsx/ui/commands/i18n/print-layout.d.ts +3 -0
  326. package/dist/xlsx/ui/commands/i18n/print-layout.d.ts.map +1 -0
  327. package/dist/xlsx/ui/commands/i18n/sparklines.d.ts +3 -0
  328. package/dist/xlsx/ui/commands/i18n/sparklines.d.ts.map +1 -0
  329. package/dist/xlsx/ui/commands/i18n/tools.d.ts.map +1 -1
  330. package/dist/xlsx/ui/commands/page-breaks.d.ts +3 -0
  331. package/dist/xlsx/ui/commands/page-breaks.d.ts.map +1 -0
  332. package/dist/xlsx/ui/index.cjs +2421 -288
  333. package/dist/xlsx/ui/index.d.ts +1 -0
  334. package/dist/xlsx/ui/index.d.ts.map +1 -1
  335. package/dist/xlsx/ui/index.mjs +2421 -289
  336. package/dist/xlsx/write/page-setup.d.ts.map +1 -1
  337. package/dist/xlsx/write/save.d.ts.map +1 -1
  338. package/dist/xlsx/write/sheet-parts.d.ts +1 -0
  339. package/dist/xlsx/write/sheet-parts.d.ts.map +1 -1
  340. package/dist/xlsx/write/workbook-part.d.ts +1 -1
  341. package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
  342. package/dist/xlsx/write/worksheet.d.ts.map +1 -1
  343. package/package.json +1 -1
  344. package/dist/pptx/chunks/index-CKIUurnd.d.ts.map +0 -1
  345. package/dist/pptx/chunks/index-Cn-GzYGp.d.ts.map +0 -1
  346. package/dist/pptx/chunks/smart-art-Q2kZQtHh.d.ts.map +0 -1
  347. package/dist/pptx/chunks/text-operations-BHfAm5K9.d.ts.map +0 -1
@@ -816,6 +816,7 @@ var init_presentation_field_keys = __esm({
816
816
  modernCommentAuthors: true,
817
817
  conformance: true,
818
818
  embedTrueTypeFonts: true,
819
+ firstSlideNumber: true,
819
820
  defaultTextStyle: true
820
821
  };
821
822
  PRESENTATION_FIELD_NAMES = Object.keys(PRESENTATION_FIELD_KEYS);
@@ -1288,6 +1289,32 @@ function inheritCustomGeometryCommandOrder(target, ...sources) {
1288
1289
  }
1289
1290
  }
1290
1291
  }
1292
+ function pathListPaths(pathLst) {
1293
+ if (!pathLst || typeof pathLst !== "object") {
1294
+ return [];
1295
+ }
1296
+ return ensureArrayLocal(childByLocalName(pathLst, "path")).filter(
1297
+ (path2) => Boolean(path2) && typeof path2 === "object"
1298
+ );
1299
+ }
1300
+ function readPathListCommandOrder(pathLst) {
1301
+ const orders = pathListPaths(pathLst).map((path2) => [...commandOrder.get(path2) ?? []]);
1302
+ return orders.some((order) => order.length > 0) ? orders : void 0;
1303
+ }
1304
+ function restorePathListCommandOrder(pathLst, orders) {
1305
+ if (!orders || orders.length === 0) {
1306
+ return;
1307
+ }
1308
+ pathListPaths(pathLst).forEach((path2, index) => {
1309
+ const order = orders[index];
1310
+ if (!order || order.length === 0 || commandOrder.has(path2)) {
1311
+ return;
1312
+ }
1313
+ if (orderSignature([...order]) === pathSignature(path2)) {
1314
+ commandOrder.set(path2, [...order]);
1315
+ }
1316
+ });
1317
+ }
1291
1318
  function orderedXmlKey(baseName, order) {
1292
1319
  return `${baseName}${ORDER_SUFFIX}${order}`;
1293
1320
  }
@@ -4412,7 +4439,7 @@ function rootRelsXml() {
4412
4439
  <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
4413
4440
  </Relationships>`;
4414
4441
  }
4415
- function presentationXml(width, height, slideCount) {
4442
+ function presentationXml(width, height, slideCount, firstSlideNumber) {
4416
4443
  const slideIdBase = 256;
4417
4444
  const slideRIdBase = 6;
4418
4445
  const sldIdLst = slideCount > 0 ? ` <p:sldIdLst>
@@ -4421,6 +4448,7 @@ ${Array.from(
4421
4448
  (_, i2) => ` <p:sldId id="${slideIdBase + i2}" r:id="rId${slideRIdBase + i2}"/>`
4422
4449
  ).join("\n")}
4423
4450
  </p:sldIdLst>` : "";
4451
+ const firstSlideNum = firstSlideNumber === void 0 ? "" : ` firstSlideNum="${Math.trunc(firstSlideNumber)}"`;
4424
4452
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
4425
4453
  <p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
4426
4454
  xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
@@ -4428,7 +4456,7 @@ ${Array.from(
4428
4456
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
4429
4457
  xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
4430
4458
  xmlns:p15="http://schemas.microsoft.com/office/powerpoint/2012/main"
4431
- saveSubsetFonts="1">
4459
+ saveSubsetFonts="1"${firstSlideNum}>
4432
4460
  <p:sldMasterIdLst>
4433
4461
  <p:sldMasterId id="2147483648" r:id="rId1"/>
4434
4462
  </p:sldMasterIdLst>
@@ -4665,7 +4693,10 @@ async function buildBlankPresentationArchive(options) {
4665
4693
  const zip = new JSZip3__default.default();
4666
4694
  zip.file("[Content_Types].xml", contentTypesXml(layoutCount, initialSlideCount));
4667
4695
  zip.file("_rels/.rels", rootRelsXml());
4668
- zip.file("ppt/presentation.xml", presentationXml(width, height, initialSlideCount));
4696
+ zip.file(
4697
+ "ppt/presentation.xml",
4698
+ presentationXml(width, height, initialSlideCount, options?.firstSlideNumber)
4699
+ );
4669
4700
  zip.file("ppt/_rels/presentation.xml.rels", presentationRelsXml(layoutCount, initialSlideCount));
4670
4701
  zip.file("ppt/slideMasters/slideMaster1.xml", slideMasterXml(layoutCount));
4671
4702
  zip.file("ppt/slideMasters/_rels/slideMaster1.xml.rels", slideMasterRelsXml(layoutCount));
@@ -39165,6 +39196,13 @@ function parseContentTypes(xml) {
39165
39196
  }
39166
39197
  return { defaults, overrides };
39167
39198
  }
39199
+ function contentTypeForPart(types, partName) {
39200
+ const overridePath = partName.startsWith("/") ? partName : `/${partName}`;
39201
+ const override = types.overrides.get(overridePath);
39202
+ if (override) return override;
39203
+ const extension = partName.split(".").pop()?.toLowerCase();
39204
+ return extension ? types.defaults.get(extension) : void 0;
39205
+ }
39168
39206
  var init_content_types = __esm({
39169
39207
  "opc/content-types.ts"() {
39170
39208
  init_xml2();
@@ -39204,10 +39242,13 @@ function relativePartTarget(basePart, targetPart) {
39204
39242
  }
39205
39243
  async function clonePartGraph(options) {
39206
39244
  const { zip, sourcePart, targetPart, shouldClone } = options;
39207
- const copies = /* @__PURE__ */ new Map([[sourcePart, targetPart]]);
39208
- const types = parseContentTypes(await zip.file("[Content_Types].xml")?.async("string"));
39245
+ const sourceZip = options.sourceZip ?? zip;
39246
+ const copies = options.copies ?? /* @__PURE__ */ new Map();
39247
+ copies.set(sourcePart, targetPart);
39248
+ const types = parseContentTypes(await sourceZip.file("[Content_Types].xml")?.async("string"));
39209
39249
  const reserved = new Set(Object.keys(zip.files));
39210
39250
  reserved.add(targetPart);
39251
+ for (const target of copies.values()) reserved.add(target);
39211
39252
  const allocate = (source) => {
39212
39253
  const match = /^(?<stem>.*?)(?:\d+)?(?<extension>\.[^/.]+)$/u.exec(source);
39213
39254
  const stem = match?.groups?.stem ?? source;
@@ -39219,9 +39260,9 @@ async function clonePartGraph(options) {
39219
39260
  return path2;
39220
39261
  };
39221
39262
  const copyRelationships = async (source, destination) => {
39222
- const contentType = types.overrides.get(`/${source}`);
39263
+ const contentType = contentTypeForPart(types, source);
39223
39264
  if (contentType) await ensureContentTypeOverride(zip, destination, contentType);
39224
- const xml = await zip.file(relationshipsPartFor(source))?.async("string");
39265
+ const xml = await sourceZip.file(relationshipsPartFor(source))?.async("string");
39225
39266
  if (!xml) return;
39226
39267
  const relationships2 = parseRelationships(xml);
39227
39268
  for (const relationship of relationships2.values()) {
@@ -39229,7 +39270,7 @@ async function clonePartGraph(options) {
39229
39270
  const originalTarget = resolvePartPath(source, relationship.target);
39230
39271
  let newTarget = copies.get(originalTarget);
39231
39272
  if (!newTarget && shouldClone(relationship, originalTarget)) {
39232
- const file = zip.file(originalTarget);
39273
+ const file = sourceZip.file(originalTarget);
39233
39274
  if (!file) throw new Error(`Cannot clone missing package part: ${originalTarget}`);
39234
39275
  newTarget = allocate(originalTarget);
39235
39276
  copies.set(originalTarget, newTarget);
@@ -58461,6 +58502,7 @@ var init_custom_geometry_parser = __esm({
58461
58502
  // pptx/core/geometry/custom-geometry-live-eval.ts
58462
58503
  function pathNodesOf(rawData) {
58463
58504
  const pathLst = rawData?.pathLstXml;
58505
+ restorePathListCommandOrder(pathLst, rawData?.pathCommandOrder);
58464
58506
  return ensureArrayValue(pathLst?.["a:path"]);
58465
58507
  }
58466
58508
  function evaluateCustomGeometryPaths(rawData, pathWidth, pathHeight, overrides) {
@@ -58500,6 +58542,7 @@ var init_custom_geometry_live_eval = __esm({
58500
58542
  "pptx/core/geometry/custom-geometry-live-eval.ts"() {
58501
58543
  init_utils();
58502
58544
  init_custom_geometry();
58545
+ init_custom_geometry_command_order();
58503
58546
  init_custom_geometry_guides();
58504
58547
  init_custom_geometry_parser();
58505
58548
  ensureArray8 = (value) => ensureArrayValue(value);
@@ -61136,7 +61179,13 @@ var init_PptxSlideNotesPartUpdater = __esm({
61136
61179
  init.slideNotesRelationshipType,
61137
61180
  `../notesSlides/${fileName}`
61138
61181
  );
61139
- init.zip.file(notesPath, init.xmlBuilder.build(this.buildNotesSlide(init.slide, strict)));
61182
+ const notesXmlObject = this.buildNotesSlide(init.slide, strict);
61183
+ init.updateNotesXmlText(
61184
+ notesXmlObject,
61185
+ init.slide.notes ?? init.slide.notesSegments?.map((segment) => segment.text).join("") ?? "",
61186
+ init.slide.notesSegments
61187
+ );
61188
+ init.zip.file(notesPath, init.xmlBuilder.build(notesXmlObject));
61140
61189
  init.zip.file(
61141
61190
  `ppt/notesSlides/_rels/${fileName}.rels`,
61142
61191
  init.xmlBuilder.build({
@@ -65820,7 +65869,7 @@ function parseShapeLockNode(node, spec) {
65820
65869
  return void 0;
65821
65870
  }
65822
65871
  const locks = {};
65823
- let hasAny = false;
65872
+ let hasAny2 = false;
65824
65873
  for (const prop of spec.permitted) {
65825
65874
  const raw = node[LOCK_ATTRIBUTE[prop]];
65826
65875
  if (raw === void 0) {
@@ -65828,9 +65877,9 @@ function parseShapeLockNode(node, spec) {
65828
65877
  }
65829
65878
  const value = String(raw).trim().toLowerCase();
65830
65879
  locks[prop] = value === "1" || value === "true";
65831
- hasAny = true;
65880
+ hasAny2 = true;
65832
65881
  }
65833
- return hasAny ? locks : void 0;
65882
+ return hasAny2 ? locks : void 0;
65834
65883
  }
65835
65884
  var LOCK_ATTRIBUTE, MODELLED_ATTRIBUTES, CARRIED_WHEN_UNSET;
65836
65885
  var init_shape_lock_node = __esm({
@@ -66697,6 +66746,7 @@ var init_PptxLoadDataBuilder = __esm({
66697
66746
  modernCommentAuthors;
66698
66747
  conformance;
66699
66748
  embedTrueTypeFonts;
66749
+ firstSlideNumber;
66700
66750
  defaultTextStyle;
66701
66751
  withDimensions(width, height, widthEmu, heightEmu) {
66702
66752
  this.width = width;
@@ -66866,6 +66916,10 @@ var init_PptxLoadDataBuilder = __esm({
66866
66916
  this.embedTrueTypeFonts = embedTrueTypeFonts;
66867
66917
  return this;
66868
66918
  }
66919
+ withFirstSlideNumber(firstSlideNumber) {
66920
+ this.firstSlideNumber = firstSlideNumber;
66921
+ return this;
66922
+ }
66869
66923
  withDefaultTextStyle(defaultTextStyle) {
66870
66924
  this.defaultTextStyle = defaultTextStyle;
66871
66925
  return this;
@@ -66917,6 +66971,7 @@ var init_PptxLoadDataBuilder = __esm({
66917
66971
  modernCommentAuthors: this.modernCommentAuthors,
66918
66972
  conformance: this.conformance,
66919
66973
  embedTrueTypeFonts: this.embedTrueTypeFonts,
66974
+ firstSlideNumber: this.firstSlideNumber,
66920
66975
  defaultTextStyle: this.defaultTextStyle
66921
66976
  };
66922
66977
  }
@@ -70821,6 +70876,297 @@ var init_native_animation_media_duration = __esm({
70821
70876
  }
70822
70877
  });
70823
70878
 
70879
+ // pptx/core/services/editor-animation-entry.ts
70880
+ function hasAuthoredAnimationEffect(entry2) {
70881
+ return Boolean(
70882
+ [entry2.entrance, entry2.exit, entry2.emphasis].some((preset) => preset && preset !== "none") || entry2.motionPath
70883
+ );
70884
+ }
70885
+ function animationFor(slideAnimations, elementId) {
70886
+ return slideAnimations.find((a) => a.elementId === elementId);
70887
+ }
70888
+ var init_editor_animation_entry = __esm({
70889
+ "pptx/core/services/editor-animation-entry.ts"() {
70890
+ }
70891
+ });
70892
+
70893
+ // pptx/core/services/native-animation-after-effect.ts
70894
+ function hasAfterEffectFlag(cTn) {
70895
+ const raw = cTn?.["@_afterEffect"];
70896
+ return raw === "1" || raw === "true";
70897
+ }
70898
+ function extractSrgbHex(colorContainer) {
70899
+ const srgb = colorContainer?.["a:srgbClr"];
70900
+ const val = srgb?.["@_val"];
70901
+ return val !== void 0 ? `#${String(val).toUpperCase()}` : void 0;
70902
+ }
70903
+ function findDimBehaviour(subTnLst) {
70904
+ for (const node of ensureArray11(subTnLst["p:animClr"])) {
70905
+ const cBhvr = node["p:cBhvr"];
70906
+ if (extractAttrNameFromCBhvr(cBhvr) !== "ppt_c") {
70907
+ continue;
70908
+ }
70909
+ if (!hasAfterEffectFlag(cBhvr?.["p:cTn"])) {
70910
+ continue;
70911
+ }
70912
+ const toNode = node["p:to"];
70913
+ const color2 = extractSrgbHex(toNode);
70914
+ if (color2) {
70915
+ return { action: "dimToColor", color: color2 };
70916
+ }
70917
+ const colorRef = themeColorRefFromSchemeClr(toNode?.["a:schemeClr"]);
70918
+ return colorRef ? { action: "dimToColor", colorRef } : { action: "dimToColor" };
70919
+ }
70920
+ return void 0;
70921
+ }
70922
+ function findHideBehaviour(subTnLst) {
70923
+ for (const node of ensureArray11(subTnLst["p:set"])) {
70924
+ const cBhvr = node["p:cBhvr"];
70925
+ if (extractAttrNameFromCBhvr(cBhvr) !== "style.visibility") {
70926
+ continue;
70927
+ }
70928
+ const innerCTn = cBhvr?.["p:cTn"];
70929
+ if (!hasAfterEffectFlag(innerCTn)) {
70930
+ continue;
70931
+ }
70932
+ const toNode = node["p:to"];
70933
+ const strVal = toNode?.["p:strVal"]?.["@_val"];
70934
+ if (String(strVal ?? "").toLowerCase() !== "hidden") {
70935
+ continue;
70936
+ }
70937
+ const action = innerCTn?.["@_masterRel"] === "sameClick" ? "hideAfterAnimation" : "hideOnNextClick";
70938
+ return { action };
70939
+ }
70940
+ return void 0;
70941
+ }
70942
+ function extractAfterAnimationFromSubTnLst(cTn) {
70943
+ const subTnLst = cTn["p:subTnLst"];
70944
+ if (!subTnLst) {
70945
+ return void 0;
70946
+ }
70947
+ return findDimBehaviour(subTnLst) ?? findHideBehaviour(subTnLst);
70948
+ }
70949
+ var init_native_animation_after_effect = __esm({
70950
+ "pptx/core/services/native-animation-after-effect.ts"() {
70951
+ init_theme_color_ref();
70952
+ init_native_animation_attr_name();
70953
+ init_native_animation_helpers();
70954
+ }
70955
+ });
70956
+
70957
+ // pptx/core/services/animation-after-effect-write.ts
70958
+ function assertAfterAnimationClearSupported(effectCTn) {
70959
+ const shapeIds = /* @__PURE__ */ new Set();
70960
+ const checkTarget = (value) => {
70961
+ if (Array.isArray(value)) {
70962
+ value.forEach(checkTarget);
70963
+ return;
70964
+ }
70965
+ if (!isXmlObject5(value)) return;
70966
+ const shapeTarget = value["p:spTgt"];
70967
+ if (isXmlObject5(shapeTarget) && shapeTarget["@_spid"] !== void 0)
70968
+ shapeIds.add(String(shapeTarget["@_spid"]));
70969
+ if ([
70970
+ "p:bg",
70971
+ "p:txEl",
70972
+ "p:subSp",
70973
+ "p:graphicEl",
70974
+ "p:oleChartEl",
70975
+ "p:sndTgt",
70976
+ "p:inkTgt",
70977
+ "p:sldTgt"
70978
+ ].some((key2) => value[key2] !== void 0))
70979
+ throw new Error("Clearing after-animation supports whole-shape targets only");
70980
+ Object.values(value).forEach(checkTarget);
70981
+ };
70982
+ checkTarget(effectCTn["p:childTnLst"]);
70983
+ if (shapeIds.size > 1)
70984
+ throw new Error("Editing after-animation supports a single whole-shape target only");
70985
+ const sub = effectCTn["p:subTnLst"];
70986
+ if (!isXmlObject5(sub)) return;
70987
+ const countAfterFlags = (value) => {
70988
+ if (Array.isArray(value))
70989
+ return value.reduce((count, child30) => count + countAfterFlags(child30), 0);
70990
+ if (!isXmlObject5(value)) return 0;
70991
+ return Object.entries(value).reduce(
70992
+ (count, [key2, child30]) => count + (key2 === "@_afterEffect" && ["1", "true"].includes(String(child30)) ? 1 : countAfterFlags(child30)),
70993
+ 0
70994
+ );
70995
+ };
70996
+ for (const [key2, value] of Object.entries(sub)) {
70997
+ for (const node of ensureArray11(value)) {
70998
+ const flags = countAfterFlags(node);
70999
+ if (!flags) continue;
71000
+ if (flags !== 1 || !extractAfterAnimationFromSubTnLst({ "p:subTnLst": { [key2]: node } }))
71001
+ throw new Error("Cannot clear an unsupported native after-animation behavior");
71002
+ checkTarget(node);
71003
+ }
71004
+ }
71005
+ if (shapeIds.size > 1)
71006
+ throw new Error("Editing after-animation supports a single whole-shape target only");
71007
+ }
71008
+ function clearAfterAnimationBehavior(effectCTn) {
71009
+ const sub = effectCTn["p:subTnLst"];
71010
+ if (!isXmlObject5(sub)) return;
71011
+ for (const key2 of Object.keys(sub)) {
71012
+ const nodes = ensureArray11(sub[key2]);
71013
+ const remaining = nodes.filter(
71014
+ (node) => !extractAfterAnimationFromSubTnLst({ "p:subTnLst": { [key2]: node } })
71015
+ );
71016
+ if (remaining.length === nodes.length) continue;
71017
+ if (remaining.length === 0) delete sub[key2];
71018
+ else sub[key2] = remaining.length === 1 ? remaining[0] : remaining;
71019
+ }
71020
+ if (Object.keys(sub).length === 0) delete effectCTn["p:subTnLst"];
71021
+ }
71022
+ function applyAfterAnimationBehavior(effectCTn, anim, shapeId) {
71023
+ if (anim.afterAnimation === void 0) return;
71024
+ if (anim.afterAnimation === "none") {
71025
+ assertAfterAnimationClearSupported(effectCTn);
71026
+ clearAfterAnimationBehavior(effectCTn);
71027
+ return;
71028
+ }
71029
+ assertAfterAnimationClearSupported(effectCTn);
71030
+ clearAfterAnimationBehavior(effectCTn);
71031
+ delete effectCTn["@_afterEffect"];
71032
+ if (anim.afterAnimation === "dimToColor" && anim.afterAnimationColor) {
71033
+ appendAfterAnimationBehavior(effectCTn, buildDimSubTnLst(shapeId, anim.afterAnimationColor));
71034
+ return;
71035
+ }
71036
+ if (anim.afterAnimation === "hideAfterAnimation") {
71037
+ const entranceId = effectCTn["@_id"] !== void 0 ? String(effectCTn["@_id"]) : "0";
71038
+ appendAfterAnimationBehavior(effectCTn, buildHideSubTnLst(shapeId, "sameClick", entranceId));
71039
+ return;
71040
+ }
71041
+ if (anim.afterAnimation === "hideOnNextClick") {
71042
+ appendAfterAnimationBehavior(effectCTn, buildHideSubTnLst(shapeId, "nextClick"));
71043
+ }
71044
+ }
71045
+ function appendAfterAnimationBehavior(effect, addition) {
71046
+ const sub = isXmlObject5(effect["p:subTnLst"]) ? effect["p:subTnLst"] : {};
71047
+ for (const [key2, value] of Object.entries(addition)) {
71048
+ const nodes = [...ensureArray11(sub[key2]), ...ensureArray11(value)];
71049
+ sub[key2] = nodes.length === 1 ? nodes[0] : nodes;
71050
+ }
71051
+ effect["p:subTnLst"] = sub;
71052
+ }
71053
+ function buildDimSubTnLst(shapeId, colorHex) {
71054
+ const hex3 = colorHex.replace(/^#/u, "").toUpperCase();
71055
+ return {
71056
+ "p:animClr": {
71057
+ "@_clrSpc": "rgb",
71058
+ "@_dir": "cw",
71059
+ "p:cBhvr": {
71060
+ "@_override": "childStyle",
71061
+ "p:cTn": {
71062
+ "@_dur": "1",
71063
+ "@_fill": "hold",
71064
+ "@_display": "0",
71065
+ "@_masterRel": "nextClick",
71066
+ "@_afterEffect": "1"
71067
+ },
71068
+ "p:tgtEl": { "p:spTgt": { "@_spid": shapeId } },
71069
+ "p:attrNameLst": { "p:attrName": "ppt_c" }
71070
+ },
71071
+ "p:to": { "a:srgbClr": { "@_val": hex3 } }
71072
+ }
71073
+ };
71074
+ }
71075
+ function buildHideSubTnLst(shapeId, masterRel, entranceId) {
71076
+ const cTn = {
71077
+ "@_dur": "1",
71078
+ "@_fill": "hold",
71079
+ "@_display": "0",
71080
+ "@_masterRel": masterRel,
71081
+ "@_afterEffect": "1"
71082
+ };
71083
+ if (masterRel === "sameClick") {
71084
+ cTn["p:stCondLst"] = {
71085
+ "p:cond": {
71086
+ "@_evt": "end",
71087
+ "@_delay": "0",
71088
+ "p:tn": { "@_val": entranceId ?? "0" }
71089
+ }
71090
+ };
71091
+ }
71092
+ return {
71093
+ "p:set": {
71094
+ "p:cBhvr": {
71095
+ "@_override": "childStyle",
71096
+ "p:cTn": cTn,
71097
+ "p:tgtEl": { "p:spTgt": { "@_spid": shapeId } },
71098
+ "p:attrNameLst": { "p:attrName": "style.visibility" }
71099
+ },
71100
+ "p:to": { "p:strVal": { "@_val": "hidden" } }
71101
+ }
71102
+ };
71103
+ }
71104
+ var init_animation_after_effect_write = __esm({
71105
+ "pptx/core/services/animation-after-effect-write.ts"() {
71106
+ init_native_animation_after_effect();
71107
+ init_native_animation_helpers();
71108
+ }
71109
+ });
71110
+
71111
+ // pptx/core/services/editor-animation-after-effect.ts
71112
+ function mergeNativeAfterAnimationIntoEditorAnimations(nativeAnimations, animations, rawTiming) {
71113
+ for (const native of nativeAnimations ?? []) {
71114
+ const existing = native.targetId ? animationFor(animations, native.targetId) : void 0;
71115
+ const action = native.afterAnimationAction ?? (existing?.afterAnimation !== void 0 ? "none" : void 0);
71116
+ if ((nativeAnimations ?? []).filter(
71117
+ (other) => other.targetId === native.targetId && ["entr", "emph"].includes(other.presetClass ?? "")
71118
+ ).length !== 1)
71119
+ continue;
71120
+ if (!native.targetId || !action || !["entr", "emph"].includes(native.presetClass ?? "") || native.textTarget)
71121
+ continue;
71122
+ if (native.target && (native.target.type !== "shape" || native.target.backgroundOnly || native.target.subShapeId || native.target.graphicElement || native.target.oleChartElement))
71123
+ continue;
71124
+ try {
71125
+ if (rawTiming && native.target?.type === "shape" && indexEffectNodes(rawTiming).filter(
71126
+ (ref) => ref.spid === (native.target?.type === "shape" ? native.target.shapeId : void 0) && ["entr", "emph"].includes(ref.presetClass)
71127
+ ).length !== 1)
71128
+ continue;
71129
+ const effect = rawTiming ? indexEffectNodes(rawTiming).find(
71130
+ (ref) => String(ref.cTn["@_id"]) === String(native.nodeId) && native.target?.type === "shape" && ref.spid === native.target.shapeId
71131
+ ) : void 0;
71132
+ if (rawTiming && !effect) continue;
71133
+ assertAfterAnimationClearSupported(
71134
+ effect?.cTn ?? { "p:subTnLst": native.cTnAttributes?.["p:subTnLst"] }
71135
+ );
71136
+ } catch {
71137
+ continue;
71138
+ }
71139
+ let entry2 = animationFor(animations, native.targetId);
71140
+ if (!entry2) {
71141
+ entry2 = { elementId: native.targetId };
71142
+ animations.push(entry2);
71143
+ }
71144
+ if (entry2.nativeAfterAnimation !== void 0) continue;
71145
+ entry2.nativeAfterAnimation = action;
71146
+ entry2.nativeAfterAnimationColor = native.afterAnimationColor;
71147
+ }
71148
+ }
71149
+ function isNativeAfterAnimationFallback(entry2) {
71150
+ return entry2.nativeAfterAnimation !== void 0 && Object.entries(entry2).every(
71151
+ ([key2, value]) => value === void 0 || [
71152
+ "elementId",
71153
+ "nativeAfterAnimation",
71154
+ "nativeAfterAnimationColor",
71155
+ "soundRId",
71156
+ "soundPath",
71157
+ "soundName",
71158
+ "stopSound"
71159
+ ].includes(key2)
71160
+ );
71161
+ }
71162
+ var init_editor_animation_after_effect = __esm({
71163
+ "pptx/core/services/editor-animation-after-effect.ts"() {
71164
+ init_editor_animation_entry();
71165
+ init_animation_after_effect_write();
71166
+ init_animation_timing_tree();
71167
+ }
71168
+ });
71169
+
70824
71170
  // pptx/core/services/slide-name.ts
70825
71171
  function asNode3(value) {
70826
71172
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
@@ -71151,6 +71497,7 @@ var init_PptxSlideLoaderService = __esm({
71151
71497
  init_animation_target_reconcile();
71152
71498
  init_animation_timeline_anchors();
71153
71499
  init_native_animation_media_duration();
71500
+ init_editor_animation_after_effect();
71154
71501
  init_slide_name();
71155
71502
  init_slide_transition_envelope();
71156
71503
  PptxSlideLoaderService = class {
@@ -71362,6 +71709,8 @@ var init_PptxSlideLoaderService = __esm({
71362
71709
  }
71363
71710
  });
71364
71711
  reconcileAnimationTargets(elements3, nativeAnimations, animations, animationTimelineAnchors);
71712
+ animations ??= [];
71713
+ mergeNativeAfterAnimationIntoEditorAnimations(nativeAnimations, animations, rawTiming);
71365
71714
  mergeNativeSoundIntoEditorAnimations(nativeAnimations, animations);
71366
71715
  mergeNativeBuildTemplatesIntoEditorAnimations(nativeAnimations, animations);
71367
71716
  applyHiddenFlagFromRawXml(elements3);
@@ -71704,6 +72053,7 @@ function sortOrder(animation) {
71704
72053
  var PptxEditorAnimationService;
71705
72054
  var init_PptxEditorAnimationService = __esm({
71706
72055
  "pptx/core/services/PptxEditorAnimationService.ts"() {
72056
+ init_editor_animation_after_effect();
71707
72057
  init_editor_animation_normalizers();
71708
72058
  init_editor_animation_trigger_meta();
71709
72059
  PptxEditorAnimationService = class {
@@ -71802,7 +72152,7 @@ var init_PptxEditorAnimationService = __esm({
71802
72152
  * @param animations - Editor animations to serialize.
71803
72153
  */
71804
72154
  applyEditorAnimations(slideNode, animations) {
71805
- const sequenced = [...animations].sort((left, right) => sortOrder(left) - sortOrder(right));
72155
+ const sequenced = animations.filter((entry2) => !isNativeAfterAnimationFallback(entry2)).sort((left, right) => sortOrder(left) - sortOrder(right));
71806
72156
  const sanitizedAnimations = sequenced.map((animation) => {
71807
72157
  const elementId = String(animation.elementId || "").trim();
71808
72158
  if (elementId.length === 0) {
@@ -71816,7 +72166,7 @@ var init_PptxEditorAnimationService = __esm({
71816
72166
  const orderIsTreeDerived = animation.orderFromTimeline !== void 0 && animation.order === animation.orderFromTimeline;
71817
72167
  const order = typeof animation.order === "number" && Number.isFinite(animation.order) && !orderIsTreeDerived ? Math.round(animation.order) : void 0;
71818
72168
  const repeatCount = typeof animation.repeatCount === "number" && Number.isFinite(animation.repeatCount) && animation.repeatCount > 0 ? animation.repeatCount : void 0;
71819
- if (!entrance && !exit2 && !emphasis && !animation.motionPath) {
72169
+ if (!entrance && !exit2 && !emphasis && !animation.motionPath && animation.afterAnimation === void 0) {
71820
72170
  return null;
71821
72171
  }
71822
72172
  return {
@@ -72301,70 +72651,6 @@ var init_animation_effect_filter_parsing = __esm({
72301
72651
  }
72302
72652
  });
72303
72653
 
72304
- // pptx/core/services/native-animation-after-effect.ts
72305
- function hasAfterEffectFlag(cTn) {
72306
- const raw = cTn?.["@_afterEffect"];
72307
- return raw === "1" || raw === "true";
72308
- }
72309
- function extractSrgbHex(colorContainer) {
72310
- const srgb = colorContainer?.["a:srgbClr"];
72311
- const val = srgb?.["@_val"];
72312
- return val !== void 0 ? `#${String(val).toUpperCase()}` : void 0;
72313
- }
72314
- function findDimBehaviour(subTnLst) {
72315
- for (const node of ensureArray11(subTnLst["p:animClr"])) {
72316
- const cBhvr = node["p:cBhvr"];
72317
- if (extractAttrNameFromCBhvr(cBhvr) !== "ppt_c") {
72318
- continue;
72319
- }
72320
- if (!hasAfterEffectFlag(cBhvr?.["p:cTn"])) {
72321
- continue;
72322
- }
72323
- const toNode = node["p:to"];
72324
- const color2 = extractSrgbHex(toNode);
72325
- if (color2) {
72326
- return { action: "dimToColor", color: color2 };
72327
- }
72328
- const colorRef = themeColorRefFromSchemeClr(toNode?.["a:schemeClr"]);
72329
- return colorRef ? { action: "dimToColor", colorRef } : { action: "dimToColor" };
72330
- }
72331
- return void 0;
72332
- }
72333
- function findHideBehaviour(subTnLst) {
72334
- for (const node of ensureArray11(subTnLst["p:set"])) {
72335
- const cBhvr = node["p:cBhvr"];
72336
- if (extractAttrNameFromCBhvr(cBhvr) !== "style.visibility") {
72337
- continue;
72338
- }
72339
- const innerCTn = cBhvr?.["p:cTn"];
72340
- if (!hasAfterEffectFlag(innerCTn)) {
72341
- continue;
72342
- }
72343
- const toNode = node["p:to"];
72344
- const strVal = toNode?.["p:strVal"]?.["@_val"];
72345
- if (String(strVal ?? "").toLowerCase() !== "hidden") {
72346
- continue;
72347
- }
72348
- const action = innerCTn?.["@_masterRel"] === "sameClick" ? "hideAfterAnimation" : "hideOnNextClick";
72349
- return { action };
72350
- }
72351
- return void 0;
72352
- }
72353
- function extractAfterAnimationFromSubTnLst(cTn) {
72354
- const subTnLst = cTn["p:subTnLst"];
72355
- if (!subTnLst) {
72356
- return void 0;
72357
- }
72358
- return findDimBehaviour(subTnLst) ?? findHideBehaviour(subTnLst);
72359
- }
72360
- var init_native_animation_after_effect = __esm({
72361
- "pptx/core/services/native-animation-after-effect.ts"() {
72362
- init_theme_color_ref();
72363
- init_native_animation_attr_name();
72364
- init_native_animation_helpers();
72365
- }
72366
- });
72367
-
72368
72654
  // pptx/core/services/native-animation-cbhvr-attrs.ts
72369
72655
  function extractCBhvrAttrs(cBhvr) {
72370
72656
  if (!cBhvr) {
@@ -72513,6 +72799,16 @@ function readTiming(cTn) {
72513
72799
  return {};
72514
72800
  }
72515
72801
  const timing = {};
72802
+ const starts = ensureArray11(cTn["p:stCondLst"]?.["p:cond"]);
72803
+ if (starts.length > 1 || cTn["@_dur"] === "indefinite" || cTn["@_repeatCount"] === "indefinite" || cTn["@_repeatDur"] !== void 0 || cTn["p:endCondLst"] !== void 0 || cTn["p:endSync"] !== void 0 || starts.some(
72804
+ (condition) => condition === null || typeof condition !== "object" || condition["@_evt"] !== void 0 || condition["@_tn"] !== void 0 || condition["@_rtn"] !== void 0 || condition["p:tn"] !== void 0 || condition["p:rtn"] !== void 0 || condition["p:tgtEl"] !== void 0 || condition["@_delay"] !== void 0 && !/^\d+$/u.test(String(condition["@_delay"])) || condition["@_delay"] === "indefinite"
72805
+ )) {
72806
+ timing.unsupportedSetTiming = true;
72807
+ }
72808
+ const fill = cTn["@_fill"];
72809
+ if (fill === "remove" || fill === "freeze" || fill === "hold" || fill === "transition") {
72810
+ timing.fill = fill;
72811
+ }
72516
72812
  const durationMs = readTimingAttr(cTn["@_dur"]);
72517
72813
  if (durationMs !== void 0) {
72518
72814
  timing.durationMs = durationMs;
@@ -72918,6 +73214,7 @@ function buildTimingNodeAnimation(cTn, trigger, group) {
72918
73214
  commandString: cmdInfo.commandString,
72919
73215
  textTarget: textTarget ?? void 0,
72920
73216
  cTnAttributes: roundTripAttrs,
73217
+ unsupportedOpacitySetTiming: cTn["@_dur"] === "indefinite" || cTn["p:endSync"] !== void 0 || void 0,
72921
73218
  afterEffect: afterEffectFlag,
72922
73219
  afterAnimationAction: parsedAfterAnimation?.action,
72923
73220
  afterAnimationColor: parsedAfterAnimation?.color,
@@ -73721,79 +74018,6 @@ var init_PptxSlideTransitionService = __esm({
73721
74018
  }
73722
74019
  });
73723
74020
 
73724
- // pptx/core/services/animation-after-effect-write.ts
73725
- function applyAfterAnimationBehavior(effectCTn, anim, shapeId) {
73726
- delete effectCTn["p:subTnLst"];
73727
- delete effectCTn["@_afterEffect"];
73728
- if (anim.afterAnimation === "dimToColor" && anim.afterAnimationColor) {
73729
- effectCTn["p:subTnLst"] = buildDimSubTnLst(shapeId, anim.afterAnimationColor);
73730
- return;
73731
- }
73732
- if (anim.afterAnimation === "hideAfterAnimation") {
73733
- const entranceId = effectCTn["@_id"] !== void 0 ? String(effectCTn["@_id"]) : "0";
73734
- effectCTn["p:subTnLst"] = buildHideSubTnLst(shapeId, "sameClick", entranceId);
73735
- return;
73736
- }
73737
- if (anim.afterAnimation === "hideOnNextClick") {
73738
- effectCTn["p:subTnLst"] = buildHideSubTnLst(shapeId, "nextClick");
73739
- }
73740
- }
73741
- function buildDimSubTnLst(shapeId, colorHex) {
73742
- const hex3 = colorHex.replace(/^#/u, "").toUpperCase();
73743
- return {
73744
- "p:animClr": {
73745
- "@_clrSpc": "rgb",
73746
- "@_dir": "cw",
73747
- "p:cBhvr": {
73748
- "@_override": "childStyle",
73749
- "p:cTn": {
73750
- "@_dur": "1",
73751
- "@_fill": "hold",
73752
- "@_display": "0",
73753
- "@_masterRel": "nextClick",
73754
- "@_afterEffect": "1"
73755
- },
73756
- "p:tgtEl": { "p:spTgt": { "@_spid": shapeId } },
73757
- "p:attrNameLst": { "p:attrName": "ppt_c" }
73758
- },
73759
- "p:to": { "a:srgbClr": { "@_val": hex3 } }
73760
- }
73761
- };
73762
- }
73763
- function buildHideSubTnLst(shapeId, masterRel, entranceId) {
73764
- const cTn = {
73765
- "@_dur": "1",
73766
- "@_fill": "hold",
73767
- "@_display": "0",
73768
- "@_masterRel": masterRel,
73769
- "@_afterEffect": "1"
73770
- };
73771
- if (masterRel === "sameClick") {
73772
- cTn["p:stCondLst"] = {
73773
- "p:cond": {
73774
- "@_evt": "end",
73775
- "@_delay": "0",
73776
- "p:tn": { "@_val": entranceId ?? "0" }
73777
- }
73778
- };
73779
- }
73780
- return {
73781
- "p:set": {
73782
- "p:cBhvr": {
73783
- "@_override": "childStyle",
73784
- "p:cTn": cTn,
73785
- "p:tgtEl": { "p:spTgt": { "@_spid": shapeId } },
73786
- "p:attrNameLst": { "p:attrName": "style.visibility" }
73787
- },
73788
- "p:to": { "p:strVal": { "@_val": "hidden" } }
73789
- }
73790
- };
73791
- }
73792
- var init_animation_after_effect_write = __esm({
73793
- "pptx/core/services/animation-after-effect-write.ts"() {
73794
- }
73795
- });
73796
-
73797
74021
  // pptx/core/services/animation-behavior-captures.json
73798
74022
  var animation_behavior_captures_default;
73799
74023
  var init_animation_behavior_captures = __esm({
@@ -92008,6 +92232,33 @@ function updateEffectNodeAttributes(cTn, anim, presetClass, shapeId, allocateId)
92008
92232
  applySoundToEffectCTn(cTn, anim);
92009
92233
  }
92010
92234
  function surgicallyUpdateTimingTree(rawTiming, animations) {
92235
+ const sourceRefs = indexEffectNodes(rawTiming);
92236
+ for (const entry2 of animations.filter((animation) => animation.afterAnimation !== void 0)) {
92237
+ if (sourceRefs.filter(
92238
+ (ref) => ref.spid === entry2.elementId && ["entr", "emph"].includes(ref.presetClass)
92239
+ ).length > 1)
92240
+ throw new Error(
92241
+ "Cannot edit an ambiguous native after-animation target with multiple effects"
92242
+ );
92243
+ }
92244
+ const explicitClears = new Map(
92245
+ animations.filter((a) => a.afterAnimation !== void 0 && !hasAuthoredAnimationEffect(a)).map((a) => [a.elementId, a])
92246
+ );
92247
+ const clearRefs = sourceRefs.filter(
92248
+ (ref) => ref.spid && explicitClears.has(ref.spid) && (ref.presetClass === "entr" || ref.presetClass === "emph")
92249
+ );
92250
+ for (const target of explicitClears.keys()) {
92251
+ if (!clearRefs.some((ref) => ref.spid === target))
92252
+ throw new Error("Cannot edit after-animation without a supported native effect");
92253
+ if (clearRefs.filter((ref) => ref.spid === target).length > 1)
92254
+ throw new Error(
92255
+ "Cannot clear an ambiguous native after-animation target with multiple effects"
92256
+ );
92257
+ }
92258
+ clearRefs.forEach((ref) => assertAfterAnimationClearSupported(ref.cTn));
92259
+ clearRefs.forEach(
92260
+ (ref) => applyAfterAnimationBehavior(ref.cTn, explicitClears.get(ref.spid), ref.spid)
92261
+ );
92011
92262
  const desired = collectDesiredEffects(animations);
92012
92263
  const previouslyOwned = readOwnedEffectKeys(rawTiming);
92013
92264
  if (desired.length === 0 && previouslyOwned.size === 0) {
@@ -92074,6 +92325,7 @@ function surgicallyUpdateTimingTree(rawTiming, animations) {
92074
92325
  }
92075
92326
  var init_animation_timing_surgical = __esm({
92076
92327
  "pptx/core/services/animation-timing-surgical.ts"() {
92328
+ init_editor_animation_entry();
92077
92329
  init_animation_after_effect_write();
92078
92330
  init_animation_behavior_captured();
92079
92331
  init_animation_timing_build_surgical();
@@ -92124,9 +92376,11 @@ var init_PptxAnimationWriteService = __esm({
92124
92376
  const validAnimations = animations.filter((a) => a.entrance || a.exit || a.emphasis || a.motionPath).sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
92125
92377
  if (existingRawTiming) {
92126
92378
  const cloned = typeof structuredClone === "function" ? structuredClone(existingRawTiming) : JSON.parse(JSON.stringify(existingRawTiming));
92127
- return surgicallyUpdateTimingTree(cloned, validAnimations);
92379
+ return surgicallyUpdateTimingTree(cloned, animations);
92128
92380
  }
92129
92381
  if (validAnimations.length === 0) {
92382
+ if (animations.some((entry2) => entry2.afterAnimation !== void 0))
92383
+ throw new Error("Cannot edit after-animation without a supported native effect");
92130
92384
  return void 0;
92131
92385
  }
92132
92386
  this.nextId = 1;
@@ -93669,6 +93923,341 @@ var init_header_footer_parts = __esm({
93669
93923
  }
93670
93924
  });
93671
93925
 
93926
+ // pptx/core/utils/chart-xlsx-write-validation.ts
93927
+ function unsupported(reason) {
93928
+ throw new Error(`Chart label replacement requires direct literal workbook cells: ${reason}.`);
93929
+ }
93930
+ async function validateAtomicChartWorkbookWrites(zip, parser, paths, writes, requireCurrentValues = false) {
93931
+ const relationships2 = xmlChild(
93932
+ parser.parse(
93933
+ await zip.file("xl/_rels/workbook.xml.rels")?.async("string") ?? ""
93934
+ ),
93935
+ "Relationships"
93936
+ );
93937
+ for (const rel of xmlChildren(relationships2, "Relationship")) {
93938
+ if (xmlAttr(rel, "TargetMode") === "External") {
93939
+ unsupported("external worksheet relationships are not supported");
93940
+ }
93941
+ }
93942
+ const sheets = /* @__PURE__ */ new Map();
93943
+ const cellsByPath = /* @__PURE__ */ new Map();
93944
+ for (const path2 of new Set(paths.values())) {
93945
+ const file = zip.file(path2);
93946
+ if (!file) {
93947
+ unsupported("a referenced worksheet is missing");
93948
+ }
93949
+ let tree;
93950
+ try {
93951
+ tree = parser.parse(await file.async("string"));
93952
+ } catch {
93953
+ unsupported("a worksheet cannot be parsed");
93954
+ }
93955
+ const data = xmlChild(xmlChild(tree, "worksheet"), "sheetData");
93956
+ if (!data) {
93957
+ unsupported("a worksheet has no cell data");
93958
+ }
93959
+ if (Object.keys(data).some((key2) => key2.includes(":"))) {
93960
+ unsupported("prefixed worksheet cell nodes are not supported");
93961
+ }
93962
+ const cells2 = /* @__PURE__ */ new Map();
93963
+ for (const row of xmlChildren(data, "row")) {
93964
+ if (Object.keys(row).some((key2) => key2.includes(":"))) {
93965
+ unsupported("prefixed worksheet cell nodes are not supported");
93966
+ }
93967
+ for (const cell of xmlChildren(row, "c")) {
93968
+ const ref = xmlAttr(cell, "r");
93969
+ if (!ref || cells2.has(ref)) {
93970
+ unsupported("duplicate or unidentified worksheet cells are not supported");
93971
+ }
93972
+ cells2.set(ref, cell);
93973
+ if (Object.keys(cell).some((key2) => key2 === "f" || key2.endsWith(":f"))) {
93974
+ unsupported("formula-dependent workbooks are not supported");
93975
+ }
93976
+ }
93977
+ }
93978
+ sheets.set(path2, data);
93979
+ cellsByPath.set(path2, cells2);
93980
+ }
93981
+ const sharedFile = zip.file("xl/sharedStrings.xml");
93982
+ const shared = sharedFile ? xmlChildren(
93983
+ xmlChild(parser.parse(await sharedFile.async("string")), "sst"),
93984
+ "si"
93985
+ ) : [];
93986
+ const destinations = /* @__PURE__ */ new Map();
93987
+ for (const write of writes) {
93988
+ const range = parseChartFormulaRange(write.formula);
93989
+ if (!range || /[\[\]:!]/u.test(range.sheetName)) {
93990
+ unsupported("a range is not a direct local reference");
93991
+ }
93992
+ if ([range.start, range.end].some(
93993
+ (cell) => cell.row < 0 || cell.row >= 1048576 || cell.col < 0 || cell.col >= 16384
93994
+ )) {
93995
+ unsupported("a source cell lies outside the worksheet limits");
93996
+ }
93997
+ const addresses = expandRangeAddresses(range, write.values.length);
93998
+ const path2 = paths.get(range.sheetName.toLowerCase());
93999
+ const data = path2 ? sheets.get(path2) : void 0;
94000
+ if (!addresses || !path2 || !data) {
94001
+ unsupported("a source range cannot be resolved");
94002
+ }
94003
+ for (const [index, address] of addresses.entries()) {
94004
+ const value = write.values[index];
94005
+ const key2 = `${path2}!${address}`;
94006
+ const prior = destinations.get(key2);
94007
+ if (prior && (prior.value !== value || prior.numeric !== write.isNumeric)) {
94008
+ unsupported("overlapping source ranges request conflicting values");
94009
+ }
94010
+ destinations.set(key2, { value, numeric: write.isNumeric });
94011
+ const cell = cellsByPath.get(path2)?.get(address);
94012
+ if (!cell) {
94013
+ unsupported("a source cell is missing");
94014
+ }
94015
+ const type = xmlAttr(cell, "t") ?? "n";
94016
+ const text2 = type === "s" ? shared[Number(xmlText(cell.v))] : xmlChild(cell, "is");
94017
+ if (text2 && Object.keys(text2).some((node) => !node.startsWith("@_") && node !== "t" && node !== "#text")) {
94018
+ unsupported("rich worksheet strings require source-workbook editing");
94019
+ }
94020
+ if (requireCurrentValues) {
94021
+ const current = text2 ? xmlText(text2.t) : xmlText(cell.v);
94022
+ const equal = write.isNumeric ? current !== void 0 && Number(current) === Number(value) : current === value;
94023
+ if (!equal) {
94024
+ unsupported("the workbook and chart caches disagree");
94025
+ }
94026
+ }
94027
+ if (write.isNumeric && !Number.isFinite(Number(value))) {
94028
+ unsupported("a numeric cache value is not finite");
94029
+ }
94030
+ if (!["n", "s", "inlineStr", "str"].includes(type)) {
94031
+ unsupported("a source cell has an unsupported value type");
94032
+ }
94033
+ }
94034
+ }
94035
+ }
94036
+ var init_chart_xlsx_write_validation = __esm({
94037
+ "pptx/core/utils/chart-xlsx-write-validation.ts"() {
94038
+ init_chart_xlsx_cellref();
94039
+ init_xml_access();
94040
+ }
94041
+ });
94042
+ function collectChartWorkbookWrite(xmlLookupService, container2, isNumeric2, values) {
94043
+ if (!container2) {
94044
+ return void 0;
94045
+ }
94046
+ const refNode = xmlLookupService.getChildByLocalName(container2, isNumeric2 ? "numRef" : "strRef");
94047
+ const formula = refNode ? xmlLookupService.getScalarChildByLocalName(refNode, "f") : void 0;
94048
+ return formula ? { formula, isNumeric: isNumeric2, values } : void 0;
94049
+ }
94050
+ function createSpreadsheetXmlParser2() {
94051
+ return new fastXmlParser.XMLParser({
94052
+ ignoreAttributes: false,
94053
+ attributeNamePrefix: "@_",
94054
+ trimValues: false,
94055
+ parseTagValue: false,
94056
+ tagValueProcessor: (tagName, tagValue) => preservesSpreadsheetXmlWhitespace(tagName) ? tagValue : tagValue.trim()
94057
+ });
94058
+ }
94059
+ function createSpreadsheetXmlBuilder2() {
94060
+ return new fastXmlParser.XMLBuilder({
94061
+ ignoreAttributes: false,
94062
+ attributeNamePrefix: "@_",
94063
+ suppressBooleanAttributes: false,
94064
+ format: false
94065
+ });
94066
+ }
94067
+ async function resolveWorksheetPathsByName(xlsxZip, parser) {
94068
+ const result = /* @__PURE__ */ new Map();
94069
+ const workbookFile = xlsxZip.file("xl/workbook.xml");
94070
+ const relsFile = xlsxZip.file("xl/_rels/workbook.xml.rels");
94071
+ if (!workbookFile || !relsFile) {
94072
+ return result;
94073
+ }
94074
+ try {
94075
+ const workbookTree = parser.parse(await workbookFile.async("string"));
94076
+ const relsTree = parser.parse(await relsFile.async("string"));
94077
+ const targetByRelId = /* @__PURE__ */ new Map();
94078
+ const relationships2 = xmlChild(relsTree, "Relationships");
94079
+ for (const rel of xmlChildren(relationships2, "Relationship")) {
94080
+ const id = xmlAttr(rel, "Id");
94081
+ const target = xmlAttr(rel, "Target");
94082
+ if (id && target) {
94083
+ targetByRelId.set(id, target);
94084
+ }
94085
+ }
94086
+ const workbookRoot = xmlChild(workbookTree, "workbook");
94087
+ const sheets = xmlChild(workbookRoot, "sheets");
94088
+ for (const sheet of xmlChildren(sheets, "sheet")) {
94089
+ const name = xmlAttr(sheet, "name");
94090
+ const relId = xmlAttr(sheet, "r:id") ?? xmlAttr(sheet, "id");
94091
+ const target = relId ? targetByRelId.get(relId) : void 0;
94092
+ if (name && target) {
94093
+ result.set(name.toLowerCase(), resolveWorkbookPartPath(target));
94094
+ }
94095
+ }
94096
+ } catch {
94097
+ }
94098
+ return result;
94099
+ }
94100
+ function resolveWorkbookPartPath(target) {
94101
+ return target.startsWith("/") ? target.slice(1) : `xl/${target}`;
94102
+ }
94103
+ async function writeChartWorkbookUpdates(xlsxBytes, writes, options = {}) {
94104
+ if (writes.length === 0) {
94105
+ return { unresolved: 0 };
94106
+ }
94107
+ let xlsxZip;
94108
+ try {
94109
+ xlsxZip = await JSZip3__default.default.loadAsync(xlsxBytes);
94110
+ } catch {
94111
+ if (options.atomic) {
94112
+ throw new Error("Chart label replacement requires a readable embedded workbook.");
94113
+ }
94114
+ return { unresolved: writes.length };
94115
+ }
94116
+ const parser = createSpreadsheetXmlParser2();
94117
+ const sheetPathByName = await resolveWorksheetPathsByName(xlsxZip, parser);
94118
+ if (options.atomic) {
94119
+ await validateAtomicChartWorkbookWrites(
94120
+ xlsxZip,
94121
+ parser,
94122
+ sheetPathByName,
94123
+ writes,
94124
+ options.requireCurrentValues ?? false
94125
+ );
94126
+ }
94127
+ const writesBySheetPath = /* @__PURE__ */ new Map();
94128
+ let unresolved = 0;
94129
+ for (const write of writes) {
94130
+ const range = parseChartFormulaRange(write.formula);
94131
+ const sheetPath = range ? sheetPathByName.get(range.sheetName.toLowerCase()) : void 0;
94132
+ const refs = range ? expandRangeAddresses(range, write.values.length) : void 0;
94133
+ if (!range || !sheetPath || !refs) {
94134
+ unresolved += 1;
94135
+ continue;
94136
+ }
94137
+ const bucket = writesBySheetPath.get(sheetPath) ?? [];
94138
+ bucket.push({ refs, values: write.values, isNumeric: write.isNumeric });
94139
+ writesBySheetPath.set(sheetPath, bucket);
94140
+ }
94141
+ const builder3 = createSpreadsheetXmlBuilder2();
94142
+ let changedAny = false;
94143
+ for (const [sheetPath, resolvedWrites] of writesBySheetPath) {
94144
+ const sheetFile = xlsxZip.file(sheetPath);
94145
+ if (!sheetFile) {
94146
+ unresolved += resolvedWrites.length;
94147
+ continue;
94148
+ }
94149
+ try {
94150
+ const sheetTree = parser.parse(await sheetFile.async("string"));
94151
+ const cellWrites = resolvedWrites.flatMap(
94152
+ ({ refs, values, isNumeric: isNumeric2 }) => refs.map((ref, i2) => ({ ref, isNumeric: isNumeric2, value: values[i2] }))
94153
+ );
94154
+ if (applyCellWritesToWorksheet(sheetTree, cellWrites)) {
94155
+ xlsxZip.file(sheetPath, builder3.build(sheetTree));
94156
+ changedAny = true;
94157
+ }
94158
+ } catch {
94159
+ unresolved += resolvedWrites.length;
94160
+ }
94161
+ }
94162
+ if (options.atomic && unresolved > 0) {
94163
+ throw new Error("Chart label replacement could not update every source range.");
94164
+ }
94165
+ if (!changedAny) {
94166
+ return { unresolved };
94167
+ }
94168
+ const bytes = await xlsxZip.generateAsync({
94169
+ type: "uint8array",
94170
+ compression: "DEFLATE",
94171
+ compressionOptions: { level: 6 }
94172
+ });
94173
+ return { bytes, unresolved };
94174
+ }
94175
+ var init_chart_xlsx_writer = __esm({
94176
+ "pptx/core/utils/chart-xlsx-writer.ts"() {
94177
+ init_chart_xlsx_cellref();
94178
+ init_chart_xlsx_write_validation();
94179
+ init_chart_xlsx_sheet_cells();
94180
+ init_xml_access();
94181
+ init_xml_whitespace();
94182
+ }
94183
+ });
94184
+ function formulaCount(value) {
94185
+ if (!value || typeof value !== "object") return 0;
94186
+ if (Array.isArray(value)) return value.reduce((total, item) => total + formulaCount(item), 0);
94187
+ return Object.entries(value).reduce(
94188
+ (total, [key2, child30]) => total + (key2 === "f" || key2.endsWith(":f") ? 1 : formulaCount(child30)),
94189
+ 0
94190
+ );
94191
+ }
94192
+ async function chartLabelsHaveEditableSources(xml, zip, chartSpace, seriesNodes, series, categories, external, chartPartPath, resolve) {
94193
+ if (!chartSpace || seriesNodes.length !== series.length || !categories.length || external?.isExternal)
94194
+ return false;
94195
+ if (formulaCount(chartSpace) !== seriesNodes.reduce((sum, node) => sum + formulaCount(node), 0))
94196
+ return false;
94197
+ const writes = [];
94198
+ const labelOwners = /* @__PURE__ */ new Map();
94199
+ for (const [index, node] of seriesNodes.entries()) {
94200
+ const entry2 = series[index];
94201
+ for (const [name, numeric, values] of [
94202
+ ["tx", false, [entry2.name]],
94203
+ ["cat", false, [...categories]],
94204
+ ["val", true, entry2.values.map(String)]
94205
+ ]) {
94206
+ const container2 = xml.getChildByLocalName(node, name);
94207
+ if (!container2) return false;
94208
+ const write = collectChartWorkbookWrite(xml, container2, numeric, [...values]);
94209
+ if (write) {
94210
+ writes.push(write);
94211
+ if (!numeric) {
94212
+ const range = parseChartFormulaRange(write.formula);
94213
+ const addresses = range ? expandRangeAddresses(range, values.length) : void 0;
94214
+ if (!range || !addresses) return false;
94215
+ for (const [point2, address] of addresses.entries()) {
94216
+ const key2 = `${range.sheetName.toLowerCase()}!${address}`;
94217
+ const owner = name === "tx" ? `series:${index}` : `category:${point2}`;
94218
+ if (labelOwners.has(key2) && labelOwners.get(key2) !== owner) return false;
94219
+ labelOwners.set(key2, owner);
94220
+ }
94221
+ }
94222
+ } else if (external || !xml.getChildByLocalName(container2, numeric ? "numLit" : "strLit") && !(name === "tx" && xml.getScalarChildByLocalName(container2, "v") !== void 0))
94223
+ return false;
94224
+ }
94225
+ }
94226
+ if (formulaCount(chartSpace) !== writes.length) return false;
94227
+ if (!external) return writes.length === 0;
94228
+ if (!external.targetPath || !external.embeddedWorkbookData) return false;
94229
+ const target = resolve(chartPartPath, external.targetPath);
94230
+ let references = 0;
94231
+ const parser = new fastXmlParser.XMLParser({ ignoreAttributes: false, attributeNamePrefix: "@_" });
94232
+ try {
94233
+ for (const path2 of Object.keys(zip.files)) {
94234
+ if (!path2.endsWith(".rels") || !path2.includes("/_rels/")) continue;
94235
+ const source = path2.replace("/_rels/", "/").slice(0, -5);
94236
+ const tree = parser.parse(await zip.file(path2).async("string"));
94237
+ for (const rel of xmlChildren(xmlChild(tree, "Relationships"), "Relationship")) {
94238
+ const relationshipTarget2 = xmlAttr(rel, "Target");
94239
+ if (relationshipTarget2 && xmlAttr(rel, "TargetMode") !== "External" && resolve(source, relationshipTarget2) === target)
94240
+ references++;
94241
+ }
94242
+ }
94243
+ if (references !== 1) return false;
94244
+ await writeChartWorkbookUpdates(external.embeddedWorkbookData, writes, {
94245
+ atomic: true,
94246
+ requireCurrentValues: true
94247
+ });
94248
+ return true;
94249
+ } catch {
94250
+ return false;
94251
+ }
94252
+ }
94253
+ var init_chart_label_source = __esm({
94254
+ "pptx/core/utils/chart-label-source.ts"() {
94255
+ init_chart_xlsx_writer();
94256
+ init_xml_access();
94257
+ init_chart_xlsx_cellref();
94258
+ }
94259
+ });
94260
+
93672
94261
  // pptx/core/utils/chart-band-fmts.ts
93673
94262
  function safeUnsignedInt2(val) {
93674
94263
  const n = Number(val);
@@ -107769,6 +108358,18 @@ var init_tag_package = __esm({
107769
108358
  }
107770
108359
  });
107771
108360
 
108361
+ // pptx/core/utils/chart-workbook-data-signature.ts
108362
+ function chartWorkbookDataSignature(data) {
108363
+ return JSON.stringify({
108364
+ categories: data.dateCategories?.values ?? data.categories,
108365
+ series: data.series.map((series) => ({ name: series.name, values: series.values }))
108366
+ });
108367
+ }
108368
+ var init_chart_workbook_data_signature = __esm({
108369
+ "pptx/core/utils/chart-workbook-data-signature.ts"() {
108370
+ }
108371
+ });
108372
+
107772
108373
  // pptx/core/utils/chart-axis-deleted.ts
107773
108374
  function authoredDeleted(node) {
107774
108375
  if (node === void 0) {
@@ -107937,8 +108538,8 @@ function buildDefRPr(style, existing, resolveColor2) {
107937
108538
  return rPr;
107938
108539
  }
107939
108540
  function applyChartAxisTitleStyleToXml(axisNode, style, getLocalName2, resolveColor2) {
107940
- const hasAny = style.fontFamily !== void 0 || style.fontSize !== void 0 || style.fontBold !== void 0 || style.fontColor !== void 0;
107941
- if (!hasAny) {
108541
+ const hasAny2 = style.fontFamily !== void 0 || style.fontSize !== void 0 || style.fontBold !== void 0 || style.fontColor !== void 0;
108542
+ if (!hasAny2) {
107942
108543
  return;
107943
108544
  }
107944
108545
  const titleKey = findKey7(axisNode, "title", getLocalName2);
@@ -108856,6 +109457,33 @@ var init_chart_title_run_alignment = __esm({
108856
109457
  }
108857
109458
  });
108858
109459
 
109460
+ // pptx/core/utils/chart-title-text-edit.ts
109461
+ function patchChartTitleRunText(title, runs, local) {
109462
+ const tx = title[findKey7(title, "tx", local) ?? ""];
109463
+ const rich = tx?.[findKey7(tx, "rich", local) ?? ""];
109464
+ const raw = rich?.[findKey7(rich, "p", local) ?? ""];
109465
+ const paragraphs = Array.isArray(raw) ? raw : raw ? [raw] : [];
109466
+ if (paragraphs.length !== 1) return false;
109467
+ const paragraph = paragraphs[0];
109468
+ if (findKey7(paragraph, "br", local) || findKey7(paragraph, "fld", local)) return false;
109469
+ const rawRuns = paragraph[findKey7(paragraph, "r", local) ?? ""];
109470
+ const original = Array.isArray(rawRuns) ? rawRuns : rawRuns ? [rawRuns] : [];
109471
+ if (original.length !== runs.length) return false;
109472
+ const keys = original.map((run) => findKey7(run, "t", local));
109473
+ if (keys.some((key2) => !key2)) return false;
109474
+ for (const [index, value] of original.entries()) {
109475
+ const run = value, key2 = keys[index];
109476
+ const text2 = run[key2];
109477
+ run[key2] = text2 && typeof text2 === "object" && !Array.isArray(text2) ? { ...text2, "#text": runs[index].text } : runs[index].text;
109478
+ }
109479
+ return true;
109480
+ }
109481
+ var init_chart_title_text_edit = __esm({
109482
+ "pptx/core/utils/chart-title-text-edit.ts"() {
109483
+ init_chart_title_xml_ops();
109484
+ }
109485
+ });
109486
+
108859
109487
  // pptx/core/utils/chart-title-serializer.ts
108860
109488
  function applyChartTitleToXml(chartRoot, model, getLocalName2, options = { prefix: "c" }) {
108861
109489
  const { prefix } = options;
@@ -108881,11 +109509,18 @@ function applyChartTitleToXml(chartRoot, model, getLocalName2, options = { prefi
108881
109509
  runs = realignOrCollapseTitleRuns(staleRuns, model.title);
108882
109510
  }
108883
109511
  let titleNode = existingKey ? chartRoot[existingKey] : void 0;
109512
+ const textOnlyStylesMatch = Boolean(
109513
+ runs && model.titleTextOnlyStyles?.length === runs.length && runs.every(
109514
+ (run, index) => ["bold", "italic", "fontSize", "color"].every(
109515
+ (key2) => run[key2] === model.titleTextOnlyStyles[index][key2]
109516
+ )
109517
+ )
109518
+ );
108884
109519
  if (runs && titleNode && typeof titleNode === "object") {
108885
109520
  const existingTexts = [];
108886
109521
  collectAllText(titleNode, getLocalName2, existingTexts);
108887
109522
  const newTexts = runs.map((run) => run.text);
108888
- if (existingTexts.length === newTexts.length && existingTexts.every((text2, index) => text2 === newTexts[index])) {
109523
+ if ((!model.titleTextOnly || textOnlyStylesMatch) && existingTexts.length === newTexts.length && existingTexts.every((text2, index) => text2 === newTexts[index])) {
108889
109524
  runs = void 0;
108890
109525
  }
108891
109526
  }
@@ -108897,6 +109532,12 @@ function applyChartTitleToXml(chartRoot, model, getLocalName2, options = { prefi
108897
109532
  insertAt2(chartRoot, 0, `${prefix}:title`, titleNode);
108898
109533
  }
108899
109534
  } else if (runs) {
109535
+ if (model.titleTextOnly && textOnlyStylesMatch) {
109536
+ if (!patchChartTitleRunText(titleNode, runs, getLocalName2))
109537
+ throw new Error("This chart title cannot be replaced without changing its text source");
109538
+ if (prefix === "c") setAutoTitleDeleted(chartRoot, false, getLocalName2);
109539
+ return true;
109540
+ }
108900
109541
  const txKey = findKey7(titleNode, "tx", getLocalName2);
108901
109542
  if (txKey) {
108902
109543
  titleNode[txKey] = buildTitleTextFromRuns(prefix, runs);
@@ -108920,6 +109561,7 @@ var init_chart_title_serializer = __esm({
108920
109561
  "pptx/core/utils/chart-title-serializer.ts"() {
108921
109562
  init_chart_title_node_builder();
108922
109563
  init_chart_title_run_alignment();
109564
+ init_chart_title_text_edit();
108923
109565
  init_chart_title_xml_ops();
108924
109566
  }
108925
109567
  });
@@ -109081,131 +109723,6 @@ var init_chart_title_style_serializer = __esm({
109081
109723
  };
109082
109724
  }
109083
109725
  });
109084
- function collectChartWorkbookWrite(xmlLookupService, container2, isNumeric2, values) {
109085
- if (!container2) {
109086
- return void 0;
109087
- }
109088
- const refNode = xmlLookupService.getChildByLocalName(container2, isNumeric2 ? "numRef" : "strRef");
109089
- const formula = refNode ? xmlLookupService.getScalarChildByLocalName(refNode, "f") : void 0;
109090
- return formula ? { formula, isNumeric: isNumeric2, values } : void 0;
109091
- }
109092
- function createSpreadsheetXmlParser2() {
109093
- return new fastXmlParser.XMLParser({
109094
- ignoreAttributes: false,
109095
- attributeNamePrefix: "@_",
109096
- trimValues: false,
109097
- tagValueProcessor: (tagName, tagValue) => preservesSpreadsheetXmlWhitespace(tagName) ? tagValue : tagValue.trim()
109098
- });
109099
- }
109100
- function createSpreadsheetXmlBuilder2() {
109101
- return new fastXmlParser.XMLBuilder({
109102
- ignoreAttributes: false,
109103
- attributeNamePrefix: "@_",
109104
- suppressBooleanAttributes: false,
109105
- format: false
109106
- });
109107
- }
109108
- async function resolveWorksheetPathsByName(xlsxZip, parser) {
109109
- const result = /* @__PURE__ */ new Map();
109110
- const workbookFile = xlsxZip.file("xl/workbook.xml");
109111
- const relsFile = xlsxZip.file("xl/_rels/workbook.xml.rels");
109112
- if (!workbookFile || !relsFile) {
109113
- return result;
109114
- }
109115
- try {
109116
- const workbookTree = parser.parse(await workbookFile.async("string"));
109117
- const relsTree = parser.parse(await relsFile.async("string"));
109118
- const targetByRelId = /* @__PURE__ */ new Map();
109119
- const relationships2 = xmlChild(relsTree, "Relationships");
109120
- for (const rel of xmlChildren(relationships2, "Relationship")) {
109121
- const id = xmlAttr(rel, "Id");
109122
- const target = xmlAttr(rel, "Target");
109123
- if (id && target) {
109124
- targetByRelId.set(id, target);
109125
- }
109126
- }
109127
- const workbookRoot = xmlChild(workbookTree, "workbook");
109128
- const sheets = xmlChild(workbookRoot, "sheets");
109129
- for (const sheet of xmlChildren(sheets, "sheet")) {
109130
- const name = xmlAttr(sheet, "name");
109131
- const relId = xmlAttr(sheet, "r:id") ?? xmlAttr(sheet, "id");
109132
- const target = relId ? targetByRelId.get(relId) : void 0;
109133
- if (name && target) {
109134
- result.set(name.toLowerCase(), resolveWorkbookPartPath(target));
109135
- }
109136
- }
109137
- } catch {
109138
- }
109139
- return result;
109140
- }
109141
- function resolveWorkbookPartPath(target) {
109142
- return target.startsWith("/") ? target.slice(1) : `xl/${target}`;
109143
- }
109144
- async function writeChartWorkbookUpdates(xlsxBytes, writes) {
109145
- if (writes.length === 0) {
109146
- return { unresolved: 0 };
109147
- }
109148
- let xlsxZip;
109149
- try {
109150
- xlsxZip = await JSZip3__default.default.loadAsync(xlsxBytes);
109151
- } catch {
109152
- return { unresolved: writes.length };
109153
- }
109154
- const parser = createSpreadsheetXmlParser2();
109155
- const sheetPathByName = await resolveWorksheetPathsByName(xlsxZip, parser);
109156
- const writesBySheetPath = /* @__PURE__ */ new Map();
109157
- let unresolved = 0;
109158
- for (const write of writes) {
109159
- const range = parseChartFormulaRange(write.formula);
109160
- const sheetPath = range ? sheetPathByName.get(range.sheetName.toLowerCase()) : void 0;
109161
- const refs = range ? expandRangeAddresses(range, write.values.length) : void 0;
109162
- if (!range || !sheetPath || !refs) {
109163
- unresolved += 1;
109164
- continue;
109165
- }
109166
- const bucket = writesBySheetPath.get(sheetPath) ?? [];
109167
- bucket.push({ refs, values: write.values, isNumeric: write.isNumeric });
109168
- writesBySheetPath.set(sheetPath, bucket);
109169
- }
109170
- const builder3 = createSpreadsheetXmlBuilder2();
109171
- let changedAny = false;
109172
- for (const [sheetPath, resolvedWrites] of writesBySheetPath) {
109173
- const sheetFile = xlsxZip.file(sheetPath);
109174
- if (!sheetFile) {
109175
- unresolved += resolvedWrites.length;
109176
- continue;
109177
- }
109178
- try {
109179
- const sheetTree = parser.parse(await sheetFile.async("string"));
109180
- const cellWrites = resolvedWrites.flatMap(
109181
- ({ refs, values, isNumeric: isNumeric2 }) => refs.map((ref, i2) => ({ ref, isNumeric: isNumeric2, value: values[i2] }))
109182
- );
109183
- if (applyCellWritesToWorksheet(sheetTree, cellWrites)) {
109184
- xlsxZip.file(sheetPath, builder3.build(sheetTree));
109185
- changedAny = true;
109186
- }
109187
- } catch {
109188
- unresolved += resolvedWrites.length;
109189
- }
109190
- }
109191
- if (!changedAny) {
109192
- return { unresolved };
109193
- }
109194
- const bytes = await xlsxZip.generateAsync({
109195
- type: "uint8array",
109196
- compression: "DEFLATE",
109197
- compressionOptions: { level: 6 }
109198
- });
109199
- return { bytes, unresolved };
109200
- }
109201
- var init_chart_xlsx_writer = __esm({
109202
- "pptx/core/utils/chart-xlsx-writer.ts"() {
109203
- init_chart_xlsx_cellref();
109204
- init_chart_xlsx_sheet_cells();
109205
- init_xml_access();
109206
- init_xml_whitespace();
109207
- }
109208
- });
109209
109726
 
109210
109727
  // pptx/core/core/runtime/chart-cx-update-data.ts
109211
109728
  function findKey31(node, localName28, getLocalName2) {
@@ -109541,13 +110058,19 @@ var init_chart_cx_update = __esm({
109541
110058
  });
109542
110059
 
109543
110060
  // pptx/core/core/runtime/chart-external-workbook-save.ts
109544
- async function saveChartExternalWorkbookUpdates(deps, chartPartPath, slidePath, externalData, writes) {
110061
+ async function saveChartExternalWorkbookUpdates(deps, chartPartPath, slidePath, externalData, writes, atomic = false) {
110062
+ if (atomic && externalData && (!externalData.targetPath || externalData.isExternal)) {
110063
+ throw new Error("Chart label replacement cannot update an external or missing workbook.");
110064
+ }
109545
110065
  if (writes.length === 0 || !externalData?.targetPath) {
109546
- return;
110066
+ return writes.length === 0;
109547
110067
  }
109548
110068
  const embeddingPath = deps.resolveImagePath(chartPartPath, externalData.targetPath);
109549
110069
  const looksEmbedded = embeddingPath.includes("embeddings/") && /\.xlsx$/iu.test(embeddingPath);
109550
- if (!looksEmbedded) {
110070
+ if (!looksEmbedded || externalData.isExternal) {
110071
+ if (atomic) {
110072
+ throw new Error("Chart label replacement requires an embedded .xlsx workbook.");
110073
+ }
109551
110074
  deps.reportWarning({
109552
110075
  code: "CHART_EXTERNAL_DATA_WRITEBACK_UNSUPPORTED",
109553
110076
  message: "Chart data changes were saved to the cached values only: the linked data source is external or not an embedded .xlsx workbook, so it was not updated.",
@@ -109556,10 +110079,13 @@ async function saveChartExternalWorkbookUpdates(deps, chartPartPath, slidePath,
109556
110079
  slideId: slidePath,
109557
110080
  xmlPath: chartPartPath
109558
110081
  });
109559
- return;
110082
+ return false;
109560
110083
  }
109561
110084
  const xlsxFile = deps.zip.file(embeddingPath);
109562
110085
  if (!xlsxFile) {
110086
+ if (atomic) {
110087
+ throw new Error("Chart label replacement workbook is missing.");
110088
+ }
109563
110089
  deps.reportWarning({
109564
110090
  code: "CHART_EMBEDDED_WORKBOOK_MISSING",
109565
110091
  message: "Chart data changes were saved to the cached values only: the referenced embedded workbook was not found in the package.",
@@ -109568,12 +110094,15 @@ async function saveChartExternalWorkbookUpdates(deps, chartPartPath, slidePath,
109568
110094
  slideId: slidePath,
109569
110095
  xmlPath: embeddingPath
109570
110096
  });
109571
- return;
110097
+ return false;
109572
110098
  }
109573
110099
  let xlsxBytes;
109574
110100
  try {
109575
110101
  xlsxBytes = await xlsxFile.async("uint8array");
109576
110102
  } catch {
110103
+ if (atomic) {
110104
+ throw new Error("Chart label replacement workbook cannot be read.");
110105
+ }
109577
110106
  deps.reportWarning({
109578
110107
  code: "CHART_EMBEDDED_WORKBOOK_UNREADABLE",
109579
110108
  message: "Chart data changes were saved to the cached values only: the referenced embedded workbook could not be read.",
@@ -109582,9 +110111,9 @@ async function saveChartExternalWorkbookUpdates(deps, chartPartPath, slidePath,
109582
110111
  slideId: slidePath,
109583
110112
  xmlPath: embeddingPath
109584
110113
  });
109585
- return;
110114
+ return false;
109586
110115
  }
109587
- const result = await writeChartWorkbookUpdates(xlsxBytes, writes);
110116
+ const result = await writeChartWorkbookUpdates(xlsxBytes, writes, { atomic });
109588
110117
  if (result.bytes) {
109589
110118
  deps.zip.file(embeddingPath, result.bytes);
109590
110119
  }
@@ -109598,6 +110127,7 @@ async function saveChartExternalWorkbookUpdates(deps, chartPartPath, slidePath,
109598
110127
  xmlPath: embeddingPath
109599
110128
  });
109600
110129
  }
110130
+ return result.unresolved === 0;
109601
110131
  }
109602
110132
  var init_chart_external_workbook_save = __esm({
109603
110133
  "pptx/core/core/runtime/chart-external-workbook-save.ts"() {
@@ -109863,8 +110393,8 @@ function applyRotationFlipToRawNode(node, rotation, flipH, flipV) {
109863
110393
  const spPrKey = findChildKey2(node, "spPr");
109864
110394
  const container2 = spPrKey ? node[spPrKey] ?? node : node;
109865
110395
  const xfrmKey = findChildKey2(container2, "xfrm");
109866
- const hasAny = Boolean(rotation) || Boolean(flipH) || Boolean(flipV);
109867
- if (!xfrmKey && !hasAny) {
110396
+ const hasAny2 = Boolean(rotation) || Boolean(flipH) || Boolean(flipV);
110397
+ if (!xfrmKey && !hasAny2) {
109868
110398
  return;
109869
110399
  }
109870
110400
  const xfrm = xfrmKey ? container2[xfrmKey] : {};
@@ -109899,24 +110429,24 @@ function hexVal(hex3) {
109899
110429
  }
109900
110430
  function buildRunProps(para) {
109901
110431
  const rPr = {};
109902
- let hasAny = false;
110432
+ let hasAny2 = false;
109903
110433
  if (para.fontSize !== void 0) {
109904
110434
  rPr["@_sz"] = String(Math.round(para.fontSize * 100));
109905
- hasAny = true;
110435
+ hasAny2 = true;
109906
110436
  }
109907
110437
  if (para.bold) {
109908
110438
  rPr["@_b"] = "1";
109909
- hasAny = true;
110439
+ hasAny2 = true;
109910
110440
  }
109911
110441
  if (para.italic) {
109912
110442
  rPr["@_i"] = "1";
109913
- hasAny = true;
110443
+ hasAny2 = true;
109914
110444
  }
109915
110445
  if (para.color) {
109916
110446
  rPr["a:solidFill"] = { "a:srgbClr": { "@_val": hexVal(para.color) } };
109917
- hasAny = true;
110447
+ hasAny2 = true;
109918
110448
  }
109919
- return hasAny ? rPr : void 0;
110449
+ return hasAny2 ? rPr : void 0;
109920
110450
  }
109921
110451
  function buildParagraphNode(para) {
109922
110452
  const node = {};
@@ -111959,7 +112489,7 @@ var init_blob_url_to_data_url = __esm({
111959
112489
 
111960
112490
  // pptx/core/core/runtime/image-a14-effects-model.ts
111961
112491
  function applyA14ExtensionToEffects(effects, a14) {
111962
- let hasAny = false;
112492
+ let hasAny2 = false;
111963
112493
  if (a14.artisticEffect !== void 0) {
111964
112494
  effects.artisticEffect = a14.artisticEffect;
111965
112495
  if (a14.originalImageRelId !== void 0) {
@@ -111971,15 +112501,15 @@ function applyA14ExtensionToEffects(effects, a14) {
111971
112501
  if (a14.artisticParams) {
111972
112502
  effects.artisticParams = a14.artisticParams;
111973
112503
  }
111974
- hasAny = true;
112504
+ hasAny2 = true;
111975
112505
  }
111976
112506
  if (a14.backgroundRemoval) {
111977
112507
  effects.backgroundRemoval = a14.backgroundRemoval;
111978
- hasAny = true;
112508
+ hasAny2 = true;
111979
112509
  }
111980
112510
  if (a14.originalImageRelId !== void 0) {
111981
112511
  effects.originalImageRelId = a14.originalImageRelId;
111982
- hasAny = true;
112512
+ hasAny2 = true;
111983
112513
  }
111984
112514
  const corrections = {};
111985
112515
  if (a14.sharpenSoften) {
@@ -112002,9 +112532,9 @@ function applyA14ExtensionToEffects(effects, a14) {
112002
112532
  if (a14.originalImageRelId !== void 0) {
112003
112533
  effects.prerenderedCorrections = corrections;
112004
112534
  }
112005
- hasAny = true;
112535
+ hasAny2 = true;
112006
112536
  }
112007
- return hasAny;
112537
+ return hasAny2;
112008
112538
  }
112009
112539
  var init_image_a14_effects_model = __esm({
112010
112540
  "pptx/core/core/runtime/image-a14-effects-model.ts"() {
@@ -113052,7 +113582,7 @@ var init_PptxHandlerRuntimeState = __esm({
113052
113582
  */
113053
113583
  savedSlideFingerprints = /* @__PURE__ */ new Map();
113054
113584
  /**
113055
- * `chartData` exactly as it stood right after `enrichChartData` parsed it,
113585
+ * `chartData` as parsed or last serialized into the current ZIP,
113056
113586
  * serialized to JSON and keyed by `chartPartPath`. The save pipeline used
113057
113587
  * to re-serialize EVERY chart part on any slide rewrite regardless of
113058
113588
  * whether the chart itself was touched, which materializes the load-time
@@ -113065,6 +113595,10 @@ var init_PptxHandlerRuntimeState = __esm({
113065
113595
  * untouched chart part pass through byte-for-byte instead.
113066
113596
  */
113067
113597
  chartDataBaselines = /* @__PURE__ */ new Map();
113598
+ /** Pending chart requests also retain warned workbook writes for later retry. */
113599
+ pendingChartUpdates;
113600
+ /** Last fully reconciled workbook data plus whether a write-back needs retry. */
113601
+ chartWorkbookDataBaselines = /* @__PURE__ */ new Map();
113068
113602
  /** Per-slide relationship maps: slide path -> (rId -> target path). */
113069
113603
  slideRelsMap = /* @__PURE__ */ new Map();
113070
113604
  /** Tracks relationship IDs with TargetMode="External" per slide/part path. */
@@ -114271,13 +114805,13 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114271
114805
  return null;
114272
114806
  }
114273
114807
  const effects = {};
114274
- let hasAny = false;
114808
+ let hasAny2 = false;
114275
114809
  const brightRaw = blip["@_bright"] ?? blip["@_brt"];
114276
114810
  if (brightRaw !== null) {
114277
114811
  const val = parseInt(String(brightRaw));
114278
114812
  if (Number.isFinite(val)) {
114279
114813
  effects.brightness = val / 1e3;
114280
- hasAny = true;
114814
+ hasAny2 = true;
114281
114815
  }
114282
114816
  }
114283
114817
  const contrastRaw = blip["@_contrast"] ?? blip["@_cont"];
@@ -114285,7 +114819,7 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114285
114819
  const val = parseInt(String(contrastRaw));
114286
114820
  if (Number.isFinite(val)) {
114287
114821
  effects.contrast = val / 1e3;
114288
- hasAny = true;
114822
+ hasAny2 = true;
114289
114823
  }
114290
114824
  }
114291
114825
  const colorEffects = parseImageColorEffects(
@@ -114295,12 +114829,12 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114295
114829
  );
114296
114830
  Object.assign(effects, colorEffects);
114297
114831
  if (Object.keys(colorEffects).length > 0) {
114298
- hasAny = true;
114832
+ hasAny2 = true;
114299
114833
  }
114300
114834
  const alphaEffects = parseImageAlphaEffects(blip, (node) => this.parseColor(node));
114301
114835
  Object.assign(effects, alphaEffects);
114302
114836
  if (Object.keys(alphaEffects).length > 0) {
114303
- hasAny = true;
114837
+ hasAny2 = true;
114304
114838
  }
114305
114839
  const lumNode = blip["a:lum"];
114306
114840
  if (lumNode) {
@@ -114320,7 +114854,7 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114320
114854
  }
114321
114855
  }
114322
114856
  effects.lum = lumEffect;
114323
- hasAny = true;
114857
+ hasAny2 = true;
114324
114858
  }
114325
114859
  const hslNode = blip["a:hsl"];
114326
114860
  if (hslNode) {
@@ -114347,7 +114881,7 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114347
114881
  }
114348
114882
  }
114349
114883
  effects.hsl = hslEffect;
114350
- hasAny = true;
114884
+ hasAny2 = true;
114351
114885
  }
114352
114886
  const tintNode = blip["a:tint"];
114353
114887
  if (tintNode) {
@@ -114367,7 +114901,7 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114367
114901
  }
114368
114902
  }
114369
114903
  effects.tint = tintEffect;
114370
- hasAny = true;
114904
+ hasAny2 = true;
114371
114905
  }
114372
114906
  const fillOverlay = blip["a:fillOverlay"];
114373
114907
  if (fillOverlay) {
@@ -114394,7 +114928,7 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114394
114928
  ...resolvedGradient ? { resolvedGradient } : {},
114395
114929
  ...resolvedPattern ? { resolvedPattern } : {}
114396
114930
  };
114397
- hasAny = true;
114931
+ hasAny2 = true;
114398
114932
  }
114399
114933
  const blurNode = blip["a:blur"];
114400
114934
  if (blurNode) {
@@ -114412,16 +114946,16 @@ var init_PptxHandlerRuntimeImageEffects = __esm({
114412
114946
  blurEffect.grow = s === "1" || s === "true";
114413
114947
  }
114414
114948
  effects.blur = blurEffect;
114415
- hasAny = true;
114949
+ hasAny2 = true;
114416
114950
  }
114417
114951
  const extLst = xmlChild(blip, "a:extLst");
114418
114952
  if (extLst) {
114419
114953
  const a14 = parseA14ImageExtension(this.ensureArray(extLst["a:ext"]));
114420
114954
  if (a14 && applyA14ExtensionToEffects(effects, a14)) {
114421
- hasAny = true;
114955
+ hasAny2 = true;
114422
114956
  }
114423
114957
  }
114424
- return hasAny ? effects : null;
114958
+ return hasAny2 ? effects : null;
114425
114959
  }
114426
114960
  /**
114427
114961
  * Resolve a blip `a:fillOverlay/a:gradFill` to the structured gradient a
@@ -116074,8 +116608,8 @@ function buildTextRunEffectListXml(style, parseColor) {
116074
116608
  const hasTextHsl = typeof style.textHslHue === "number" || typeof style.textHslSaturation === "number" || typeof style.textHslLuminance === "number";
116075
116609
  const hasTextClrChange = Boolean(style.textClrChangeFrom) && Boolean(style.textClrChangeTo);
116076
116610
  const hasTextDuotone = Boolean(style.textDuotone);
116077
- const hasAny = hasTextShadow || hasTextInnerShadow || hasTextPresetShadow || hasTextGlow || hasTextReflection || hasTextBlur || hasTextSoftEdge || hasTextAlphaModFix || hasTextAlphaMod || hasTextHsl || hasTextClrChange || hasTextDuotone;
116078
- if (!hasAny) {
116611
+ const hasAny2 = hasTextShadow || hasTextInnerShadow || hasTextPresetShadow || hasTextGlow || hasTextReflection || hasTextBlur || hasTextSoftEdge || hasTextAlphaModFix || hasTextAlphaMod || hasTextHsl || hasTextClrChange || hasTextDuotone;
116612
+ if (!hasAny2) {
116079
116613
  return void 0;
116080
116614
  }
116081
116615
  const effectLst = {};
@@ -120399,6 +120933,87 @@ var init_table_column_width_save = __esm({
120399
120933
  }
120400
120934
  });
120401
120935
 
120936
+ // pptx/core/core/runtime/table-style-change-cell-clear.ts
120937
+ function normaliseStyleId(id) {
120938
+ const text2 = typeof id === "string" || typeof id === "number" ? String(id) : "";
120939
+ const trimmed2 = text2.trim().toUpperCase();
120940
+ if (!trimmed2) {
120941
+ return "";
120942
+ }
120943
+ return trimmed2.startsWith("{") ? trimmed2 : `{${trimmed2}}`;
120944
+ }
120945
+ function xmlTableStyleId(tblPr) {
120946
+ if (!tblPr || typeof tblPr !== "object") {
120947
+ return "";
120948
+ }
120949
+ const props = tblPr;
120950
+ const node = props["a:tableStyleId"];
120951
+ const spec = normaliseStyleId(
120952
+ node && typeof node === "object" ? node["#text"] : node
120953
+ );
120954
+ if (spec) {
120955
+ return spec;
120956
+ }
120957
+ const legacy = props["a:tblStyle"];
120958
+ return normaliseStyleId(legacy?.["@_val"] || props["@_tblStyle"]);
120959
+ }
120960
+ function tableStyleIdChanged(tblPr, nextStyleId) {
120961
+ if (nextStyleId === void 0) {
120962
+ return false;
120963
+ }
120964
+ return normaliseStyleId(nextStyleId) !== xmlTableStyleId(tblPr);
120965
+ }
120966
+ function clearCellFormattingForStyleChange(xmlCell, style) {
120967
+ const tcPr = xmlCell["a:tcPr"];
120968
+ if (!tcPr || typeof tcPr !== "object") {
120969
+ return;
120970
+ }
120971
+ const props = tcPr;
120972
+ if (!hasAny(style, FILL_FIELDS)) {
120973
+ for (const key2 of FILL_KEYS) {
120974
+ delete props[key2];
120975
+ }
120976
+ }
120977
+ for (const [key2, fields] of LINE_KEYS) {
120978
+ if (!hasAny(style, fields)) {
120979
+ delete props[key2];
120980
+ }
120981
+ }
120982
+ if (!style?.cell3D) {
120983
+ delete props["a:cell3D"];
120984
+ }
120985
+ }
120986
+ var FILL_KEYS, LINE_KEYS, FILL_FIELDS, hasAny;
120987
+ var init_table_style_change_cell_clear = __esm({
120988
+ "pptx/core/core/runtime/table-style-change-cell-clear.ts"() {
120989
+ FILL_KEYS = [
120990
+ "a:noFill",
120991
+ "a:solidFill",
120992
+ "a:gradFill",
120993
+ "a:blipFill",
120994
+ "a:pattFill",
120995
+ "a:grpFill"
120996
+ ];
120997
+ LINE_KEYS = [
120998
+ ["a:lnL", ["borderLeftWidth", "borderLeftColor", "borderLeftDash"]],
120999
+ ["a:lnR", ["borderRightWidth", "borderRightColor", "borderRightDash"]],
121000
+ ["a:lnT", ["borderTopWidth", "borderTopColor", "borderTopDash"]],
121001
+ ["a:lnB", ["borderBottomWidth", "borderBottomColor", "borderBottomDash"]],
121002
+ ["a:lnTlToBr", ["borderDiagDownWidth", "borderDiagDownColor"]],
121003
+ ["a:lnBlToTr", ["borderDiagUpWidth", "borderDiagUpColor"]]
121004
+ ];
121005
+ FILL_FIELDS = [
121006
+ "fillMode",
121007
+ "backgroundColor",
121008
+ "gradientFillStops",
121009
+ "patternFillPreset",
121010
+ "backgroundImageFillPath",
121011
+ "backgroundImageFillData"
121012
+ ];
121013
+ hasAny = (style, keys) => keys.some((key2) => style?.[key2] !== void 0);
121014
+ }
121015
+ });
121016
+
120402
121017
  // pptx/core/core/runtime/table-paragraph-save-order.ts
120403
121018
  function runTag(run) {
120404
121019
  return run.isLineBreak ? "a:br" : run.isField ? "a:fld" : "a:r";
@@ -121073,6 +121688,7 @@ var init_table_tblpr_save = __esm({
121073
121688
  var CHART_DATA_DISPLAY_OPTIONS_EXT_URI, PptxHandlerRuntime24;
121074
121689
  var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121075
121690
  "pptx/core/core/runtime/PptxHandlerRuntimeSaveDataSerialization.ts"() {
121691
+ init_chart_workbook_data_signature();
121076
121692
  init_chart_axis_dispunits_serializer();
121077
121693
  init_chart_axis_gridlines_serializer();
121078
121694
  init_chart_axis_label_formatting();
@@ -121124,6 +121740,7 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121124
121740
  init_PptxHandlerRuntimeChartUserShapes();
121125
121741
  init_save_table_merge_helpers();
121126
121742
  init_table_column_width_save();
121743
+ init_table_style_change_cell_clear();
121127
121744
  init_table_paragraph_save_order();
121128
121745
  init_table_structural_ops();
121129
121746
  init_table_tblpr_save();
@@ -121145,6 +121762,7 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121145
121762
  if (!tbl) {
121146
121763
  return;
121147
121764
  }
121765
+ const styleChanged = tableData.clearDirectCellFormatting === true || tableStyleIdChanged(tbl["a:tblPr"], tableData.tableStyleId);
121148
121766
  serializeTablePropertyFlags(tbl, tableData);
121149
121767
  writeTablePropertiesOwnFillAndEffects(tbl["a:tblPr"], tableData);
121150
121768
  const xmlRows = this.ensureArray(tbl["a:tr"]);
@@ -121176,6 +121794,9 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121176
121794
  if (cell.text !== void 0) {
121177
121795
  this.writeTableCellText(xmlCell, cell.text);
121178
121796
  }
121797
+ if (styleChanged) {
121798
+ clearCellFormattingForStyleChange(xmlCell, cell.style);
121799
+ }
121179
121800
  if (cell.style) {
121180
121801
  this.writeTableCellStyle(xmlCell, cell.style, cell.paragraphs);
121181
121802
  }
@@ -121199,6 +121820,9 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121199
121820
  if (cell.text !== void 0) {
121200
121821
  this.writeTableCellText(xmlCell, cell.text);
121201
121822
  }
121823
+ if (styleChanged) {
121824
+ clearCellFormattingForStyleChange(xmlCell, cell.style);
121825
+ }
121202
121826
  if (cell.style) {
121203
121827
  this.writeTableCellStyle(xmlCell, cell.style, cell.paragraphs);
121204
121828
  }
@@ -121210,8 +121834,6 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121210
121834
  console.warn("Failed to serialize table data:", e);
121211
121835
  }
121212
121836
  }
121213
- /** Pending chart data updates to process in the async save method. */
121214
- pendingChartUpdates;
121215
121837
  /**
121216
121838
  * Record `chartData` as parsed, straight off `enrichChartData`, as this
121217
121839
  * chart's load-time baseline. See {@link chartDataBaselines}.
@@ -121221,6 +121843,10 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121221
121843
  return;
121222
121844
  }
121223
121845
  this.chartDataBaselines.set(chartData.chartPartPath, JSON.stringify(chartData));
121846
+ this.chartWorkbookDataBaselines.set(chartData.chartPartPath, {
121847
+ signature: chartWorkbookDataSignature(chartData),
121848
+ pending: false
121849
+ });
121224
121850
  }
121225
121851
  /**
121226
121852
  * Collect chart data for deferred async processing during save.
@@ -121237,12 +121863,28 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121237
121863
  /**
121238
121864
  * Process all pending chart data updates (called from the async save method).
121239
121865
  */
121240
- async processPendingChartUpdates() {
121866
+ async processPendingChartUpdates(slides) {
121241
121867
  if (!this.pendingChartUpdates || this.pendingChartUpdates.length === 0) {
121242
121868
  return;
121243
121869
  }
121870
+ if (slides) {
121871
+ const current = /* @__PURE__ */ new Map();
121872
+ const visit = (elements3, slidePath) => {
121873
+ for (const element of elements3) {
121874
+ if (element.type === "group") visit(element.children, slidePath);
121875
+ else if (element.type === "chart" && element.chartData?.chartPartPath) {
121876
+ current.set(element.chartData.chartPartPath, {
121877
+ chartData: element.chartData,
121878
+ slidePath
121879
+ });
121880
+ }
121881
+ }
121882
+ };
121883
+ for (const slide of slides) visit(slide.elements, slide.id);
121884
+ this.pendingChartUpdates = [...current.values()];
121885
+ }
121244
121886
  for (const { chartData, slidePath } of this.pendingChartUpdates) {
121245
- if (chartData.chartPartPath && this.chartDataBaselines.get(chartData.chartPartPath) === JSON.stringify(chartData)) {
121887
+ if (chartData.chartPartPath && !this.chartWorkbookDataBaselines.get(chartData.chartPartPath)?.pending && this.chartDataBaselines.get(chartData.chartPartPath) === JSON.stringify(chartData)) {
121246
121888
  continue;
121247
121889
  }
121248
121890
  if (chartData.colorPalette && chartData.colorStylePartPath) {
@@ -121661,7 +122303,9 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121661
122303
  {
121662
122304
  title: chartData.title,
121663
122305
  hasTitle: chartData.style?.hasTitle,
121664
- titleRuns: chartData.titleRuns
122306
+ titleRuns: chartData.titleRuns,
122307
+ titleTextOnly: chartData.titleTextOnly,
122308
+ titleTextOnlyStyles: chartData.titleTextOnlyStyles
121665
122309
  },
121666
122310
  (key2) => this.compatibilityService.getXmlLocalName(key2)
121667
122311
  );
@@ -121853,23 +122497,41 @@ var init_PptxHandlerRuntimeSaveDataSerialization = __esm({
121853
122497
  }
121854
122498
  }
121855
122499
  await this.syncChartUserShapesToXml(chartSpace, chartData, chartPartPath);
122500
+ const serializedBaseline = this.chartDataBaselines.get(chartPartPath);
122501
+ const signature = chartWorkbookDataSignature(chartData);
122502
+ const workbookBaseline = this.chartWorkbookDataBaselines.get(chartPartPath);
122503
+ const previousSignature = workbookBaseline?.signature ?? (serializedBaseline ? chartWorkbookDataSignature(JSON.parse(serializedBaseline)) : void 0);
122504
+ const workbookDataChanged = workbookBaseline?.pending || signature !== previousSignature;
122505
+ if (workbookDataChanged) {
122506
+ const complete = await saveChartExternalWorkbookUpdates(
122507
+ {
122508
+ zip: this.zip,
122509
+ resolveImagePath: (basePath, target) => this.resolveImagePath(basePath, target),
122510
+ reportWarning: (warning) => this.compatibilityService.reportWarning(warning)
122511
+ },
122512
+ chartPartPath,
122513
+ slidePath,
122514
+ chartData.externalData,
122515
+ workbookWrites,
122516
+ chartData.dataLabelTextOnly ?? false
122517
+ );
122518
+ this.chartWorkbookDataBaselines.set(chartPartPath, {
122519
+ signature: complete ? signature : previousSignature ?? signature,
122520
+ pending: !complete
122521
+ });
122522
+ }
121856
122523
  this.zip.file(chartPartPath, this.builder.build(chartXmlData));
121857
- await saveChartExternalWorkbookUpdates(
121858
- {
121859
- zip: this.zip,
121860
- resolveImagePath: (basePath, target) => this.resolveImagePath(basePath, target),
121861
- reportWarning: (warning) => this.compatibilityService.reportWarning(warning)
121862
- },
121863
- chartPartPath,
121864
- slidePath,
121865
- chartData.externalData,
121866
- workbookWrites
121867
- );
122524
+ this.chartDataBaselines.set(chartPartPath, JSON.stringify(chartData));
121868
122525
  } catch (e) {
122526
+ if (chartData.dataLabelTextOnly) {
122527
+ throw e;
122528
+ }
121869
122529
  console.warn(`[pptx-save] Failed to serialize chart data for ${chartPartPath}:`, e);
121870
122530
  }
121871
122531
  }
121872
- this.pendingChartUpdates = void 0;
122532
+ this.pendingChartUpdates = this.pendingChartUpdates.filter(
122533
+ ({ chartData }) => chartData.chartPartPath && this.chartWorkbookDataBaselines.get(chartData.chartPartPath)?.pending
122534
+ );
121873
122535
  }
121874
122536
  /**
121875
122537
  * Route a chart save that the 2006 `c:*Chart` update loop cannot handle:
@@ -130073,22 +130735,44 @@ function drawingNamespace(strict) {
130073
130735
  var NOTES_MASTER_CONTENT_TYPE, PptxHandlerRuntime50;
130074
130736
  var init_PptxHandlerRuntimeSaveNotesInfrastructure = __esm({
130075
130737
  "pptx/core/core/runtime/PptxHandlerRuntimeSaveNotesInfrastructure.ts"() {
130738
+ init_relationships();
130076
130739
  init_PptxHandlerRuntimeSaveViewProperties();
130077
130740
  NOTES_MASTER_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml";
130078
130741
  PptxHandlerRuntime50 = class extends PptxHandlerRuntime49 {
130079
130742
  /** Ensure authored notes have the global notes-master OPC infrastructure. */
130080
130743
  async ensureNotesMasterForAuthoredNotes(slides, constants) {
130081
130744
  const needsNotes = slides.some(
130082
- (slide) => slide.notes !== void 0 || Boolean(slide.notesSegments?.length)
130745
+ (slide) => Boolean(slide.notes) || Boolean(slide.notesSegments?.some((segment) => segment.text))
130083
130746
  );
130084
130747
  if (!needsNotes || Object.keys(this.zip.files).some(
130085
130748
  (path2) => /^ppt\/notesMasters\/notesMaster\d+\.xml$/u.test(path2)
130086
130749
  )) {
130087
130750
  return;
130088
130751
  }
130752
+ const relsPath2 = "ppt/_rels/presentation.xml.rels";
130753
+ const relsXml = await this.zip.file(relsPath2)?.async("string");
130754
+ if (!relsXml || !this.presentationData) return;
130755
+ if (Array.from(parseRelationships(relsXml).values()).some(
130756
+ (relationship) => relationship.type.endsWith("/notesMaster") && relationship.mode !== "External" && this.zip.file(resolvePartPath("ppt/presentation.xml", relationship.target))
130757
+ ))
130758
+ return;
130089
130759
  const strict = constants.conformance === "strict";
130090
130760
  const masterPath = "ppt/notesMasters/notesMaster1.xml";
130091
- const themePath = Object.keys(this.zip.files).find((path2) => /^ppt\/theme\/theme\d+\.xml$/u.test(path2)) ?? "ppt/theme/theme1.xml";
130761
+ const sourceThemePath = Object.keys(this.zip.files).find((path2) => /^ppt\/theme\/theme\d+\.xml$/u.test(path2)) ?? "ppt/theme/theme1.xml";
130762
+ let themeIndex = 1;
130763
+ while (this.zip.file(`ppt/theme/theme${themeIndex}.xml`)) themeIndex += 1;
130764
+ const themePath = `ppt/theme/theme${themeIndex}.xml`;
130765
+ const themeBytes = await this.zip.file(sourceThemePath)?.async("uint8array");
130766
+ const theme = themeBytes ?? this.buildThemeXml(themePath, void 0);
130767
+ if (!theme) throw new Error("Cannot create a notes theme from the presentation state");
130768
+ this.zip.file(themePath, theme);
130769
+ const themeRelationships = await this.zip.file(`ppt/theme/_rels/${sourceThemePath.slice(sourceThemePath.lastIndexOf("/") + 1)}.rels`)?.async("uint8array");
130770
+ if (themeRelationships)
130771
+ this.zip.file(`ppt/theme/_rels/theme${themeIndex}.xml.rels`, themeRelationships);
130772
+ await this.addContentTypeOverride(
130773
+ `/${themePath}`,
130774
+ "application/vnd.openxmlformats-officedocument.theme+xml"
130775
+ );
130092
130776
  this.zip.file(masterPath, this.builder.build(this.buildDefaultNotesMaster(strict)));
130093
130777
  this.zip.file(
130094
130778
  "ppt/notesMasters/_rels/notesMaster1.xml.rels",
@@ -130103,11 +130787,6 @@ var init_PptxHandlerRuntimeSaveNotesInfrastructure = __esm({
130103
130787
  }
130104
130788
  })
130105
130789
  );
130106
- const relsPath2 = "ppt/_rels/presentation.xml.rels";
130107
- const relsXml = await this.zip.file(relsPath2)?.async("string");
130108
- if (!relsXml || !this.presentationData) {
130109
- return;
130110
- }
130111
130790
  const relsData = this.parser.parse(relsXml);
130112
130791
  const relsRoot = relsData["Relationships"] ?? {};
130113
130792
  const relationships2 = asArray7(relsRoot["Relationship"]);
@@ -130842,7 +131521,7 @@ var init_PptxHandlerRuntimeSavePipeline = __esm({
130842
131521
  saveSession,
130843
131522
  saveConstants
130844
131523
  );
130845
- await this.processPendingChartUpdates();
131524
+ await this.processPendingChartUpdates(slides);
130846
131525
  await this.ensureChartPartContentTypes();
130847
131526
  await this.ensureOleEmbeddingContentTypes();
130848
131527
  await this.processPendingOleContentUpdates();
@@ -131818,6 +132497,7 @@ var PptxHandlerRuntime60;
131818
132497
  var init_PptxHandlerRuntimeGeometryParsing = __esm({
131819
132498
  "pptx/core/core/runtime/PptxHandlerRuntimeGeometryParsing.ts"() {
131820
132499
  init_color_primitives();
132500
+ init_custom_geometry_command_order();
131821
132501
  init_custom_geometry_parser();
131822
132502
  init_guide_formula();
131823
132503
  init_PptxHandlerRuntimePlaceholderLookup();
@@ -131979,6 +132659,10 @@ var init_PptxHandlerRuntimeGeometryParsing = __esm({
131979
132659
  const pathLst = custGeom["a:pathLst"];
131980
132660
  if (isNonEmpty(pathLst)) {
131981
132661
  result.pathLstXml = pathLst;
132662
+ const pathCommandOrder = readPathListCommandOrder(pathLst);
132663
+ if (pathCommandOrder) {
132664
+ result.pathCommandOrder = pathCommandOrder;
132665
+ }
131982
132666
  }
131983
132667
  return Object.keys(result).length > 0 ? result : void 0;
131984
132668
  }
@@ -132889,7 +133573,7 @@ var init_PptxHandlerRuntimeShapeBodyParsing = __esm({
132889
133573
  return void 0;
132890
133574
  }
132891
133575
  const locks = {};
132892
- let hasAny = false;
133576
+ let hasAny2 = false;
132893
133577
  const boolAttr2 = (attr6) => {
132894
133578
  const raw = spLocks[attr6];
132895
133579
  if (raw === void 0) {
@@ -132902,7 +133586,7 @@ var init_PptxHandlerRuntimeShapeBodyParsing = __esm({
132902
133586
  const val = boolAttr2(attr6);
132903
133587
  if (val !== void 0) {
132904
133588
  fn(val);
132905
- hasAny = true;
133589
+ hasAny2 = true;
132906
133590
  }
132907
133591
  };
132908
133592
  set2("@_noGrp", (v) => {
@@ -132941,7 +133625,7 @@ var init_PptxHandlerRuntimeShapeBodyParsing = __esm({
132941
133625
  set2("@_noCrop", (v) => {
132942
133626
  locks.noCrop = v;
132943
133627
  });
132944
- return hasAny ? locks : void 0;
133628
+ return hasAny2 ? locks : void 0;
132945
133629
  }
132946
133630
  /**
132947
133631
  * Parse the `@txBox` attribute from a `p:cNvSpPr` node. Returns `true` /
@@ -140853,6 +141537,7 @@ var init_PptxHandlerRuntimeChartExternalData = __esm({
140853
141537
  );
140854
141538
  const autoUpdateAttr = externalDataNode["@_autoUpdate"];
140855
141539
  const autoUpdate = autoUpdateNode?.["@_val"] === "1" || autoUpdateNode?.["@_val"] === "true" || autoUpdateAttr === "1" || autoUpdateAttr === "true" || false;
141540
+ let isExternal = false;
140856
141541
  let targetPath;
140857
141542
  try {
140858
141543
  const chartDir = chartPartPath.substring(0, chartPartPath.lastIndexOf("/") + 1);
@@ -140867,6 +141552,7 @@ var init_PptxHandlerRuntimeChartExternalData = __esm({
140867
141552
  for (const rel of rels) {
140868
141553
  if (String(rel?.["@_Id"] || "") === relId) {
140869
141554
  targetPath = String(rel?.["@_Target"] || "").trim() || void 0;
141555
+ isExternal = String(rel?.["@_TargetMode"] || "") === "External";
140870
141556
  break;
140871
141557
  }
140872
141558
  }
@@ -140875,7 +141561,7 @@ var init_PptxHandlerRuntimeChartExternalData = __esm({
140875
141561
  } catch {
140876
141562
  }
140877
141563
  let embeddedWorkbookData;
140878
- if (targetPath) {
141564
+ if (targetPath && !isExternal) {
140879
141565
  try {
140880
141566
  const embeddingPath = this.resolveImagePath(chartPartPath, targetPath);
140881
141567
  if (embeddingPath.includes("embeddings/") && embeddingPath.endsWith(".xlsx")) {
@@ -140889,6 +141575,7 @@ var init_PptxHandlerRuntimeChartExternalData = __esm({
140889
141575
  }
140890
141576
  return {
140891
141577
  relId,
141578
+ ...isExternal ? { isExternal: true } : {},
140892
141579
  targetPath,
140893
141580
  autoUpdate,
140894
141581
  ...embeddedWorkbookData ? { embeddedWorkbookData } : {}
@@ -141259,6 +141946,8 @@ var init_PptxHandlerRuntimeChartExParsing = __esm({
141259
141946
  ...result.categoryLevels ? { categoryLevels: result.categoryLevels } : {},
141260
141947
  series: result.series,
141261
141948
  title: cxTitleText,
141949
+ titleTextEditable: false,
141950
+ dataLabelTextEditable: false,
141262
141951
  style: chartStyle2,
141263
141952
  chartPartPath,
141264
141953
  chartRelationshipId,
@@ -141282,6 +141971,7 @@ var init_PptxHandlerRuntimeChartExParsing = __esm({
141282
141971
  var PptxHandlerRuntime95;
141283
141972
  var init_PptxHandlerRuntimeChartParsing = __esm({
141284
141973
  "pptx/core/core/runtime/PptxHandlerRuntimeChartParsing.ts"() {
141974
+ init_chart_label_source();
141285
141975
  init_chart_advanced_parser();
141286
141976
  init_chart_axis_parser();
141287
141977
  init_chart_band_fmts();
@@ -141472,12 +142162,34 @@ var init_PptxHandlerRuntimeChartParsing = __esm({
141472
142162
  colorAdapter
141473
142163
  );
141474
142164
  const style = chartStyleFromNeutral(neutral, this.extractChartStyle(chartSpace, chartRoot));
142165
+ const titleTx = reader2.xml.getChildByLocalName(
142166
+ reader2.xml.getChildByLocalName(chartRoot, "title"),
142167
+ "tx"
142168
+ );
142169
+ const titleRich = reader2.xml.getChildByLocalName(titleTx, "rich");
142170
+ const titleParagraphs = reader2.xml.getChildrenArrayByLocalName(titleRich, "p");
142171
+ const titleTextEditable = Boolean(
142172
+ titleRuns?.length && titleParagraphs.length === 1 && !Object.keys(titleParagraphs[0] ?? {}).some(
142173
+ (key2) => ["br", "fld"].includes(reader2.localName(key2))
142174
+ )
142175
+ );
141475
142176
  const groupOptions = groupOptionsFromNeutral(groups[0]?.group, chartType);
141476
142177
  const linesAndChrome = this.readChartLinesAndChrome(neutral, tree, groups, reader2);
141477
142178
  const facts = await this.readChartPartFacts(chartSpace, chartRoot, chartPartPath);
141478
142179
  const workbook = facts.embeddedWorkbookData;
141479
142180
  const dateCategories = rawDateCategories ? { ...rawDateCategories, date1904: neutral.date1904 ?? workbook?.date1904 ?? false } : void 0;
141480
142181
  const filled = applyEmbeddedWorkbookFallback(chartType, categories, built.series, workbook);
142182
+ const dataLabelTextEditable = !categoryLevels && !dateCategories && await chartLabelsHaveEditableSources(
142183
+ reader2.xml,
142184
+ this.zip,
142185
+ chartSpace,
142186
+ built.seriesNodes,
142187
+ filled.series,
142188
+ filled.categories,
142189
+ facts.externalData,
142190
+ chartPartPath,
142191
+ this.resolveImagePath.bind(this)
142192
+ );
141481
142193
  const hasPicture = filled.series.some(
141482
142194
  (entry2) => entry2.picture || entry2.impliedPicture || entry2.dataPoints?.some((point2) => point2.picture || point2.impliedPicture)
141483
142195
  );
@@ -141510,6 +142222,14 @@ var init_PptxHandlerRuntimeChartParsing = __esm({
141510
142222
  ...built.filtered,
141511
142223
  title: neutralTitleText(neutral.title),
141512
142224
  ...titleRuns ? { titleRuns } : {},
142225
+ titleTextEditable,
142226
+ dataLabelTextEditable,
142227
+ ...dataLabelTextEditable ? {
142228
+ dataLabelSourceShape: {
142229
+ categoryCount: filled.categories.length,
142230
+ seriesValueCounts: filled.series.map((series) => series.values.length)
142231
+ }
142232
+ } : {},
141513
142233
  style,
141514
142234
  grouping: groupOptions.grouping,
141515
142235
  ...groupOptions,
@@ -141533,13 +142253,15 @@ var init_PptxHandlerRuntimeChartParsing = __esm({
141533
142253
  });
141534
142254
 
141535
142255
  // pptx/core/core/runtime/PptxHandlerRuntimePresentationStructure.ts
141536
- var PptxHandlerRuntime96;
142256
+ var XSD_INT_MIN, XSD_INT_MAX, PptxHandlerRuntime96;
141537
142257
  var init_PptxHandlerRuntimePresentationStructure = __esm({
141538
142258
  "pptx/core/core/runtime/PptxHandlerRuntimePresentationStructure.ts"() {
141539
142259
  init_kinsoku_parser();
141540
142260
  init_presentation_section_parser();
141541
142261
  init_header_footer_parts();
141542
142262
  init_PptxHandlerRuntimeChartParsing();
142263
+ XSD_INT_MIN = -2147483648;
142264
+ XSD_INT_MAX = 2147483647;
141543
142265
  PptxHandlerRuntime96 = class extends PptxHandlerRuntime95 {
141544
142266
  parseEditorAnimations(slideXml3) {
141545
142267
  return this.editorAnimationService.parseEditorAnimations(slideXml3);
@@ -141722,6 +142444,22 @@ var init_PptxHandlerRuntimePresentationStructure = __esm({
141722
142444
  const lexical = String(raw).trim().toLowerCase();
141723
142445
  return lexical !== "0" && lexical !== "false";
141724
142446
  }
142447
+ /**
142448
+ * Extract `p:presentation/@firstSlideNum` (ECMA-376 §19.2.1.26, an
142449
+ * `xsd:int`). `undefined` when absent, not an integer, or outside the
142450
+ * `xsd:int` range (-2147483648 to 2147483647, which also rejects digit
142451
+ * strings too long to parse), so the spec default (`1`) is never forced
142452
+ * onto the typed model.
142453
+ */
142454
+ extractFirstSlideNumber() {
142455
+ const pres = this.presentationData?.["p:presentation"];
142456
+ const lexical = String(pres?.["@_firstSlideNum"] ?? "").trim();
142457
+ if (!/^[+-]?\d+$/.test(lexical)) {
142458
+ return void 0;
142459
+ }
142460
+ const value = Number(lexical);
142461
+ return value >= XSD_INT_MIN && value <= XSD_INT_MAX ? value : void 0;
142462
+ }
141725
142463
  };
141726
142464
  }
141727
142465
  });
@@ -142007,6 +142745,8 @@ var init_PptxHandlerRuntimeLoadSession = __esm({
142007
142745
  this.slideMap.clear();
142008
142746
  this.savedSlideFingerprints.clear();
142009
142747
  this.chartDataBaselines.clear();
142748
+ this.chartWorkbookDataBaselines.clear();
142749
+ this.pendingChartUpdates = void 0;
142010
142750
  this.layoutCache.clear();
142011
142751
  this.masterCache.clear();
142012
142752
  this.templateElementBaselines.reset();
@@ -142390,7 +143130,7 @@ var init_PptxHandlerRuntimeLoadPipeline = __esm({
142390
143130
  this.commentAuthorDetails.size > 0 ? Array.from(this.commentAuthorDetails.values()) : void 0
142391
143131
  ).withModernCommentAuthors(
142392
143132
  this.modernCommentAuthors.size > 0 ? Array.from(this.modernCommentAuthors.values()) : void 0
142393
- ).withConformance(this.isStrictOoxml ? "strict" : "transitional").withEmbedTrueTypeFonts(embedTrueTypeFonts).withDefaultTextStyle(defaultTextStyle).build();
143133
+ ).withConformance(this.isStrictOoxml ? "strict" : "transitional").withEmbedTrueTypeFonts(embedTrueTypeFonts).withFirstSlideNumber(this.extractFirstSlideNumber()).withDefaultTextStyle(defaultTextStyle).build();
142394
143134
  }
142395
143135
  /**
142396
143136
  * Walk the raw XML of every slide to find the highest numeric `@_id`
@@ -142496,6 +143236,8 @@ var init_PptxHandlerRuntimeLoadPipeline = __esm({
142496
143236
  this.slideMap.clear();
142497
143237
  this.savedSlideFingerprints.clear();
142498
143238
  this.chartDataBaselines.clear();
143239
+ this.chartWorkbookDataBaselines.clear();
143240
+ this.pendingChartUpdates = void 0;
142499
143241
  this.slideRelsMap.clear();
142500
143242
  this.externalRelsMap.clear();
142501
143243
  this.layoutCache.clear();
@@ -146795,7 +147537,10 @@ var init_PptxHandler = __esm({
146795
147537
  const imported = deserializePptxFromJson(text2);
146796
147538
  const blankBytes = await buildBlankPresentationArchive({
146797
147539
  width: imported.widthEmu,
146798
- height: imported.heightEmu
147540
+ height: imported.heightEmu,
147541
+ // Saving writes presentation.xml from the loaded archive, not from
147542
+ // the overlaid model, so the archive must carry the value itself.
147543
+ firstSlideNumber: imported.firstSlideNumber
146799
147544
  });
146800
147545
  const base = await super.load(blankBytes, options);
146801
147546
  return applyImportedPptxData(base, imported);
@@ -146841,11 +147586,16 @@ function duplicateSlide(slide, newSlideNumber) {
146841
147586
  cloned.elements = cloned.elements.map(reassignElementId);
146842
147587
  if (cloned.animations && cloned.animations.length > 0) {
146843
147588
  const idMap = /* @__PURE__ */ new Map();
146844
- slide.elements.forEach((originalEl, idx) => {
146845
- if (idx < cloned.elements.length) {
146846
- idMap.set(originalEl.id, cloned.elements[idx].id);
146847
- }
146848
- });
147589
+ const mapElements = (originals, copies) => {
147590
+ originals.forEach((original, index) => {
147591
+ const copy = copies[index];
147592
+ if (!copy) return;
147593
+ idMap.set(original.id, copy.id);
147594
+ if (original.type === "group" && copy.type === "group")
147595
+ mapElements(original.children, copy.children);
147596
+ });
147597
+ };
147598
+ mapElements(slide.elements, cloned.elements);
146849
147599
  cloned.animations = cloned.animations.map((anim) => ({
146850
147600
  ...anim,
146851
147601
  elementId: idMap.get(anim.elementId) ?? anim.elementId
@@ -149680,15 +150430,26 @@ init_font_substitution();
149680
150430
  var DEFAULT_FONT_SIZE = 18;
149681
150431
  var FALLBACK_PAD_FACTOR = 0.06;
149682
150432
  function drawTextSegments(ctx, segments, bodyStyle, w, h2, scaleFactor = 1) {
149683
- const padL = bodyStyle?.bodyInsetLeft ? bodyStyle.bodyInsetLeft * scaleFactor : Math.round(w * FALLBACK_PAD_FACTOR);
149684
- const padR = bodyStyle?.bodyInsetRight ? bodyStyle.bodyInsetRight * scaleFactor : Math.round(w * FALLBACK_PAD_FACTOR);
149685
- const padT = bodyStyle?.bodyInsetTop ? bodyStyle.bodyInsetTop * scaleFactor : Math.round(h2 * FALLBACK_PAD_FACTOR);
149686
- const padB = bodyStyle?.bodyInsetBottom ? bodyStyle.bodyInsetBottom * scaleFactor : Math.round(h2 * FALLBACK_PAD_FACTOR);
150433
+ const padL = bodyStyle?.bodyInsetLeft !== void 0 ? bodyStyle.bodyInsetLeft * scaleFactor : Math.round(w * FALLBACK_PAD_FACTOR);
150434
+ const padR = bodyStyle?.bodyInsetRight !== void 0 ? bodyStyle.bodyInsetRight * scaleFactor : Math.round(w * FALLBACK_PAD_FACTOR);
150435
+ const padT = bodyStyle?.bodyInsetTop !== void 0 ? bodyStyle.bodyInsetTop * scaleFactor : Math.round(h2 * FALLBACK_PAD_FACTOR);
150436
+ const padB = bodyStyle?.bodyInsetBottom !== void 0 ? bodyStyle.bodyInsetBottom * scaleFactor : Math.round(h2 * FALLBACK_PAD_FACTOR);
149687
150437
  const maxWidth = w - padL - padR;
149688
150438
  if (maxWidth <= 0) {
149689
150439
  return;
149690
150440
  }
149691
- const paragraphs = splitIntoParagraphs(segments);
150441
+ const paragraphs = splitIntoParagraphs(
150442
+ segments.map((segment) => ({
150443
+ ...segment,
150444
+ style: {
150445
+ ...bodyStyle,
150446
+ ...Object.fromEntries(
150447
+ Object.entries(segment.style).filter(([, value]) => value !== void 0)
150448
+ )
150449
+ }
150450
+ })),
150451
+ bodyStyle
150452
+ );
149692
150453
  const lines = layoutParagraphs(ctx, paragraphs, maxWidth, scaleFactor);
149693
150454
  if (lines.length === 0) {
149694
150455
  return;
@@ -149724,33 +150485,58 @@ function drawTextSegments(ctx, segments, bodyStyle, w, h2, scaleFactor = 1) {
149724
150485
  y += line2.height * 0.3;
149725
150486
  }
149726
150487
  }
149727
- function splitIntoParagraphs(segments) {
149728
- const paragraphs = [[]];
150488
+ function splitIntoParagraphs(segments, bodyStyle) {
150489
+ const paragraphs = [{ segments: [], style: bodyStyle ?? {} }];
149729
150490
  for (const seg of segments) {
149730
- if (seg.isParagraphBreak) {
149731
- paragraphs.push([]);
149732
- } else if (seg.text) {
149733
- paragraphs[paragraphs.length - 1].push(seg);
150491
+ if (seg.isParagraphBreak || seg.text === "\n" && !seg.isLineBreak) {
150492
+ paragraphs.push({ segments: [], style: seg.style });
150493
+ } else if (seg.text || seg.isLineBreak) {
150494
+ paragraphs[paragraphs.length - 1].segments.push(seg);
149734
150495
  }
149735
150496
  }
149736
- return paragraphs.filter((p) => p.length > 0);
150497
+ return paragraphs;
149737
150498
  }
149738
150499
  function layoutParagraphs(ctx, paragraphs, maxWidth, scaleFactor) {
149739
150500
  const lines = [];
149740
- for (const para of paragraphs) {
149741
- const paraAlign = para[0]?.style?.align;
150501
+ for (const paragraph of paragraphs) {
150502
+ const para = paragraph.segments;
150503
+ const paraAlign = para[0]?.style.align ?? paragraph.style.align;
149742
150504
  let currentLine = [];
149743
150505
  let lineWidth = 0;
149744
150506
  let lineHeight = 0;
150507
+ let fallbackHeight = (para[0]?.style.fontSize ?? paragraph.style.fontSize ?? DEFAULT_FONT_SIZE) * scaleFactor * 1.2;
150508
+ const flushLine = () => {
150509
+ while (currentLine.length > 0 && /^\s+$/.test(currentLine[currentLine.length - 1].text)) {
150510
+ lineWidth -= currentLine.pop().measuredWidth;
150511
+ }
150512
+ lines.push({
150513
+ runs: currentLine,
150514
+ width: lineWidth,
150515
+ height: lineHeight || fallbackHeight,
150516
+ align: paraAlign
150517
+ });
150518
+ currentLine = [];
150519
+ lineWidth = 0;
150520
+ lineHeight = 0;
150521
+ };
149745
150522
  for (const seg of para) {
149746
150523
  ctx.font = buildFont(seg.style, scaleFactor);
149747
150524
  const fontSize = (seg.style.fontSize ?? DEFAULT_FONT_SIZE) * scaleFactor;
149748
150525
  const segHeight = fontSize * 1.2;
149749
- const tokens = seg.text.split(/(?<=\s)(?=\S)|(?<=\S)(?=\s)/);
150526
+ fallbackHeight = segHeight;
150527
+ if (seg.isLineBreak) {
150528
+ flushLine();
150529
+ continue;
150530
+ }
150531
+ const tokens = seg.text.split(/(\r\n|\r|\n)|(?<=\s)(?=\S)|(?<=\S)(?=\s)/);
149750
150532
  for (const raw of tokens) {
149751
150533
  if (!raw) {
149752
150534
  continue;
149753
150535
  }
150536
+ if (/^(\r\n|\r|\n)$/.test(raw)) {
150537
+ flushLine();
150538
+ continue;
150539
+ }
149754
150540
  if (/^\s+$/.test(raw)) {
149755
150541
  if (currentLine.length > 0) {
149756
150542
  const spaceW = ctx.measureText(raw).width;
@@ -149766,19 +150552,7 @@ function layoutParagraphs(ctx, paragraphs, maxWidth, scaleFactor) {
149766
150552
  const word = raw;
149767
150553
  const wordW = ctx.measureText(word).width;
149768
150554
  if (lineWidth + wordW > maxWidth && currentLine.length > 0) {
149769
- while (currentLine.length > 0 && /^\s+$/.test(currentLine[currentLine.length - 1].text)) {
149770
- const removed = currentLine.pop();
149771
- lineWidth -= removed.measuredWidth;
149772
- }
149773
- lines.push({
149774
- runs: currentLine,
149775
- width: lineWidth,
149776
- height: lineHeight,
149777
- align: paraAlign
149778
- });
149779
- currentLine = [];
149780
- lineWidth = 0;
149781
- lineHeight = 0;
150555
+ flushLine();
149782
150556
  }
149783
150557
  currentLine.push({
149784
150558
  text: word,
@@ -149789,14 +150563,7 @@ function layoutParagraphs(ctx, paragraphs, maxWidth, scaleFactor) {
149789
150563
  lineHeight = Math.max(lineHeight, segHeight);
149790
150564
  }
149791
150565
  }
149792
- if (currentLine.length > 0) {
149793
- lines.push({
149794
- runs: currentLine,
149795
- width: lineWidth,
149796
- height: lineHeight,
149797
- align: paraAlign
149798
- });
149799
- }
150566
+ flushLine();
149800
150567
  }
149801
150568
  return lines;
149802
150569
  }