@rowsncolumns/toolkit 24.4.1

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 (456) hide show
  1. package/LICENSE.md +100 -0
  2. package/Readme.md +27 -0
  3. package/dist/cjs/autofilter-condition.d.ts +43 -0
  4. package/dist/cjs/autofilter-condition.d.ts.map +1 -0
  5. package/dist/cjs/autofilter-condition.js +155 -0
  6. package/dist/cjs/csv-export.d.ts +49 -0
  7. package/dist/cjs/csv-export.d.ts.map +1 -0
  8. package/dist/cjs/csv-export.js +142 -0
  9. package/dist/cjs/csv-import-worker.d.ts +16 -0
  10. package/dist/cjs/csv-import-worker.d.ts.map +1 -0
  11. package/dist/cjs/csv-import-worker.js +60 -0
  12. package/dist/cjs/csv-import.d.ts +38 -0
  13. package/dist/cjs/csv-import.d.ts.map +1 -0
  14. package/dist/cjs/csv-import.js +166 -0
  15. package/dist/cjs/csv-parser/helpers.d.ts +14 -0
  16. package/dist/cjs/csv-parser/helpers.d.ts.map +1 -0
  17. package/dist/cjs/csv-parser/helpers.js +145 -0
  18. package/dist/cjs/csv-parser/types.d.ts +66 -0
  19. package/dist/cjs/csv-parser/types.d.ts.map +1 -0
  20. package/dist/cjs/csv-parser/types.js +14 -0
  21. package/dist/cjs/csv-parser/worker.d.ts +2 -0
  22. package/dist/cjs/csv-parser/worker.d.ts.map +1 -0
  23. package/dist/cjs/csv-parser/worker.js +200 -0
  24. package/dist/cjs/excel-export.d.ts +11 -0
  25. package/dist/cjs/excel-export.d.ts.map +1 -0
  26. package/dist/cjs/excel-export.js +22 -0
  27. package/dist/cjs/excel-import-session.d.ts +51 -0
  28. package/dist/cjs/excel-import-session.d.ts.map +1 -0
  29. package/dist/cjs/excel-import-session.js +307 -0
  30. package/dist/cjs/excel-import-worker.d.ts +7 -0
  31. package/dist/cjs/excel-import-worker.d.ts.map +1 -0
  32. package/dist/cjs/excel-import-worker.js +119 -0
  33. package/dist/cjs/excel-parser/builtin-numfmts.d.ts +24 -0
  34. package/dist/cjs/excel-parser/builtin-numfmts.d.ts.map +1 -0
  35. package/dist/cjs/excel-parser/builtin-numfmts.js +63 -0
  36. package/dist/cjs/excel-parser/cfb-decryptor.d.ts +53 -0
  37. package/dist/cjs/excel-parser/cfb-decryptor.d.ts.map +1 -0
  38. package/dist/cjs/excel-parser/cfb-decryptor.js +553 -0
  39. package/dist/cjs/excel-parser/cfb-encryptor.d.ts +23 -0
  40. package/dist/cjs/excel-parser/cfb-encryptor.d.ts.map +1 -0
  41. package/dist/cjs/excel-parser/cfb-encryptor.js +200 -0
  42. package/dist/cjs/excel-parser/dv-cell-stamp.d.ts +29 -0
  43. package/dist/cjs/excel-parser/dv-cell-stamp.d.ts.map +1 -0
  44. package/dist/cjs/excel-parser/dv-cell-stamp.js +239 -0
  45. package/dist/cjs/excel-parser/helpers.d.ts +28 -0
  46. package/dist/cjs/excel-parser/helpers.d.ts.map +1 -0
  47. package/dist/cjs/excel-parser/helpers.js +188 -0
  48. package/dist/cjs/excel-parser/interface.d.ts +179 -0
  49. package/dist/cjs/excel-parser/interface.d.ts.map +1 -0
  50. package/dist/cjs/excel-parser/interface.js +1 -0
  51. package/dist/cjs/excel-parser/plugins/base/index.d.ts +31 -0
  52. package/dist/cjs/excel-parser/plugins/base/index.d.ts.map +1 -0
  53. package/dist/cjs/excel-parser/plugins/base/index.js +101 -0
  54. package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
  55. package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
  56. package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.js +488 -0
  57. package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts +15 -0
  58. package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
  59. package/dist/cjs/excel-parser/plugins/ods/data-validations.js +353 -0
  60. package/dist/cjs/excel-parser/plugins/ods/formula.d.ts +8 -0
  61. package/dist/cjs/excel-parser/plugins/ods/formula.d.ts.map +1 -0
  62. package/dist/cjs/excel-parser/plugins/ods/formula.js +82 -0
  63. package/dist/cjs/excel-parser/plugins/ods/index.d.ts +122 -0
  64. package/dist/cjs/excel-parser/plugins/ods/index.d.ts.map +1 -0
  65. package/dist/cjs/excel-parser/plugins/ods/index.js +3642 -0
  66. package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts +25 -0
  67. package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
  68. package/dist/cjs/excel-parser/plugins/ods/sparklines.js +221 -0
  69. package/dist/cjs/excel-parser/plugins/ods/styles.d.ts +60 -0
  70. package/dist/cjs/excel-parser/plugins/ods/styles.d.ts.map +1 -0
  71. package/dist/cjs/excel-parser/plugins/ods/styles.js +808 -0
  72. package/dist/cjs/excel-parser/plugins/ods/types.d.ts +7 -0
  73. package/dist/cjs/excel-parser/plugins/ods/types.d.ts.map +1 -0
  74. package/dist/cjs/excel-parser/plugins/ods/types.js +1 -0
  75. package/dist/cjs/excel-parser/plugins/xls/index.d.ts +5 -0
  76. package/dist/cjs/excel-parser/plugins/xls/index.d.ts.map +1 -0
  77. package/dist/cjs/excel-parser/plugins/xls/index.js +19 -0
  78. package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
  79. package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
  80. package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.js +49 -0
  81. package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts +117 -0
  82. package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
  83. package/dist/cjs/excel-parser/plugins/xlsb/index.js +2972 -0
  84. package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
  85. package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
  86. package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.js +527 -0
  87. package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts +5 -0
  88. package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
  89. package/dist/cjs/excel-parser/plugins/xlsm/index.js +10 -0
  90. package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts +60 -0
  91. package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
  92. package/dist/cjs/excel-parser/plugins/xlsx/charts.js +2178 -0
  93. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
  94. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
  95. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +620 -0
  96. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
  97. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
  98. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +515 -0
  99. package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
  100. package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
  101. package/dist/cjs/excel-parser/plugins/xlsx/drawing.js +941 -0
  102. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +320 -0
  103. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
  104. package/dist/cjs/excel-parser/plugins/xlsx/index.js +6056 -0
  105. package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
  106. package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
  107. package/dist/cjs/excel-parser/plugins/xlsx/numfmt.js +3 -0
  108. package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
  109. package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
  110. package/dist/cjs/excel-parser/plugins/xlsx/pivots.js +342 -0
  111. package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
  112. package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
  113. package/dist/cjs/excel-parser/plugins/xlsx/relationships.js +26 -0
  114. package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
  115. package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
  116. package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.js +59 -0
  117. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +44 -0
  118. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
  119. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +1377 -0
  120. package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts +50 -0
  121. package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
  122. package/dist/cjs/excel-parser/plugins/xlsx/theme.js +150 -0
  123. package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
  124. package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
  125. package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.js +141 -0
  126. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
  127. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
  128. package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.js +407 -0
  129. package/dist/cjs/excel-parser/registry.d.ts +5 -0
  130. package/dist/cjs/excel-parser/registry.d.ts.map +1 -0
  131. package/dist/cjs/excel-parser/registry.js +21 -0
  132. package/dist/cjs/excel-parser/style-registry.d.ts +51 -0
  133. package/dist/cjs/excel-parser/style-registry.d.ts.map +1 -0
  134. package/dist/cjs/excel-parser/style-registry.js +175 -0
  135. package/dist/cjs/excel-parser/theme-default.d.ts +3 -0
  136. package/dist/cjs/excel-parser/theme-default.d.ts.map +1 -0
  137. package/dist/cjs/excel-parser/theme-default.js +19 -0
  138. package/dist/cjs/excel-parser/types.d.ts +365 -0
  139. package/dist/cjs/excel-parser/types.d.ts.map +1 -0
  140. package/dist/cjs/excel-parser/types.js +59 -0
  141. package/dist/cjs/excel-parser/utils.d.ts +6 -0
  142. package/dist/cjs/excel-parser/utils.d.ts.map +1 -0
  143. package/dist/cjs/excel-parser/utils.js +30 -0
  144. package/dist/cjs/excel-parser/workbook.d.ts +51 -0
  145. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -0
  146. package/dist/cjs/excel-parser/workbook.js +317 -0
  147. package/dist/cjs/excel-parser/worker.d.ts +2 -0
  148. package/dist/cjs/excel-parser/worker.d.ts.map +1 -0
  149. package/dist/cjs/excel-parser/worker.js +1149 -0
  150. package/dist/cjs/excel-parser/zip-parser-streaming.d.ts +13 -0
  151. package/dist/cjs/excel-parser/zip-parser-streaming.d.ts.map +1 -0
  152. package/dist/cjs/excel-parser/zip-parser-streaming.js +200 -0
  153. package/dist/cjs/excel-parser/zip-parser.d.ts +11 -0
  154. package/dist/cjs/excel-parser/zip-parser.d.ts.map +1 -0
  155. package/dist/cjs/excel-parser/zip-parser.js +49 -0
  156. package/dist/cjs/exporter/invalid-data-validation.d.ts +19 -0
  157. package/dist/cjs/exporter/invalid-data-validation.d.ts.map +1 -0
  158. package/dist/cjs/exporter/invalid-data-validation.js +39 -0
  159. package/dist/cjs/exporter/ods/ods-export.d.ts +26 -0
  160. package/dist/cjs/exporter/ods/ods-export.d.ts.map +1 -0
  161. package/dist/cjs/exporter/ods/ods-export.js +3714 -0
  162. package/dist/cjs/exporter/ods/sparkline-builder.d.ts +33 -0
  163. package/dist/cjs/exporter/ods/sparkline-builder.d.ts.map +1 -0
  164. package/dist/cjs/exporter/ods/sparkline-builder.js +221 -0
  165. package/dist/cjs/exporter/xlsx/chart-builder.d.ts +3 -0
  166. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -0
  167. package/dist/cjs/exporter/xlsx/chart-builder.js +1901 -0
  168. package/dist/cjs/exporter/xlsx/chart-templates.d.ts +1781 -0
  169. package/dist/cjs/exporter/xlsx/chart-templates.d.ts.map +1 -0
  170. package/dist/cjs/exporter/xlsx/chart-templates.js +1798 -0
  171. package/dist/cjs/exporter/xlsx/future-functions.d.ts +10 -0
  172. package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -0
  173. package/dist/cjs/exporter/xlsx/future-functions.js +264 -0
  174. package/dist/cjs/exporter/xlsx/pivot-builder.d.ts +58 -0
  175. package/dist/cjs/exporter/xlsx/pivot-builder.d.ts.map +1 -0
  176. package/dist/cjs/exporter/xlsx/pivot-builder.js +277 -0
  177. package/dist/cjs/exporter/xlsx/power-query-builder.d.ts +26 -0
  178. package/dist/cjs/exporter/xlsx/power-query-builder.d.ts.map +1 -0
  179. package/dist/cjs/exporter/xlsx/power-query-builder.js +306 -0
  180. package/dist/cjs/exporter/xlsx/slicer-builder.d.ts +11 -0
  181. package/dist/cjs/exporter/xlsx/slicer-builder.d.ts.map +1 -0
  182. package/dist/cjs/exporter/xlsx/slicer-builder.js +87 -0
  183. package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts +61 -0
  184. package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
  185. package/dist/cjs/exporter/xlsx/sparkline-builder.js +489 -0
  186. package/dist/cjs/exporter/xlsx/style-builder.d.ts +93 -0
  187. package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -0
  188. package/dist/cjs/exporter/xlsx/style-builder.js +813 -0
  189. package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
  190. package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
  191. package/dist/cjs/exporter/xlsx/threaded-comments-builder.js +189 -0
  192. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +121 -0
  193. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -0
  194. package/dist/cjs/exporter/xlsx/xlsx-export.js +4596 -0
  195. package/dist/cjs/helpers/theme-xml-generator.d.ts +8 -0
  196. package/dist/cjs/helpers/theme-xml-generator.d.ts.map +1 -0
  197. package/dist/cjs/helpers/theme-xml-generator.js +33 -0
  198. package/dist/cjs/helpers.d.ts +34 -0
  199. package/dist/cjs/helpers.d.ts.map +1 -0
  200. package/dist/cjs/helpers.js +189 -0
  201. package/dist/cjs/index.d.ts +16 -0
  202. package/dist/cjs/index.d.ts.map +1 -0
  203. package/dist/cjs/index.js +15 -0
  204. package/dist/cjs/indexed-colors.d.ts +2 -0
  205. package/dist/cjs/indexed-colors.d.ts.map +1 -0
  206. package/dist/cjs/indexed-colors.js +75 -0
  207. package/dist/cjs/ods-export.d.ts +24 -0
  208. package/dist/cjs/ods-export.d.ts.map +1 -0
  209. package/dist/cjs/ods-export.js +23 -0
  210. package/dist/cjs/parse.d.ts +24 -0
  211. package/dist/cjs/parse.d.ts.map +1 -0
  212. package/dist/cjs/parse.js +68 -0
  213. package/dist/cjs/power-query.d.ts +41 -0
  214. package/dist/cjs/power-query.d.ts.map +1 -0
  215. package/dist/cjs/power-query.js +22 -0
  216. package/dist/cjs/server.d.ts +9 -0
  217. package/dist/cjs/server.d.ts.map +1 -0
  218. package/dist/cjs/server.js +8 -0
  219. package/dist/cjs/theme1.d.ts +3 -0
  220. package/dist/cjs/theme1.d.ts.map +1 -0
  221. package/dist/cjs/theme1.js +2 -0
  222. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  223. package/dist/cjs/types.d.ts +14 -0
  224. package/dist/cjs/types.d.ts.map +1 -0
  225. package/dist/cjs/types.js +14 -0
  226. package/dist/cjs/vitest.config.d.ts +3 -0
  227. package/dist/cjs/vitest.config.d.ts.map +1 -0
  228. package/dist/cjs/vitest.config.js +16 -0
  229. package/dist/esm/autofilter-condition.d.ts +43 -0
  230. package/dist/esm/autofilter-condition.d.ts.map +1 -0
  231. package/dist/esm/autofilter-condition.js +145 -0
  232. package/dist/esm/csv-export.d.ts +49 -0
  233. package/dist/esm/csv-export.d.ts.map +1 -0
  234. package/dist/esm/csv-export.js +126 -0
  235. package/dist/esm/csv-import-worker.d.ts +16 -0
  236. package/dist/esm/csv-import-worker.d.ts.map +1 -0
  237. package/dist/esm/csv-import-worker.js +60 -0
  238. package/dist/esm/csv-import.d.ts +38 -0
  239. package/dist/esm/csv-import.d.ts.map +1 -0
  240. package/dist/esm/csv-import.js +132 -0
  241. package/dist/esm/csv-parser/helpers.d.ts +14 -0
  242. package/dist/esm/csv-parser/helpers.d.ts.map +1 -0
  243. package/dist/esm/csv-parser/helpers.js +0 -0
  244. package/dist/esm/csv-parser/types.d.ts +66 -0
  245. package/dist/esm/csv-parser/types.d.ts.map +1 -0
  246. package/dist/esm/csv-parser/types.js +14 -0
  247. package/dist/esm/csv-parser/worker.d.ts +2 -0
  248. package/dist/esm/csv-parser/worker.d.ts.map +1 -0
  249. package/dist/esm/csv-parser/worker.js +154 -0
  250. package/dist/esm/excel-export.d.ts +11 -0
  251. package/dist/esm/excel-export.d.ts.map +1 -0
  252. package/dist/esm/excel-export.js +13 -0
  253. package/dist/esm/excel-import-session.d.ts +51 -0
  254. package/dist/esm/excel-import-session.d.ts.map +1 -0
  255. package/dist/esm/excel-import-session.js +255 -0
  256. package/dist/esm/excel-import-worker.d.ts +7 -0
  257. package/dist/esm/excel-import-worker.d.ts.map +1 -0
  258. package/dist/esm/excel-import-worker.js +116 -0
  259. package/dist/esm/excel-parser/builtin-numfmts.d.ts +24 -0
  260. package/dist/esm/excel-parser/builtin-numfmts.d.ts.map +1 -0
  261. package/dist/esm/excel-parser/builtin-numfmts.js +59 -0
  262. package/dist/esm/excel-parser/cfb-decryptor.d.ts +53 -0
  263. package/dist/esm/excel-parser/cfb-decryptor.d.ts.map +1 -0
  264. package/dist/esm/excel-parser/cfb-decryptor.js +493 -0
  265. package/dist/esm/excel-parser/cfb-encryptor.d.ts +23 -0
  266. package/dist/esm/excel-parser/cfb-encryptor.d.ts.map +1 -0
  267. package/dist/esm/excel-parser/cfb-encryptor.js +181 -0
  268. package/dist/esm/excel-parser/dv-cell-stamp.d.ts +29 -0
  269. package/dist/esm/excel-parser/dv-cell-stamp.d.ts.map +1 -0
  270. package/dist/esm/excel-parser/dv-cell-stamp.js +155 -0
  271. package/dist/esm/excel-parser/helpers.d.ts +28 -0
  272. package/dist/esm/excel-parser/helpers.d.ts.map +1 -0
  273. package/dist/esm/excel-parser/helpers.js +160 -0
  274. package/dist/esm/excel-parser/interface.d.ts +179 -0
  275. package/dist/esm/excel-parser/interface.d.ts.map +1 -0
  276. package/dist/esm/excel-parser/interface.js +1 -0
  277. package/dist/esm/excel-parser/plugins/base/index.d.ts +31 -0
  278. package/dist/esm/excel-parser/plugins/base/index.d.ts.map +1 -0
  279. package/dist/esm/excel-parser/plugins/base/index.js +64 -0
  280. package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
  281. package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
  282. package/dist/esm/excel-parser/plugins/ods/conditional-formatting.js +405 -0
  283. package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts +15 -0
  284. package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
  285. package/dist/esm/excel-parser/plugins/ods/data-validations.js +331 -0
  286. package/dist/esm/excel-parser/plugins/ods/formula.d.ts +8 -0
  287. package/dist/esm/excel-parser/plugins/ods/formula.d.ts.map +1 -0
  288. package/dist/esm/excel-parser/plugins/ods/formula.js +82 -0
  289. package/dist/esm/excel-parser/plugins/ods/index.d.ts +122 -0
  290. package/dist/esm/excel-parser/plugins/ods/index.d.ts.map +1 -0
  291. package/dist/esm/excel-parser/plugins/ods/index.js +2896 -0
  292. package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts +25 -0
  293. package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
  294. package/dist/esm/excel-parser/plugins/ods/sparklines.js +188 -0
  295. package/dist/esm/excel-parser/plugins/ods/styles.d.ts +60 -0
  296. package/dist/esm/excel-parser/plugins/ods/styles.d.ts.map +1 -0
  297. package/dist/esm/excel-parser/plugins/ods/styles.js +732 -0
  298. package/dist/esm/excel-parser/plugins/ods/types.d.ts +7 -0
  299. package/dist/esm/excel-parser/plugins/ods/types.d.ts.map +1 -0
  300. package/dist/esm/excel-parser/plugins/ods/types.js +1 -0
  301. package/dist/esm/excel-parser/plugins/xls/index.d.ts +5 -0
  302. package/dist/esm/excel-parser/plugins/xls/index.d.ts.map +1 -0
  303. package/dist/esm/excel-parser/plugins/xls/index.js +7 -0
  304. package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
  305. package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
  306. package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.js +48 -0
  307. package/dist/esm/excel-parser/plugins/xlsb/index.d.ts +117 -0
  308. package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
  309. package/dist/esm/excel-parser/plugins/xlsb/index.js +2339 -0
  310. package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
  311. package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
  312. package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.js +522 -0
  313. package/dist/esm/excel-parser/plugins/xlsm/index.d.ts +5 -0
  314. package/dist/esm/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
  315. package/dist/esm/excel-parser/plugins/xlsm/index.js +6 -0
  316. package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts +60 -0
  317. package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
  318. package/dist/esm/excel-parser/plugins/xlsx/charts.js +2036 -0
  319. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
  320. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
  321. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +621 -0
  322. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
  323. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
  324. package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +493 -0
  325. package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
  326. package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
  327. package/dist/esm/excel-parser/plugins/xlsx/drawing.js +905 -0
  328. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +320 -0
  329. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
  330. package/dist/esm/excel-parser/plugins/xlsx/index.js +4654 -0
  331. package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
  332. package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
  333. package/dist/esm/excel-parser/plugins/xlsx/numfmt.js +3 -0
  334. package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
  335. package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
  336. package/dist/esm/excel-parser/plugins/xlsx/pivots.js +254 -0
  337. package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
  338. package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
  339. package/dist/esm/excel-parser/plugins/xlsx/relationships.js +13 -0
  340. package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
  341. package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
  342. package/dist/esm/excel-parser/plugins/xlsx/sheet-views.js +64 -0
  343. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +44 -0
  344. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
  345. package/dist/esm/excel-parser/plugins/xlsx/styles.js +1365 -0
  346. package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts +50 -0
  347. package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
  348. package/dist/esm/excel-parser/plugins/xlsx/theme.js +127 -0
  349. package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
  350. package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
  351. package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.js +103 -0
  352. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
  353. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
  354. package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.js +399 -0
  355. package/dist/esm/excel-parser/registry.d.ts +5 -0
  356. package/dist/esm/excel-parser/registry.d.ts.map +1 -0
  357. package/dist/esm/excel-parser/registry.js +20 -0
  358. package/dist/esm/excel-parser/style-registry.d.ts +51 -0
  359. package/dist/esm/excel-parser/style-registry.d.ts.map +1 -0
  360. package/dist/esm/excel-parser/style-registry.js +163 -0
  361. package/dist/esm/excel-parser/theme-default.d.ts +3 -0
  362. package/dist/esm/excel-parser/theme-default.d.ts.map +1 -0
  363. package/dist/esm/excel-parser/theme-default.js +19 -0
  364. package/dist/esm/excel-parser/types.d.ts +365 -0
  365. package/dist/esm/excel-parser/types.d.ts.map +1 -0
  366. package/dist/esm/excel-parser/types.js +59 -0
  367. package/dist/esm/excel-parser/utils.d.ts +6 -0
  368. package/dist/esm/excel-parser/utils.d.ts.map +1 -0
  369. package/dist/esm/excel-parser/utils.js +25 -0
  370. package/dist/esm/excel-parser/workbook.d.ts +51 -0
  371. package/dist/esm/excel-parser/workbook.d.ts.map +1 -0
  372. package/dist/esm/excel-parser/workbook.js +192 -0
  373. package/dist/esm/excel-parser/worker.d.ts +2 -0
  374. package/dist/esm/excel-parser/worker.d.ts.map +1 -0
  375. package/dist/esm/excel-parser/worker.js +862 -0
  376. package/dist/esm/excel-parser/zip-parser-streaming.d.ts +13 -0
  377. package/dist/esm/excel-parser/zip-parser-streaming.d.ts.map +1 -0
  378. package/dist/esm/excel-parser/zip-parser-streaming.js +119 -0
  379. package/dist/esm/excel-parser/zip-parser.d.ts +11 -0
  380. package/dist/esm/excel-parser/zip-parser.d.ts.map +1 -0
  381. package/dist/esm/excel-parser/zip-parser.js +43 -0
  382. package/dist/esm/exporter/invalid-data-validation.d.ts +19 -0
  383. package/dist/esm/exporter/invalid-data-validation.d.ts.map +1 -0
  384. package/dist/esm/exporter/invalid-data-validation.js +37 -0
  385. package/dist/esm/exporter/ods/ods-export.d.ts +26 -0
  386. package/dist/esm/exporter/ods/ods-export.d.ts.map +1 -0
  387. package/dist/esm/exporter/ods/ods-export.js +3238 -0
  388. package/dist/esm/exporter/ods/sparkline-builder.d.ts +33 -0
  389. package/dist/esm/exporter/ods/sparkline-builder.d.ts.map +1 -0
  390. package/dist/esm/exporter/ods/sparkline-builder.js +165 -0
  391. package/dist/esm/exporter/xlsx/chart-builder.d.ts +3 -0
  392. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -0
  393. package/dist/esm/exporter/xlsx/chart-builder.js +1805 -0
  394. package/dist/esm/exporter/xlsx/chart-templates.d.ts +1781 -0
  395. package/dist/esm/exporter/xlsx/chart-templates.d.ts.map +1 -0
  396. package/dist/esm/exporter/xlsx/chart-templates.js +1798 -0
  397. package/dist/esm/exporter/xlsx/future-functions.d.ts +10 -0
  398. package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -0
  399. package/dist/esm/exporter/xlsx/future-functions.js +264 -0
  400. package/dist/esm/exporter/xlsx/pivot-builder.d.ts +58 -0
  401. package/dist/esm/exporter/xlsx/pivot-builder.d.ts.map +1 -0
  402. package/dist/esm/exporter/xlsx/pivot-builder.js +230 -0
  403. package/dist/esm/exporter/xlsx/power-query-builder.d.ts +26 -0
  404. package/dist/esm/exporter/xlsx/power-query-builder.d.ts.map +1 -0
  405. package/dist/esm/exporter/xlsx/power-query-builder.js +257 -0
  406. package/dist/esm/exporter/xlsx/slicer-builder.d.ts +11 -0
  407. package/dist/esm/exporter/xlsx/slicer-builder.d.ts.map +1 -0
  408. package/dist/esm/exporter/xlsx/slicer-builder.js +84 -0
  409. package/dist/esm/exporter/xlsx/sparkline-builder.d.ts +61 -0
  410. package/dist/esm/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
  411. package/dist/esm/exporter/xlsx/sparkline-builder.js +437 -0
  412. package/dist/esm/exporter/xlsx/style-builder.d.ts +93 -0
  413. package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -0
  414. package/dist/esm/exporter/xlsx/style-builder.js +795 -0
  415. package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
  416. package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
  417. package/dist/esm/exporter/xlsx/threaded-comments-builder.js +175 -0
  418. package/dist/esm/exporter/xlsx/xlsx-export.d.ts +121 -0
  419. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -0
  420. package/dist/esm/exporter/xlsx/xlsx-export.js +4062 -0
  421. package/dist/esm/helpers/theme-xml-generator.d.ts +8 -0
  422. package/dist/esm/helpers/theme-xml-generator.d.ts.map +1 -0
  423. package/dist/esm/helpers/theme-xml-generator.js +33 -0
  424. package/dist/esm/helpers.d.ts +34 -0
  425. package/dist/esm/helpers.d.ts.map +1 -0
  426. package/dist/esm/helpers.js +182 -0
  427. package/dist/esm/index.d.ts +16 -0
  428. package/dist/esm/index.d.ts.map +1 -0
  429. package/dist/esm/index.js +15 -0
  430. package/dist/esm/indexed-colors.d.ts +2 -0
  431. package/dist/esm/indexed-colors.d.ts.map +1 -0
  432. package/dist/esm/indexed-colors.js +75 -0
  433. package/dist/esm/ods-export.d.ts +24 -0
  434. package/dist/esm/ods-export.d.ts.map +1 -0
  435. package/dist/esm/ods-export.js +12 -0
  436. package/dist/esm/parse.d.ts +24 -0
  437. package/dist/esm/parse.d.ts.map +1 -0
  438. package/dist/esm/parse.js +55 -0
  439. package/dist/esm/power-query.d.ts +41 -0
  440. package/dist/esm/power-query.d.ts.map +1 -0
  441. package/dist/esm/power-query.js +19 -0
  442. package/dist/esm/server.d.ts +9 -0
  443. package/dist/esm/server.d.ts.map +1 -0
  444. package/dist/esm/server.js +8 -0
  445. package/dist/esm/theme1.d.ts +3 -0
  446. package/dist/esm/theme1.d.ts.map +1 -0
  447. package/dist/esm/theme1.js +2 -0
  448. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  449. package/dist/esm/types.d.ts +14 -0
  450. package/dist/esm/types.d.ts.map +1 -0
  451. package/dist/esm/types.js +14 -0
  452. package/dist/esm/vitest.config.d.ts +3 -0
  453. package/dist/esm/vitest.config.d.ts.map +1 -0
  454. package/dist/esm/vitest.config.js +16 -0
  455. package/package.json +62 -0
  456. package/xlsx.d.ts +52 -0
@@ -0,0 +1,905 @@
1
+ import { uuid } from "@rowsncolumns/utils";
2
+ import { get } from "lodash-es";
3
+ /**
4
+ * Create a data URL from binary data and MIME type
5
+ * @param data Binary data of the image
6
+ * @param mimeType MIME type of the image
7
+ * @returns Data URL string
8
+ */
9
+ function createDataUrl(data, mimeType) {
10
+ // Convert ArrayBuffer to Base64 string
11
+ const base64 = arrayBufferToBase64(data);
12
+ return `data:${mimeType};base64,${base64}`;
13
+ }
14
+ /**
15
+ * Convert an ArrayBuffer to a Base64 string
16
+ * @param buffer ArrayBuffer to convert
17
+ * @returns Base64 string
18
+ */
19
+ function arrayBufferToBase64(buffer) {
20
+ const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
21
+ // Use Buffer in Node.js, btoa in browser
22
+ if (typeof Buffer !== "undefined") {
23
+ return Buffer.from(bytes).toString("base64");
24
+ }
25
+ let binary = "";
26
+ const len = bytes.byteLength;
27
+ for (let i = 0; i < len; i++) {
28
+ binary += String.fromCharCode(bytes[i]);
29
+ }
30
+ return btoa(binary);
31
+ }
32
+ // Conversion constant: 1 pixel is approximately 9525 EMUs (at 96 DPI)
33
+ const EMU_PER_PIXEL = 9525;
34
+ const DEFAULT_CELL_IMAGE_MAX_SIZE_PX = 60;
35
+ const CELL_IMAGE_OFFSET_THRESHOLD_PX = 1;
36
+ /**
37
+ * Convert EMUs to pixels
38
+ * @param emuValue Value in English Metric Units
39
+ * @returns Value in pixels (at 96 DPI)
40
+ */
41
+ function emuToPixels(emuValue) {
42
+ return Math.round(emuValue / EMU_PER_PIXEL);
43
+ }
44
+ /**
45
+ * Process different types of image anchors
46
+ * @param anchors The anchor elements from the drawing
47
+ * @param anchorType The type of anchor
48
+ * @param drawingPath The path to the drawing file
49
+ * @param sheetName The name of the worksheet
50
+ * @param zipParser The zip parser instance
51
+ * @param xmlParser The XML parser instance
52
+ * @returns An array of image objects with their properties and binary data
53
+ */
54
+ export async function processAnchors(anchors, anchorType, drawingPath, sheetId, zipParser, xmlParser) {
55
+ const images = [];
56
+ if (!anchors)
57
+ return images;
58
+ // Normalize to array
59
+ const anchorArray = Array.isArray(anchors) ? anchors : [anchors];
60
+ for (const anchor of anchorArray) {
61
+ let isInsideCell = false;
62
+ // Get position information based on anchor type
63
+ let position = {
64
+ sheetId,
65
+ // sheet: sheetName,
66
+ // anchorType: anchorType, // Store the anchor type to differentiate positioning
67
+ };
68
+ if (anchorType === "twoCellAnchors") {
69
+ // Two cell anchor defines a rectangle with from and to cells
70
+ // Handle different namespace patterns
71
+ // Adjust row and column indices to start from 1 (Excel-like) instead of 0 (zero-based)
72
+ // Store both the original (0-based) and adjusted (1-based) indices
73
+ const fromColBase0 = parseInt(get(anchor, "xdr:from.xdr:col.t$") ||
74
+ get(anchor, "from.col.t$") ||
75
+ get(anchor, "xdr:from.xdr:col") ||
76
+ get(anchor, "from.col") ||
77
+ "0");
78
+ const fromRowBase0 = parseInt(get(anchor, "xdr:from.xdr:row.t$") ||
79
+ get(anchor, "from.row.t$") ||
80
+ get(anchor, "xdr:from.xdr:row") ||
81
+ get(anchor, "from.row") ||
82
+ "0");
83
+ const toColBase0 = parseInt(get(anchor, "xdr:to.xdr:col.t$") ||
84
+ get(anchor, "to.col.t$") ||
85
+ get(anchor, "xdr:to.xdr:col") ||
86
+ get(anchor, "to.col") ||
87
+ "0");
88
+ const toRowBase0 = parseInt(get(anchor, "xdr:to.xdr:row.t$") ||
89
+ get(anchor, "to.row.t$") ||
90
+ get(anchor, "xdr:to.xdr:row") ||
91
+ get(anchor, "to.row") ||
92
+ "0");
93
+ // Convert to 1-based indices (Excel-like)
94
+ const fromCol = fromColBase0 + 1;
95
+ const fromRow = fromRowBase0 + 1;
96
+ const toCol = toColBase0 + 1;
97
+ const toRow = toRowBase0 + 1;
98
+ // Get offset information if available (convert to pixels)
99
+ const fromColOffEmu = parseInt(get(anchor, "xdr:from.xdr:colOff.t$") ||
100
+ get(anchor, "from.colOff.t$") ||
101
+ get(anchor, "xdr:from.xdr:colOff") ||
102
+ get(anchor, "from.colOff") ||
103
+ "0");
104
+ const fromRowOffEmu = parseInt(get(anchor, "xdr:from.xdr:rowOff.t$") ||
105
+ get(anchor, "from.rowOff.t$") ||
106
+ get(anchor, "xdr:from.xdr:rowOff") ||
107
+ get(anchor, "from.rowOff") ||
108
+ "0");
109
+ const toColOffEmu = parseInt(get(anchor, "xdr:to.xdr:colOff.t$") ||
110
+ get(anchor, "to.colOff.t$") ||
111
+ get(anchor, "xdr:to.xdr:colOff") ||
112
+ get(anchor, "to.colOff") ||
113
+ "0");
114
+ const toRowOffEmu = parseInt(get(anchor, "xdr:to.xdr:rowOff.t$") ||
115
+ get(anchor, "to.rowOff.t$") ||
116
+ get(anchor, "xdr:to.xdr:rowOff") ||
117
+ get(anchor, "to.rowOff") ||
118
+ "0");
119
+ // Convert EMUs to pixels
120
+ const fromColOff = emuToPixels(fromColOffEmu);
121
+ const fromRowOff = emuToPixels(fromRowOffEmu);
122
+ const toColOff = emuToPixels(toColOffEmu);
123
+ const toRowOff = emuToPixels(toRowOffEmu);
124
+ // Get extent (size) information (in EMUs) from the correct path
125
+ const cxEmu = parseInt(get(anchor, "xdr:pic.xdr:spPr.a:xfrm.a:ext.a$.cx") ||
126
+ get(anchor, "pic.spPr.xfrm.ext.a$.cx") ||
127
+ "0");
128
+ const cyEmu = parseInt(get(anchor, "xdr:pic.xdr:spPr.a:xfrm.a:ext.a$.cy") ||
129
+ get(anchor, "pic.spPr.xfrm.ext.a$.cy") ||
130
+ "0");
131
+ // Convert EMUs to pixels
132
+ const width = emuToPixels(cxEmu);
133
+ const height = emuToPixels(cyEmu);
134
+ // Check for editAs attribute which indicates if image is locked to cells
135
+ const editAs = get(anchor, "a$.editAs") || "";
136
+ isInsideCell = determineIfTwoCellInsideCell(editAs, fromColBase0, fromRowBase0, toColBase0, toRowBase0);
137
+ position = {
138
+ ...position,
139
+ overlayPosition: {
140
+ anchorCell: {
141
+ rowIndex: fromRow,
142
+ columnIndex: fromCol,
143
+ },
144
+ heightPixels: height,
145
+ widthPixels: width,
146
+ offsetXPixels: fromColOff,
147
+ offsetYPixels: fromRowOff,
148
+ },
149
+ };
150
+ }
151
+ else if (anchorType === "oneCellAnchor") {
152
+ // One cell anchor defines a point with just from cell and extents
153
+ // Handle different namespace patterns
154
+ // Adjust row and column indices to start from 1 (Excel-like) instead of 0 (zero-based)
155
+ const fromColBase0 = parseInt(get(anchor, "xdr:from.xdr:col.t$") ||
156
+ get(anchor, "from.col.t$") ||
157
+ get(anchor, "xdr:from.xdr:col") ||
158
+ get(anchor, "from.col") ||
159
+ "0");
160
+ const fromRowBase0 = parseInt(get(anchor, "xdr:from.xdr:row.t$") ||
161
+ get(anchor, "from.row.t$") ||
162
+ get(anchor, "xdr:from.xdr:row") ||
163
+ get(anchor, "from.row") ||
164
+ "0");
165
+ // Convert to 1-based indices (Excel-like)
166
+ const fromCol = fromColBase0 + 1;
167
+ const fromRow = fromRowBase0 + 1;
168
+ // Get offset information (in EMUs)
169
+ const fromColOffEmu = parseInt(get(anchor, "xdr:from.xdr:colOff.t$") ||
170
+ get(anchor, "from.colOff.t$") ||
171
+ get(anchor, "xdr:from.xdr:colOff") ||
172
+ get(anchor, "from.colOff") ||
173
+ "0");
174
+ const fromRowOffEmu = parseInt(get(anchor, "xdr:from.xdr:rowOff.t$") ||
175
+ get(anchor, "from.rowOff.t$") ||
176
+ get(anchor, "xdr:from.xdr:rowOff") ||
177
+ get(anchor, "from.rowOff") ||
178
+ "0");
179
+ // Convert EMUs to pixels
180
+ const fromColOff = emuToPixels(fromColOffEmu);
181
+ const fromRowOff = emuToPixels(fromRowOffEmu);
182
+ // Get extent (size) information (in EMUs)
183
+ const cxEmu = parseInt(get(anchor, "xdr:ext.a$.cx") || get(anchor, "ext.a$.cx") || "0");
184
+ const cyEmu = parseInt(get(anchor, "xdr:ext.a$.cy") || get(anchor, "ext.a$.cy") || "0");
185
+ // Convert EMUs to pixels
186
+ const width = emuToPixels(cxEmu);
187
+ const height = emuToPixels(cyEmu);
188
+ // Add info about locking with sheet which helps determine positioning
189
+ const fLocksWithSheet = get(anchor, "xdr:clientData.a$.fLocksWithSheet") ||
190
+ get(anchor, "clientData.a$.fLocksWithSheet") ||
191
+ "0";
192
+ isInsideCell = determineIfOneCellInsideCell(fromColOffEmu, fromRowOffEmu, fLocksWithSheet, cxEmu, cyEmu);
193
+ position = {
194
+ ...position,
195
+ overlayPosition: {
196
+ anchorCell: {
197
+ rowIndex: fromRow,
198
+ columnIndex: fromCol,
199
+ },
200
+ heightPixels: height,
201
+ widthPixels: width,
202
+ offsetXPixels: fromColOff,
203
+ offsetYPixels: fromRowOff,
204
+ },
205
+ };
206
+ // position = {
207
+ // ...position,
208
+ // fromCol,
209
+ // fromRow,
210
+ // fromColOff,
211
+ // fromRowOff,
212
+ // width,
213
+ // height,
214
+ // // Store original indices in case they're needed
215
+ // _fromColBase0: fromColBase0,
216
+ // _fromRowBase0: fromRowBase0,
217
+ // // Store original EMU values for reference if needed
218
+ // _fromColOffEmu: fromColOffEmu,
219
+ // _fromRowOffEmu: fromRowOffEmu,
220
+ // _widthEmu: cxEmu,
221
+ // _heightEmu: cyEmu,
222
+ // fLocksWithSheet: fLocksWithSheet === "1",
223
+ // // For oneCellAnchor, determine based on offsets and locking
224
+ // isInsideCell: determineIfOneCellInsideCell(
225
+ // fromColOffEmu,
226
+ // fromRowOffEmu,
227
+ // fLocksWithSheet,
228
+ // cxEmu,
229
+ // cyEmu
230
+ // ),
231
+ // };
232
+ }
233
+ else if (anchorType === "absoluteAnchors") {
234
+ // Absolute anchor doesn't have cell reference, only absolute position (in EMUs)
235
+ const posXEmu = parseInt(get(anchor, "xdr:pos.a$.x") || get(anchor, "pos.a$.x") || "0") || 0;
236
+ const posYEmu = parseInt(get(anchor, "xdr:pos.a$.y") || get(anchor, "pos.a$.y") || "0") || 0;
237
+ // Convert EMUs to pixels
238
+ const posX = emuToPixels(posXEmu);
239
+ const posY = emuToPixels(posYEmu);
240
+ // Get extent (size) information (in EMUs)
241
+ const cxEmu = parseInt(get(anchor, "xdr:ext.a$.cx") || get(anchor, "ext.a$.cx") || "0") || 0;
242
+ const cyEmu = parseInt(get(anchor, "xdr:ext.a$.cy") || get(anchor, "ext.a$.cy") || "0") || 0;
243
+ // Convert EMUs to pixels
244
+ const width = emuToPixels(cxEmu);
245
+ const height = emuToPixels(cyEmu);
246
+ position = {
247
+ ...position,
248
+ overlayPosition: {
249
+ anchorCell: {
250
+ rowIndex: 1,
251
+ columnIndex: 1,
252
+ },
253
+ heightPixels: height,
254
+ widthPixels: width,
255
+ offsetXPixels: posX,
256
+ offsetYPixels: posY,
257
+ },
258
+ };
259
+ }
260
+ // Find the picture element with different possible namespaces
261
+ const picture = get(anchor, "xdr:pic") || get(anchor, "pic");
262
+ // Find shape (textbox or drawing shape) element
263
+ const shape = get(anchor, "xdr:sp") || get(anchor, "sp");
264
+ // Drawing shape (Insert → Shapes): parsed into an `EmbedShapeSpec` so the
265
+ // geometry/fill/outline render. A shape is only routed here when it is
266
+ // visibly a *shape* — a non-rect preset geometry, an explicit fill, or an
267
+ // `<xdr:style>` theme-style block. Plain text boxes (`txBox="1"`, or a bare
268
+ // unstyled rect) keep the textbox path below, so they don't inherit the
269
+ // shape renderer's default accent styling.
270
+ if (shape && isDrawingShape(shape)) {
271
+ const shapeSpec = parseShapeSpec(shape);
272
+ const cxEmu = parseInt(get(shape, "xdr:spPr.a:xfrm.a:ext.a$.cx") ||
273
+ get(shape, "spPr.xfrm.ext.a$.cx") ||
274
+ "0");
275
+ const cyEmu = parseInt(get(shape, "xdr:spPr.a:xfrm.a:ext.a$.cy") ||
276
+ get(shape, "spPr.xfrm.ext.a$.cy") ||
277
+ "0");
278
+ if (cxEmu > 0 && cyEmu > 0 && position.overlayPosition) {
279
+ position.overlayPosition.widthPixels = emuToPixels(cxEmu);
280
+ position.overlayPosition.heightPixels = emuToPixels(cyEmu);
281
+ }
282
+ // Shape rotation lives on the embed (like images), in degrees.
283
+ const rotUnits = parseInt(get(shape, "xdr:spPr.a:xfrm.a$.rot") ||
284
+ get(shape, "spPr.xfrm.a$.rot") ||
285
+ "0");
286
+ images.push({
287
+ isInsideCell,
288
+ embedId: uuid(),
289
+ spec: shapeSpec,
290
+ position,
291
+ rotation: rotUnits ? rotUnits / 60000 : undefined,
292
+ draggable: true,
293
+ });
294
+ continue;
295
+ }
296
+ // Process textbox if shape has text body
297
+ if (shape) {
298
+ const txBody = get(shape, "xdr:txBody") || get(shape, "txBody");
299
+ if (txBody) {
300
+ // Extract textbox properties
301
+ const textBoxName = get(shape, "xdr:nvSpPr.xdr:cNvPr.a$.name") ||
302
+ get(shape, "nvSpPr.cNvPr.a$.name") ||
303
+ "TextBox";
304
+ const textBoxId = get(shape, "xdr:nvSpPr.xdr:cNvPr.a$.id") ||
305
+ get(shape, "nvSpPr.cNvPr.a$.id") ||
306
+ "";
307
+ // Extract explicit width/height from shape properties (similar to images)
308
+ const cxEmu = parseInt(get(shape, "xdr:spPr.a:xfrm.a:ext.a$.cx") ||
309
+ get(shape, "spPr.xfrm.ext.a$.cx") ||
310
+ "0");
311
+ const cyEmu = parseInt(get(shape, "xdr:spPr.a:xfrm.a:ext.a$.cy") ||
312
+ get(shape, "spPr.xfrm.ext.a$.cy") ||
313
+ "0");
314
+ // Convert EMUs to pixels and override position dimensions if available
315
+ if (cxEmu > 0 && cyEmu > 0) {
316
+ const width = emuToPixels(cxEmu);
317
+ const height = emuToPixels(cyEmu);
318
+ if (position.overlayPosition) {
319
+ position.overlayPosition.widthPixels = width;
320
+ position.overlayPosition.heightPixels = height;
321
+ }
322
+ }
323
+ // Parse text content and formatting
324
+ const textBoxSpec = parseTextBoxContent(txBody, shape);
325
+ images.push({
326
+ isInsideCell,
327
+ embedId: uuid(),
328
+ spec: textBoxSpec,
329
+ position,
330
+ draggable: true,
331
+ });
332
+ continue;
333
+ }
334
+ }
335
+ if (!picture)
336
+ continue;
337
+ // Get the embedded picture relationship ID with different possible paths
338
+ const blipRId = get(picture, "xdr:blipFill.a:blip.a$.embed") ||
339
+ get(picture, "xdr:blipFill.a:blip.a$.r:embed") ||
340
+ get(picture, "blipFill.a:blip.a$.embed") ||
341
+ get(picture, "blipFill.a:blip.a$.r:embed") ||
342
+ get(picture, "blipFill.blip.a$.embed") ||
343
+ get(picture, "blipFill.blip.a$.r:embed");
344
+ if (!blipRId)
345
+ continue;
346
+ // Get the name of the image if available - handle different path patterns
347
+ const imageName = get(picture, "xdr:nvPicPr.xdr:cNvPr.a$.name") ||
348
+ get(picture, "nvPicPr.cNvPr.a$.name") ||
349
+ "Image";
350
+ // Get the image ID - handle different path patterns
351
+ const imageId = get(picture, "xdr:nvPicPr.xdr:cNvPr.a$.id") ||
352
+ get(picture, "nvPicPr.cNvPr.a$.id") ||
353
+ "";
354
+ // Get title if available
355
+ const imageTitle = get(picture, "xdr:nvPicPr.xdr:cNvPr.a$.title") ||
356
+ get(picture, "nvPicPr.cNvPr.a$.title") ||
357
+ "";
358
+ // 3. Get the image file from the drawing relationships
359
+ const drawingDir = drawingPath.substring(0, drawingPath.lastIndexOf("/"));
360
+ const drawingFilename = drawingPath.split("/").pop();
361
+ const drawingRelsPath = `${drawingDir}/_rels/${drawingFilename}.rels`;
362
+ const drawingRelsContent = await zipParser.getText(drawingRelsPath);
363
+ if (!drawingRelsContent)
364
+ continue;
365
+ // Parse drawing relationships
366
+ const drawingRels = xmlParser.parse(drawingRelsContent);
367
+ const imageRelations = get(drawingRels, "Relationships.Relationship");
368
+ if (!imageRelations)
369
+ continue;
370
+ // Find the specific image relationship
371
+ const imageRel = Array.isArray(imageRelations)
372
+ ? imageRelations.find((rel) => rel.a$.Id === blipRId)
373
+ : imageRelations.a$.Id === blipRId
374
+ ? imageRelations
375
+ : null;
376
+ if (!imageRel)
377
+ continue;
378
+ // Get the target path of the image
379
+ const imageTarget = imageRel.a$.Target;
380
+ let imagePath;
381
+ // Handle different path formats
382
+ if (imageTarget.startsWith("/")) {
383
+ // Absolute path from the root of the zip
384
+ imagePath = imageTarget.substring(1);
385
+ }
386
+ else if (imageTarget.startsWith("../")) {
387
+ // Relative path going up directories
388
+ // Since drawingDir is something like 'xl/drawings',
389
+ // and '../media/image1.png' means 'xl/media/image1.png'
390
+ const baseDir = drawingDir.split("/").slice(0, -1).join("/");
391
+ imagePath = `${baseDir}/${imageTarget.replace("../", "")}`;
392
+ }
393
+ else {
394
+ // Relative path in the same directory
395
+ imagePath = `${drawingDir}/${imageTarget}`;
396
+ }
397
+ // 4. Get the actual image data
398
+ const imageData = await zipParser.getBinary(imagePath);
399
+ if (!imageData)
400
+ continue;
401
+ // Determine image type from the path
402
+ const imageExt = imagePath.split(".").pop()?.toLowerCase() || "";
403
+ const imageType = `image/${imageExt === "jpg" ? "jpeg" : imageExt}`;
404
+ // Add the image to our collection
405
+ images.push({
406
+ isInsideCell,
407
+ embedId: uuid(),
408
+ spec: {
409
+ id: imageId,
410
+ imageUrl: createDataUrl(imageData, imageType),
411
+ type: "image",
412
+ description: imageName,
413
+ },
414
+ position,
415
+ draggable: true,
416
+ lockAspectRatio: true,
417
+ });
418
+ }
419
+ return images;
420
+ }
421
+ /**
422
+ * Parse color from DrawingML color element
423
+ * Supports both RGB (srgbClr) and theme colors (schemeClr)
424
+ */
425
+ function parseDrawingColor(colorElement) {
426
+ if (!colorElement)
427
+ return undefined;
428
+ // RGB color
429
+ const srgbClr = get(colorElement, "a:srgbClr.a$.val");
430
+ if (srgbClr) {
431
+ return `#${srgbClr}`;
432
+ }
433
+ // Theme color - map to approximate RGB values
434
+ const schemeClr = get(colorElement, "a:schemeClr.a$.val");
435
+ if (schemeClr) {
436
+ // Basic theme color mapping (Office theme defaults)
437
+ const themeColorMap = {
438
+ accent1: "#4472C4",
439
+ accent2: "#ED7D31",
440
+ accent3: "#A5A5A5",
441
+ accent4: "#FFC000",
442
+ accent5: "#5B9BD5",
443
+ accent6: "#70AD47",
444
+ dk1: "#000000",
445
+ lt1: "#FFFFFF",
446
+ dk2: "#44546A",
447
+ lt2: "#E7E6E6",
448
+ hlink: "#0563C1",
449
+ folHlink: "#954F72",
450
+ };
451
+ return themeColorMap[schemeClr] || "#000000";
452
+ }
453
+ return undefined;
454
+ }
455
+ const toArray = (value) => Array.isArray(value) ? value : value ? [value] : [];
456
+ /** DrawingML scheme-color names → the spreadsheet theme's ColorIndex slots. */
457
+ const SCHEME_TO_THEME_INDEX = {
458
+ bg1: 0,
459
+ lt1: 0,
460
+ tx1: 1,
461
+ dk1: 1,
462
+ bg2: 2,
463
+ lt2: 2,
464
+ tx2: 3,
465
+ dk2: 3,
466
+ accent1: 4,
467
+ accent2: 5,
468
+ accent3: 6,
469
+ accent4: 7,
470
+ accent5: 8,
471
+ accent6: 9,
472
+ hlink: 10,
473
+ };
474
+ /** OOXML preset names → the renderer's preset union where they differ. */
475
+ const PRESET_RENAMES = {
476
+ rtTriangle: "rightTriangle",
477
+ snip1Rect: "snipSingleCornerRect",
478
+ };
479
+ /**
480
+ * Parse a DrawingML color element into a `Color` — a live theme reference
481
+ * (`{ theme, tint }`) for `<a:schemeClr>` (so the shape follows document theme
482
+ * changes, unlike {@link parseDrawingColor}'s baked-in hex), or a hex string
483
+ * for `<a:srgbClr>`. Luminance/tint modifiers map onto the theme tint:
484
+ * `lumOff`/`tint` lighten (accent1 "lighter 40%" = lumMod 60000 + lumOff 40000
485
+ * → tint 0.4), `shade`/`lumMod`-only darken.
486
+ */
487
+ function parseDrawingColorValue(colorElement) {
488
+ if (!colorElement)
489
+ return undefined;
490
+ const srgbClr = get(colorElement, "a:srgbClr.a$.val");
491
+ if (srgbClr)
492
+ return `#${srgbClr}`;
493
+ const schemeClr = get(colorElement, "a:schemeClr");
494
+ const schemeVal = get(schemeClr, "a$.val");
495
+ if (schemeVal) {
496
+ const theme = SCHEME_TO_THEME_INDEX[schemeVal];
497
+ if (theme === undefined) {
498
+ // Unmapped scheme name (e.g. folHlink): fall back to the baked hex.
499
+ return parseDrawingColor(colorElement);
500
+ }
501
+ const lumOff = parseInt(get(schemeClr, "a:lumOff.a$.val") || "0");
502
+ const tintVal = parseInt(get(schemeClr, "a:tint.a$.val") || "0");
503
+ const shade = parseInt(get(schemeClr, "a:shade.a$.val") || "0");
504
+ const lumMod = parseInt(get(schemeClr, "a:lumMod.a$.val") || "0");
505
+ let tint;
506
+ if (lumOff > 0)
507
+ tint = lumOff / 100000;
508
+ else if (tintVal > 0)
509
+ tint = tintVal / 100000;
510
+ else if (shade > 0)
511
+ tint = -(1 - shade / 100000);
512
+ else if (lumMod > 0 && lumMod < 100000)
513
+ tint = -(1 - lumMod / 100000);
514
+ return tint !== undefined ? { theme, tint } : { theme };
515
+ }
516
+ return undefined;
517
+ }
518
+ /** `<a:alpha val>` (1/100000) under a color element → 0–1 opacity, if reduced. */
519
+ function parseColorOpacity(colorElement) {
520
+ const alpha = parseInt(get(colorElement, "a:srgbClr.a:alpha.a$.val") ||
521
+ get(colorElement, "a:schemeClr.a:alpha.a$.val") ||
522
+ "0");
523
+ return alpha > 0 && alpha < 100000 ? alpha / 100000 : undefined;
524
+ }
525
+ /** `<a:prstGeom>` → geometry preset + `<a:avLst>` adjust guides. */
526
+ function parseShapeGeometry(spPr) {
527
+ const prstGeom = get(spPr, "a:prstGeom");
528
+ const prst = get(prstGeom, "a$.prst");
529
+ if (!prst)
530
+ return undefined;
531
+ let adjustments;
532
+ for (const gd of toArray(get(prstGeom, "a:avLst.a:gd"))) {
533
+ const name = get(gd, "a$.name");
534
+ const fmla = get(gd, "a$.fmla") || "";
535
+ const match = /^val\s+(-?\d+)$/.exec(fmla);
536
+ if (name && match) {
537
+ (adjustments ??= {})[name] = parseInt(match[1]);
538
+ }
539
+ }
540
+ return { preset: PRESET_RENAMES[prst] ?? prst, adjustments };
541
+ }
542
+ /** Empty elements (`<a:noFill/>`) parse to `""` — presence must not be truthiness. */
543
+ const hasElement = (obj, path) => get(obj, path) !== undefined;
544
+ /** Explicit `<a:noFill>`/`<a:solidFill>`/`<a:gradFill>` on `spPr` (style refs are separate). */
545
+ function parseShapeFill(spPr) {
546
+ if (hasElement(spPr, "a:noFill"))
547
+ return { kind: "none" };
548
+ const solidFill = get(spPr, "a:solidFill");
549
+ if (solidFill) {
550
+ const color = parseDrawingColorValue(solidFill);
551
+ if (color) {
552
+ return { kind: "solid", color, opacity: parseColorOpacity(solidFill) };
553
+ }
554
+ }
555
+ const gradFill = get(spPr, "a:gradFill");
556
+ if (gradFill) {
557
+ const stops = toArray(get(gradFill, "a:gsLst.a:gs"))
558
+ .map((gs) => ({
559
+ position: parseInt(get(gs, "a$.pos") || "0") / 100000,
560
+ color: parseDrawingColorValue(gs) ?? "#FFFFFF",
561
+ opacity: parseColorOpacity(gs),
562
+ }))
563
+ .sort((a, b) => a.position - b.position);
564
+ if (stops.length) {
565
+ const ang = parseInt(get(gradFill, "a:lin.a$.ang") || "0");
566
+ return {
567
+ kind: "gradient",
568
+ stops,
569
+ angle: ang ? ang / 60000 : 90,
570
+ shading: get(gradFill, "a:path") ? "radial" : "linear",
571
+ };
572
+ }
573
+ }
574
+ return undefined;
575
+ }
576
+ const DASH_RENAMES = {
577
+ solid: "solid",
578
+ dot: "dot",
579
+ sysDot: "dot",
580
+ dash: "dash",
581
+ sysDash: "dash",
582
+ dashDot: "dashDot",
583
+ sysDashDot: "dashDot",
584
+ lgDash: "longDash",
585
+ lgDashDot: "longDashDot",
586
+ lgDashDotDot: "longDashDotDot",
587
+ };
588
+ /** `<a:ln>` → outline; `<a:noFill>` inside it means explicitly strokeless (width 0). */
589
+ function parseShapeOutline(spPr) {
590
+ const ln = get(spPr, "a:ln");
591
+ if (ln === undefined)
592
+ return undefined;
593
+ if (hasElement(ln, "a:noFill"))
594
+ return { width: 0 };
595
+ const solidFill = get(ln, "a:solidFill");
596
+ const color = parseDrawingColorValue(solidFill);
597
+ const wEmu = parseInt(get(ln, "a$.w") || "0");
598
+ const dashVal = get(ln, "a:prstDash.a$.val");
599
+ if (!color && !wEmu && !dashVal)
600
+ return undefined;
601
+ return {
602
+ color,
603
+ width: wEmu ? emuToPixels(wEmu) : undefined,
604
+ dash: dashVal ? DASH_RENAMES[dashVal] : undefined,
605
+ opacity: solidFill ? parseColorOpacity(solidFill) : undefined,
606
+ };
607
+ }
608
+ /** `<a:effectLst><a:outerShdw>` → drop shadow (distance+direction → x/y offsets). */
609
+ function parseShapeShadow(spPr) {
610
+ const shdw = get(spPr, "a:effectLst.a:outerShdw");
611
+ if (!shdw)
612
+ return undefined;
613
+ const distPx = emuToPixels(parseInt(get(shdw, "a$.dist") || "0"));
614
+ const dirRad = (parseInt(get(shdw, "a$.dir") || "0") / 60000) * (Math.PI / 180);
615
+ const blurRad = parseInt(get(shdw, "a$.blurRad") || "0");
616
+ return {
617
+ color: parseDrawingColorValue(shdw),
618
+ opacity: parseColorOpacity(shdw),
619
+ blurRadius: blurRad ? emuToPixels(blurRad) : undefined,
620
+ offsetXPixels: distPx ? Math.round(Math.cos(dirRad) * distPx) : undefined,
621
+ offsetYPixels: distPx ? Math.round(Math.sin(dirRad) * distPx) : undefined,
622
+ };
623
+ }
624
+ /** `<xdr:style>` fill/line/effect/font references into the theme format scheme. */
625
+ function parseShapeStyleRefs(shape) {
626
+ const style = get(shape, "xdr:style") || get(shape, "style");
627
+ if (!style)
628
+ return undefined;
629
+ const parseRef = (name) => {
630
+ const ref = get(style, name);
631
+ if (!ref)
632
+ return undefined;
633
+ const index = parseInt(get(ref, "a$.idx") || "0");
634
+ const color = parseDrawingColorValue(ref);
635
+ return color ? { index, color } : undefined;
636
+ };
637
+ const refs = {
638
+ fill: parseRef("a:fillRef"),
639
+ line: parseRef("a:lnRef"),
640
+ effect: parseRef("a:effectRef"),
641
+ };
642
+ const fontRef = get(style, "a:fontRef");
643
+ if (fontRef) {
644
+ const scheme = get(fontRef, "a$.idx");
645
+ if (scheme === "major" || scheme === "minor") {
646
+ refs.font = { scheme, color: parseDrawingColorValue(fontRef) };
647
+ }
648
+ }
649
+ return refs.fill || refs.line || refs.effect || refs.font ? refs : undefined;
650
+ }
651
+ /**
652
+ * Whether an `<xdr:sp>` should import as a drawing shape (`EmbedShapeSpec`)
653
+ * rather than a textbox. Text boxes are excluded explicitly (`txBox="1"`), and
654
+ * a rect with no `<xdr:style>` block stays a textbox too — routing those to
655
+ * the shape renderer would repaint plain text notes with the default accent
656
+ * shape style.
657
+ */
658
+ export function isDrawingShape(shape) {
659
+ const txBox = get(shape, "xdr:nvSpPr.xdr:cNvSpPr.a$.txBox") ||
660
+ get(shape, "nvSpPr.cNvSpPr.a$.txBox");
661
+ if (txBox === "1" || txBox === true)
662
+ return false;
663
+ const spPr = get(shape, "xdr:spPr") || get(shape, "spPr");
664
+ const preset = get(spPr, "a:prstGeom.a$.prst");
665
+ if (preset && preset !== "rect")
666
+ return true;
667
+ return hasElement(shape, "xdr:style") || hasElement(shape, "style");
668
+ }
669
+ /** Parse an `<xdr:sp>` drawing shape into an {@link EmbedShapeSpec}. */
670
+ export function parseShapeSpec(shape) {
671
+ const spPr = get(shape, "xdr:spPr") || get(shape, "spPr");
672
+ const name = get(shape, "xdr:nvSpPr.xdr:cNvPr.a$.name") ||
673
+ get(shape, "nvSpPr.cNvPr.a$.name");
674
+ // Shape text rides the textbox content model; box-level background/borders
675
+ // are shape fill/outline concerns, so only the text fields carry over. An
676
+ // empty text body (Excel writes one on every shape) is omitted entirely.
677
+ let textBody;
678
+ const txBody = get(shape, "xdr:txBody") || get(shape, "txBody");
679
+ if (txBody) {
680
+ const tb = parseTextBoxContent(txBody, shape);
681
+ const hasText = Boolean(tb.text?.trim()) ||
682
+ Boolean(tb.richText?.some((run) => run.text.trim()));
683
+ if (hasText) {
684
+ textBody = {
685
+ text: tb.text,
686
+ richText: tb.richText,
687
+ textFormat: tb.textFormat,
688
+ verticalAlignment: tb.verticalAlignment,
689
+ horizontalAlignment: tb.horizontalAlignment,
690
+ wrapStrategy: tb.wrapStrategy,
691
+ textRotation: tb.textRotation,
692
+ padding: tb.padding,
693
+ };
694
+ }
695
+ }
696
+ const xfrm = get(spPr, "a:xfrm");
697
+ const flipH = get(xfrm, "a$.flipH");
698
+ const flipV = get(xfrm, "a$.flipV");
699
+ return {
700
+ type: "shape",
701
+ name,
702
+ geometry: parseShapeGeometry(spPr) ?? { preset: "rect" },
703
+ fill: parseShapeFill(spPr),
704
+ outline: parseShapeOutline(spPr),
705
+ shadow: parseShapeShadow(spPr),
706
+ styleRefs: parseShapeStyleRefs(shape),
707
+ textBody,
708
+ flipHorizontal: flipH === "1" || flipH === true ? true : undefined,
709
+ flipVertical: flipV === "1" || flipV === true ? true : undefined,
710
+ };
711
+ }
712
+ /**
713
+ * Parse textbox content from DrawingML text body
714
+ * @param txBody The text body element from DrawingML
715
+ * @param shape The shape element containing formatting properties
716
+ * @returns EmbedTextBoxSpec object
717
+ */
718
+ function parseTextBoxContent(txBody, shape) {
719
+ const richText = [];
720
+ let plainText = "";
721
+ // Get paragraphs
722
+ const paragraphs = get(txBody, "a:p") || [];
723
+ const paragraphArray = Array.isArray(paragraphs) ? paragraphs : [paragraphs];
724
+ for (const paragraph of paragraphArray) {
725
+ // Extract paragraph properties for indentation and bullets
726
+ const pPr = get(paragraph, "a:pPr") || {};
727
+ const indentEmu = parseInt(get(pPr, "a$.marL") || get(pPr, "a$.indent") || "0");
728
+ // Convert EMUs to approximate character spaces (roughly 90000 EMUs ≈ 1 character space)
729
+ const indentSpaces = Math.round(indentEmu / 90000);
730
+ // Check for bullets
731
+ let bulletChar = "";
732
+ const buChar = get(pPr, "a:buChar.a$.char");
733
+ const buAutoNum = get(pPr, "a:buAutoNum");
734
+ const buNone = get(pPr, "a:buNone");
735
+ if (!buNone) {
736
+ if (buChar) {
737
+ // Custom bullet character (e.g., "•", "-", etc.)
738
+ bulletChar = buChar + " ";
739
+ }
740
+ else if (buAutoNum) {
741
+ // Auto-numbered bullets (would need context to track numbering)
742
+ bulletChar = "• ";
743
+ }
744
+ }
745
+ // Get text runs
746
+ const runs = get(paragraph, "a:r") || [];
747
+ const runArray = Array.isArray(runs) ? runs : runs ? [runs] : [];
748
+ // Add indentation and bullet to the first run of the paragraph
749
+ let isFirstRun = true;
750
+ for (const run of runArray) {
751
+ let text = get(run, "a:t.t$") || get(run, "a:t") || "";
752
+ // Handle tab characters
753
+ const tabElements = get(run, "a:tab");
754
+ if (tabElements) {
755
+ const tabCount = Array.isArray(tabElements) ? tabElements.length : 1;
756
+ text = "\t".repeat(tabCount) + text;
757
+ }
758
+ // Add indentation and bullet to the first run
759
+ if (isFirstRun) {
760
+ if (indentSpaces > 0) {
761
+ const indent = " ".repeat(indentSpaces);
762
+ text = indent + text;
763
+ }
764
+ if (bulletChar) {
765
+ text = bulletChar + text;
766
+ }
767
+ isFirstRun = false;
768
+ }
769
+ plainText += text;
770
+ // Parse run properties
771
+ const rPr = get(run, "a:rPr") || {};
772
+ const format = {};
773
+ // Font size (in points * 100, e.g., 1100 = 11pt)
774
+ const sz = parseInt(get(rPr, "a$.sz") || "0");
775
+ if (sz > 0) {
776
+ format.fontSize = sz / 100;
777
+ }
778
+ // Bold
779
+ const bold = get(rPr, "a$.b");
780
+ if (bold === "1" || bold === true) {
781
+ format.bold = true;
782
+ }
783
+ // Italic
784
+ const italic = get(rPr, "a$.i");
785
+ if (italic === "1" || italic === true) {
786
+ format.italic = true;
787
+ }
788
+ // Underline
789
+ const underline = get(rPr, "a$.u");
790
+ if (underline && underline !== "none") {
791
+ format.underline = true;
792
+ }
793
+ // Strikethrough
794
+ const strike = get(rPr, "a$.strike");
795
+ if (strike && strike !== "noStrike") {
796
+ format.strikethrough = true;
797
+ }
798
+ // Font family
799
+ const fontFamily = get(rPr, "a:latin.a$.typeface");
800
+ if (fontFamily) {
801
+ format.fontFamily = fontFamily;
802
+ }
803
+ // Text color (supports RGB and theme colors)
804
+ const solidFill = get(rPr, "a:solidFill");
805
+ const color = parseDrawingColor(solidFill);
806
+ if (color) {
807
+ format.color = color;
808
+ }
809
+ richText.push({
810
+ text,
811
+ format: Object.keys(format).length > 0 ? format : undefined,
812
+ });
813
+ }
814
+ // Add paragraph break (newline) between paragraphs
815
+ if (paragraphArray.indexOf(paragraph) < paragraphArray.length - 1) {
816
+ plainText += "\n";
817
+ richText.push({ text: "\n" });
818
+ }
819
+ }
820
+ // Get shape properties for background, borders, etc.
821
+ const spPr = get(shape, "xdr:spPr") || get(shape, "spPr");
822
+ const spec = {
823
+ type: "textbox",
824
+ text: plainText,
825
+ richText: richText.length > 0 ? richText : undefined,
826
+ };
827
+ // Parse background color (supports RGB and theme colors)
828
+ const solidFill = get(spPr, "a:solidFill");
829
+ const bgColor = parseDrawingColor(solidFill);
830
+ if (bgColor) {
831
+ spec.backgroundColor = bgColor;
832
+ }
833
+ // Parse text alignment and other properties from body properties
834
+ const bodyPr = get(txBody, "a:bodyPr") || {};
835
+ const anchor = get(bodyPr, "a$.anchor");
836
+ if (anchor) {
837
+ // Map DrawingML anchor to our vertical alignment
838
+ const anchorMap = {
839
+ t: "top",
840
+ ctr: "middle",
841
+ b: "bottom",
842
+ };
843
+ spec.verticalAlignment = anchorMap[anchor];
844
+ }
845
+ // Parse wrap strategy
846
+ const wrap = get(bodyPr, "a$.wrap");
847
+ if (wrap) {
848
+ const wrapMap = {
849
+ square: "wrap",
850
+ none: "overflow",
851
+ };
852
+ spec.wrapStrategy = wrapMap[wrap];
853
+ }
854
+ // Parse padding (insets) - convert from EMUs to pixels
855
+ const lIns = parseInt(get(bodyPr, "a$.lIns") || "0");
856
+ const rIns = parseInt(get(bodyPr, "a$.rIns") || "0");
857
+ const tIns = parseInt(get(bodyPr, "a$.tIns") || "0");
858
+ const bIns = parseInt(get(bodyPr, "a$.bIns") || "0");
859
+ // Use average of insets as padding (or could store separately if needed)
860
+ const avgPadding = (lIns + rIns + tIns + bIns) / 4;
861
+ if (avgPadding > 0) {
862
+ spec.padding = emuToPixels(avgPadding);
863
+ }
864
+ return spec;
865
+ }
866
+ /**
867
+ * Determine if a two-cell anchored image is inside a cell
868
+ * @param editAs The editAs attribute value
869
+ * @param fromCol From column
870
+ * @param fromRow From row
871
+ * @param toCol To column
872
+ * @param toRow To row
873
+ * @returns Boolean indicating if image is inside a cell
874
+ */
875
+ function determineIfTwoCellInsideCell(editAs, fromCol, fromRow, toCol, toRow) {
876
+ // Two-cell anchors represent floating images in Excel. We only mark them as
877
+ // "cell" content when the rectangle is constrained to a single cell.
878
+ return fromCol === toCol && fromRow === toRow;
879
+ }
880
+ /**
881
+ * Determine if a oneCellAnchor image is inside a cell
882
+ * Using EMU values for accurate assessment
883
+ * @param fromColOff Column offset in EMUs
884
+ * @param fromRowOff Row offset in EMUs
885
+ * @param fLocksWithSheet Whether image locks with sheet
886
+ * @param cx Image width in EMUs
887
+ * @param cy Image height in EMUs
888
+ * @returns Boolean indicating if the image is inside a cell
889
+ */
890
+ export function determineIfOneCellInsideCell(fromColOff, fromRowOff, fLocksWithSheet, cx, cy) {
891
+ const widthPixels = emuToPixels(Math.max(0, cx));
892
+ const heightPixels = emuToPixels(Math.max(0, cy));
893
+ const exceedsCellSize = (!!widthPixels && widthPixels > DEFAULT_CELL_IMAGE_MAX_SIZE_PX) ||
894
+ (!!heightPixels && heightPixels > DEFAULT_CELL_IMAGE_MAX_SIZE_PX);
895
+ if (exceedsCellSize) {
896
+ return false;
897
+ }
898
+ if (fLocksWithSheet === "1") {
899
+ return true;
900
+ }
901
+ const offsetXPixels = Math.abs(emuToPixels(fromColOff));
902
+ const offsetYPixels = Math.abs(emuToPixels(fromRowOff));
903
+ return (offsetXPixels <= CELL_IMAGE_OFFSET_THRESHOLD_PX &&
904
+ offsetYPixels <= CELL_IMAGE_OFFSET_THRESHOLD_PX);
905
+ }