@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,493 @@
1
+ /// <reference path="../xlsx.d.ts" />
2
+ import { CFB } from "xlsx/xlsx.mjs";
3
+ import { sha1 } from "@noble/hashes/sha1";
4
+ import { sha256 } from "@noble/hashes/sha256";
5
+ import { sha384, sha512 } from "@noble/hashes/sha512";
6
+ import { cbc, ecb } from "@noble/ciphers/aes";
7
+ const BLOCK_KEY_VERIFIER_INPUT = new Uint8Array([
8
+ 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79,
9
+ ]);
10
+ const BLOCK_KEY_VERIFIER_HASH = new Uint8Array([
11
+ 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e,
12
+ ]);
13
+ const BLOCK_KEY_ENCRYPTION_KEY = new Uint8Array([
14
+ 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6,
15
+ ]);
16
+ export const LEGACY_XLS_UNSUPPORTED_MESSAGE = "This file is a legacy Excel 97-2003 (.xls) workbook, which is not supported. Please open it in Excel and save it as .xlsx, then try again.";
17
+ /**
18
+ * Inspects a CFB container's directory to decide whether it is an
19
+ * Office-encrypted OOXML package (`EncryptionInfo` stream present) or an
20
+ * unencrypted legacy BIFF `.xls` workbook (`Workbook`/`Book` stream present
21
+ * without `EncryptionInfo`). Returns "unknown" for anything else, including
22
+ * containers that fail to parse — callers should fall back to their existing
23
+ * behavior in that case.
24
+ */
25
+ export const detectCfbContainerKind = async (source) => {
26
+ try {
27
+ const buffer = source instanceof File ? await source.arrayBuffer() : source;
28
+ const cfb = CFB.read(new Uint8Array(buffer), { type: "array" });
29
+ const streamNames = new Set(cfb.FileIndex.map((entry) => entry.name));
30
+ if (streamNames.has("EncryptionInfo")) {
31
+ return "encrypted-ooxml";
32
+ }
33
+ if (streamNames.has("Workbook") || streamNames.has("Book")) {
34
+ return "legacy-xls";
35
+ }
36
+ return "unknown";
37
+ }
38
+ catch {
39
+ return "unknown";
40
+ }
41
+ };
42
+ export class CFBDecryptor {
43
+ /**
44
+ * Decrypts a CFB-encrypted XLSX file
45
+ * @param source The encrypted file or array buffer
46
+ * @param password The password to decrypt with
47
+ * @returns The decrypted XLSX data as ArrayBuffer
48
+ */
49
+ static async decrypt(source, password) {
50
+ // Read CFB structure
51
+ const buffer = source instanceof File ? await source.arrayBuffer() : source;
52
+ const uint8Array = new Uint8Array(buffer);
53
+ const cfb = CFB.read(uint8Array, { type: "array" });
54
+ // Dispatch on the EncryptionInfo version (MS-OFFCRYPTO): agile (4.4), standard AES (x.2 + fAES),
55
+ // or RC4 CryptoAPI (x.2 + fCryptoAPI). Extensible (x.3) and legacy schemes are unsupported.
56
+ const infoContent = this.getEncryptionInfoContent(cfb);
57
+ if (!infoContent) {
58
+ throw new Error("Could not parse encryption information");
59
+ }
60
+ const view = new DataView(infoContent.buffer, infoContent.byteOffset, infoContent.byteLength);
61
+ const versionMajor = view.getUint16(0, true);
62
+ const versionMinor = view.getUint16(2, true);
63
+ if (versionMajor === 4 && versionMinor === 4) {
64
+ return this.decryptAgile(cfb, password);
65
+ }
66
+ if (versionMinor === 2 && versionMajor >= 2 && versionMajor <= 4) {
67
+ return this.decryptStandardFamily(cfb, infoContent, password);
68
+ }
69
+ const detail = versionMinor === 3 ? " (extensible encryption)" : "";
70
+ throw new Error(`Unsupported workbook encryption version ${versionMajor}.${versionMinor}${detail}. ` +
71
+ `Supported: agile (4.4), standard AES (x.2), RC4 CryptoAPI.`);
72
+ }
73
+ static decryptAgile(cfb, password) {
74
+ const encryptionInfo = this.parseEncryptionInfo(cfb);
75
+ if (!encryptionInfo) {
76
+ throw new Error("Could not parse encryption information");
77
+ }
78
+ // Derive key from password
79
+ const passwordDerivedKey = this.deriveKey(password, encryptionInfo);
80
+ // Verify password by decrypting verifier
81
+ const isValid = this.verifyPassword(passwordDerivedKey, encryptionInfo);
82
+ if (!isValid) {
83
+ throw new Error("Incorrect password");
84
+ }
85
+ // Decrypt the encrypted key value to get the actual encryption key
86
+ const encryptionKey = this.decryptEncryptedKey(passwordDerivedKey, encryptionInfo);
87
+ // Decrypt the package using the decrypted encryption key
88
+ const encryptedPackage = this.getEncryptedPackage(cfb);
89
+ return this.decryptPackage(encryptedPackage, encryptionKey, encryptionInfo);
90
+ }
91
+ static getEncryptionInfoContent(cfb) {
92
+ const entry = cfb.FileIndex.find((e) => e.name === "EncryptionInfo");
93
+ if (!entry || !entry.content) {
94
+ return null;
95
+ }
96
+ const contentArray = entry.content;
97
+ return contentArray instanceof Uint8Array
98
+ ? contentArray
99
+ : new Uint8Array(contentArray);
100
+ }
101
+ // ── Standard (MS-OFFCRYPTO §2.3.4.5-9) & RC4 CryptoAPI (§2.3.5) ──────────────────
102
+ static decryptStandardFamily(cfb, infoContent, password) {
103
+ // `body` begins at the EncryptionHeaderFlags dword (after the 4-byte version).
104
+ const body = infoContent.subarray(4);
105
+ const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
106
+ const headerSize = dv.getUint32(4, true);
107
+ const header = body.subarray(8, 8 + headerSize);
108
+ const hdv = new DataView(header.buffer, header.byteOffset, header.byteLength);
109
+ const algId = hdv.getUint32(8, true);
110
+ const keySizeBits = hdv.getUint32(16, true);
111
+ const verifier = body.subarray(8 + headerSize);
112
+ const salt = verifier.subarray(4, 20);
113
+ const encryptedVerifier = verifier.subarray(20, 36);
114
+ // AES uses a 32-byte encrypted verifier hash (SHA1 padded to two blocks); RC4 uses 20.
115
+ const isAes = (algId & 0xff00) === 0x6600;
116
+ const isRc4 = algId === 0x6801 || algId === 0;
117
+ if (!isAes && !isRc4) {
118
+ throw new Error(`Unsupported workbook encryption cipher (algId 0x${algId.toString(16)}).`);
119
+ }
120
+ const vhashLen = isAes ? 32 : 20;
121
+ const encryptedVerifierHash = verifier.subarray(40, 40 + vhashLen);
122
+ const encryptedPackage = this.getEncryptedPackage(cfb);
123
+ if (isAes) {
124
+ const keyBytes = keySizeBits !== 0
125
+ ? keySizeBits / 8
126
+ : algId === 0x660e
127
+ ? 16
128
+ : algId === 0x660f
129
+ ? 24
130
+ : 32;
131
+ const key = this.standardKey(password, salt, keyBytes);
132
+ const verifierPlain = this.aesEcbDecrypt(encryptedVerifier, key);
133
+ const expected = this.hash(verifierPlain, "SHA1");
134
+ const stored = this.aesEcbDecrypt(encryptedVerifierHash, key);
135
+ if (!this.bytesEqual(expected, stored.subarray(0, expected.length))) {
136
+ throw new Error("Incorrect password");
137
+ }
138
+ return this.decryptStandardPackage(encryptedPackage, key);
139
+ }
140
+ // RC4 CryptoAPI: 40-bit keys are 5 significant bytes zero-padded to 16.
141
+ const keyBytes = keySizeBits === 40 || keySizeBits === 0 ? 5 : keySizeBits / 8;
142
+ const key0 = this.rc4CryptoApiKey(password, salt, keyBytes, 0);
143
+ const combined = this.rc4(key0, this.concatArrays(encryptedVerifier, encryptedVerifierHash));
144
+ const verifierPlain = combined.subarray(0, encryptedVerifier.length);
145
+ const storedHash = combined.subarray(encryptedVerifier.length);
146
+ if (!this.bytesEqual(this.hash(verifierPlain, "SHA1"), storedHash)) {
147
+ throw new Error("Incorrect password");
148
+ }
149
+ return this.decryptRc4Package(encryptedPackage, password, salt, keyBytes);
150
+ }
151
+ /** Standard key derivation (MS-OFFCRYPTO §2.3.4.7): iterated SHA1 then the X1‖X2 final block. */
152
+ static standardKey(password, salt, keyBytes) {
153
+ const SPIN_COUNT = 50000;
154
+ let h = this.hash(this.concatArrays(salt, this.stringToUtf16LE(password)), "SHA1");
155
+ for (let i = 0; i < SPIN_COUNT; i++) {
156
+ h = this.hash(this.concatArrays(this.le32(i), h), "SHA1");
157
+ }
158
+ const hfinal = this.hash(this.concatArrays(h, this.le32(0)), "SHA1");
159
+ const buf1 = new Uint8Array(64).fill(0x36);
160
+ const buf2 = new Uint8Array(64).fill(0x5c);
161
+ for (let i = 0; i < 20; i++) {
162
+ buf1[i] ^= hfinal[i];
163
+ buf2[i] ^= hfinal[i];
164
+ }
165
+ const x1 = this.hash(buf1, "SHA1");
166
+ const x2 = this.hash(buf2, "SHA1");
167
+ return this.concatArrays(x1, x2).slice(0, keyBytes);
168
+ }
169
+ static decryptStandardPackage(encryptedPackage, key) {
170
+ const sizeView = new DataView(encryptedPackage.buffer, encryptedPackage.byteOffset, 8);
171
+ const packageSize = Number(sizeView.getBigUint64(0, true));
172
+ const decrypted = this.aesEcbDecrypt(encryptedPackage.subarray(8), key);
173
+ const trimmed = decrypted.subarray(0, packageSize);
174
+ const result = new ArrayBuffer(trimmed.byteLength);
175
+ new Uint8Array(result).set(trimmed);
176
+ return result;
177
+ }
178
+ /** RC4 CryptoAPI key derivation (MS-OFFCRYPTO §2.3.5.2). */
179
+ static rc4CryptoApiKey(password, salt, keyBytes, block) {
180
+ const h0 = this.hash(this.concatArrays(salt, this.stringToUtf16LE(password)), "SHA1");
181
+ const hfinal = this.hash(this.concatArrays(h0, this.le32(block)), "SHA1");
182
+ if (keyBytes === 5) {
183
+ const key = new Uint8Array(16);
184
+ key.set(hfinal.subarray(0, 5));
185
+ return key;
186
+ }
187
+ return hfinal.subarray(0, keyBytes);
188
+ }
189
+ static decryptRc4Package(encryptedPackage, password, salt, keyBytes) {
190
+ const RC4_BLOCK_LENGTH = 512;
191
+ const sizeView = new DataView(encryptedPackage.buffer, encryptedPackage.byteOffset, 8);
192
+ const packageSize = Number(sizeView.getBigUint64(0, true));
193
+ const data = encryptedPackage.subarray(8);
194
+ const out = new Uint8Array(data.length);
195
+ // RC4 re-keys every 512 bytes of the encrypted package, using the block index.
196
+ for (let block = 0; block * RC4_BLOCK_LENGTH < data.length; block++) {
197
+ const start = block * RC4_BLOCK_LENGTH;
198
+ const end = Math.min(start + RC4_BLOCK_LENGTH, data.length);
199
+ const key = this.rc4CryptoApiKey(password, salt, keyBytes, block);
200
+ out.set(this.rc4(key, data.subarray(start, end)), start);
201
+ }
202
+ const trimmed = out.subarray(0, packageSize);
203
+ const result = new ArrayBuffer(trimmed.byteLength);
204
+ new Uint8Array(result).set(trimmed);
205
+ return result;
206
+ }
207
+ /** AES-ECB block decrypt (no padding). Trailing sub-block bytes are ignored. */
208
+ static aesEcbDecrypt(data, key) {
209
+ const aligned = data.length - (data.length % 16);
210
+ const cipher = ecb(key, { disablePadding: true });
211
+ return cipher.decrypt(data.subarray(0, aligned));
212
+ }
213
+ /** RC4 stream cipher (KSA + PRGA). Symmetric — the same op encrypts and decrypts. */
214
+ static rc4(key, data) {
215
+ const s = new Uint8Array(256);
216
+ for (let i = 0; i < 256; i++)
217
+ s[i] = i;
218
+ let j = 0;
219
+ for (let i = 0; i < 256; i++) {
220
+ j = (j + s[i] + key[i % key.length]) & 0xff;
221
+ const t = s[i];
222
+ s[i] = s[j];
223
+ s[j] = t;
224
+ }
225
+ const out = new Uint8Array(data.length);
226
+ let a = 0;
227
+ let b = 0;
228
+ for (let k = 0; k < data.length; k++) {
229
+ a = (a + 1) & 0xff;
230
+ b = (b + s[a]) & 0xff;
231
+ const t = s[a];
232
+ s[a] = s[b];
233
+ s[b] = t;
234
+ out[k] = data[k] ^ s[(s[a] + s[b]) & 0xff];
235
+ }
236
+ return out;
237
+ }
238
+ static le32(n) {
239
+ const b = new Uint8Array(4);
240
+ new DataView(b.buffer).setUint32(0, n >>> 0, true);
241
+ return b;
242
+ }
243
+ static bytesEqual(a, b) {
244
+ if (a.length !== b.length)
245
+ return false;
246
+ for (let i = 0; i < a.length; i++) {
247
+ if (a[i] !== b[i])
248
+ return false;
249
+ }
250
+ return true;
251
+ }
252
+ static parseEncryptionInfo(cfb) {
253
+ // Find EncryptionInfo stream
254
+ const encInfoEntry = cfb.FileIndex.find((entry) => entry.name === "EncryptionInfo");
255
+ if (!encInfoEntry || !encInfoEntry.content) {
256
+ return null;
257
+ }
258
+ // CFB library returns content as array, convert to Uint8Array with proper buffer
259
+ const contentArray = encInfoEntry.content;
260
+ const content = contentArray instanceof Uint8Array
261
+ ? contentArray
262
+ : new Uint8Array(contentArray);
263
+ // Create a new buffer to ensure we have a proper ArrayBuffer
264
+ const buffer = new ArrayBuffer(content.length);
265
+ const bufferView = new Uint8Array(buffer);
266
+ bufferView.set(content);
267
+ const view = new DataView(buffer);
268
+ // Read version info
269
+ const versionMajor = view.getUint16(0, true);
270
+ const versionMinor = view.getUint16(2, true);
271
+ // Only support Agile encryption (version 4.4)
272
+ if (versionMajor !== 4 || versionMinor !== 4) {
273
+ throw new Error(`Unsupported encryption version: ${versionMajor}.${versionMinor}. Only Agile encryption (4.4) is supported.`);
274
+ }
275
+ // Parse XML encryption descriptor (starts at byte 8)
276
+ const xmlBytes = content.slice(8);
277
+ const xmlString = new TextDecoder().decode(xmlBytes);
278
+ const encInfo = this.parseAgileEncryptionXml(xmlString);
279
+ return encInfo;
280
+ }
281
+ static parseAgileEncryptionXml(xml) {
282
+ // Simple XML parsing for encryption parameters
283
+ const getAttr = (tag, attr) => {
284
+ // Match tag with optional namespace prefix (p:, x:, etc.)
285
+ // Use non-greedy match to avoid consuming the target attribute
286
+ const regex = new RegExp(`<(?:\\w+:)?${tag}[^>]*?\\s+${attr}="([^"]*)"`, "i");
287
+ const match = xml.match(regex);
288
+ if (!match) {
289
+ console.warn(`Failed to find attribute ${attr} on tag ${tag}`);
290
+ // Try alternative: attribute might be first after tag name
291
+ const altRegex = new RegExp(`<(?:\\w+:)?${tag}\\s+${attr}="([^"]*)"`, "i");
292
+ const altMatch = xml.match(altRegex);
293
+ return altMatch ? altMatch[1] : "";
294
+ }
295
+ return match ? match[1] : "";
296
+ };
297
+ const getBase64 = (tag, attr) => {
298
+ const base64 = getAttr(tag, attr);
299
+ if (!base64) {
300
+ console.warn(`No base64 value found for ${tag}.${attr}`);
301
+ return new Uint8Array(0);
302
+ }
303
+ try {
304
+ const binary = atob(base64);
305
+ const bytes = new Uint8Array(binary.length);
306
+ for (let i = 0; i < binary.length; i++) {
307
+ bytes[i] = binary.charCodeAt(i);
308
+ }
309
+ return bytes;
310
+ }
311
+ catch (error) {
312
+ console.error(`Failed to decode base64 for ${tag}.${attr}:`, error);
313
+ return new Uint8Array(0);
314
+ }
315
+ };
316
+ const algorithm = getAttr("keyData", "cipherAlgorithm") || "AES";
317
+ const keySize = parseInt(getAttr("keyData", "keyBits") || "256") / 8;
318
+ const blockSize = parseInt(getAttr("keyData", "blockSize") || "16");
319
+ const hashAlgorithm = getAttr("keyData", "hashAlgorithm") || "SHA512";
320
+ const hashSize = parseInt(getAttr("keyData", "hashSize") || "64");
321
+ const saltSize = parseInt(getAttr("keyData", "saltSize") || "16");
322
+ // TWO different salts are used:
323
+ // 1. passwordSalt from encryptedKey - for password derivation and verification
324
+ // 2. packageSalt from keyData - for package decryption IVs
325
+ const passwordSalt = getBase64("encryptedKey", "saltValue");
326
+ const packageSalt = getBase64("keyData", "saltValue");
327
+ // Get values from p:encryptedKey element
328
+ const spinCount = parseInt(getAttr("encryptedKey", "spinCount") || "100000");
329
+ const encryptedVerifierHashInput = getBase64("encryptedKey", "encryptedVerifierHashInput");
330
+ const encryptedVerifierHashValue = getBase64("encryptedKey", "encryptedVerifierHashValue");
331
+ const encryptedKeyValue = getBase64("encryptedKey", "encryptedKeyValue");
332
+ // Validate that all required values were parsed
333
+ if (!passwordSalt.length || !packageSalt.length) {
334
+ throw new Error("Failed to parse salt values from encryption info");
335
+ }
336
+ if (!encryptedVerifierHashInput.length ||
337
+ !encryptedVerifierHashValue.length ||
338
+ !encryptedKeyValue.length) {
339
+ throw new Error("Failed to parse encrypted verifier values from encryption info");
340
+ }
341
+ return {
342
+ algorithm,
343
+ keySize,
344
+ blockSize,
345
+ hashAlgorithm,
346
+ hashSize,
347
+ saltSize,
348
+ passwordSalt,
349
+ packageSalt,
350
+ encryptedVerifierHashInput,
351
+ encryptedVerifierHashValue,
352
+ encryptedKeyValue,
353
+ spinCount,
354
+ };
355
+ }
356
+ static deriveKey(password, info) {
357
+ // Convert password to UTF-16LE
358
+ const passwordBytes = this.stringToUtf16LE(password);
359
+ // Initial hash H0 = H(passwordSalt + password)
360
+ // Use passwordSalt from encryptedKey, NOT packageSalt from keyData
361
+ let hash = this.hash(this.concatArrays(info.passwordSalt, passwordBytes), info.hashAlgorithm);
362
+ // Spin iteration: H(iterator + H(n-1))
363
+ for (let i = 0; i < info.spinCount; i++) {
364
+ const iterator = new Uint8Array(4);
365
+ new DataView(iterator.buffer).setUint32(0, i, true);
366
+ hash = this.hash(this.concatArrays(iterator, hash), info.hashAlgorithm);
367
+ }
368
+ // Return H_final (the result after spin iterations)
369
+ // Individual keys are derived from this using block keys
370
+ return hash;
371
+ }
372
+ static decryptEncryptedKey(passwordDerivedKey, info) {
373
+ const keyForKeyValue = this.deriveAgileBlockKey(passwordDerivedKey, BLOCK_KEY_ENCRYPTION_KEY, info);
374
+ // Agile encryption uses raw CBC block decryption (no PKCS padding).
375
+ const decryptedKey = this.decryptAESNoPadding(info.encryptedKeyValue, keyForKeyValue, info.passwordSalt.slice(0, 16));
376
+ return decryptedKey.slice(0, info.keySize);
377
+ }
378
+ static verifyPassword(passwordDerivedKey, info) {
379
+ try {
380
+ const keyForVerifierInput = this.deriveAgileBlockKey(passwordDerivedKey, BLOCK_KEY_VERIFIER_INPUT, info);
381
+ // Decrypt verifier hash input
382
+ const verifierHashInput = this.decryptAESNoPadding(info.encryptedVerifierHashInput, keyForVerifierInput, info.passwordSalt.slice(0, 16));
383
+ // Hash the decrypted verifier
384
+ const verifierHash = this.hash(verifierHashInput.slice(0, 16), info.hashAlgorithm);
385
+ const keyForVerifierValue = this.deriveAgileBlockKey(passwordDerivedKey, BLOCK_KEY_VERIFIER_HASH, info);
386
+ // Decrypt verifier hash value
387
+ const decryptedVerifierHash = this.decryptAESNoPadding(info.encryptedVerifierHashValue, keyForVerifierValue, info.passwordSalt.slice(0, 16));
388
+ // Compare hashes
389
+ const expectedHashLength = Math.min(info.hashSize, verifierHash.length, decryptedVerifierHash.length);
390
+ for (let i = 0; i < expectedHashLength; i++) {
391
+ if (verifierHash[i] !== decryptedVerifierHash[i]) {
392
+ return false;
393
+ }
394
+ }
395
+ return true;
396
+ }
397
+ catch (error) {
398
+ console.error("Password verification error:", error);
399
+ return false;
400
+ }
401
+ }
402
+ static getEncryptedPackage(cfb) {
403
+ const entry = cfb.FileIndex.find((e) => e.name === "EncryptedPackage" || e.name === "0EncryptedPackage");
404
+ if (!entry || !entry.content) {
405
+ throw new Error("EncryptedPackage stream not found");
406
+ }
407
+ // CFB library returns content as array, convert to proper Uint8Array
408
+ const contentArray = entry.content;
409
+ return contentArray instanceof Uint8Array
410
+ ? contentArray
411
+ : new Uint8Array(contentArray);
412
+ }
413
+ static decryptPackage(encrypted, key, info) {
414
+ // Read the package size from the first 8 bytes
415
+ const sizeView = new DataView(encrypted.buffer, encrypted.byteOffset, 8);
416
+ const packageSize = Number(sizeView.getBigUint64(0, true));
417
+ // Skip the first 8 bytes (package size) to get encrypted data
418
+ const encryptedData = encrypted.slice(8);
419
+ // MS-OFFCRYPTO uses segmented decryption with 4096-byte blocks
420
+ const SEGMENT_LENGTH = 4096;
421
+ const totalSegments = Math.ceil(encryptedData.length / SEGMENT_LENGTH);
422
+ const decryptedSegments = [];
423
+ for (let i = 0; i < totalSegments; i++) {
424
+ const start = i * SEGMENT_LENGTH;
425
+ const end = Math.min(start + SEGMENT_LENGTH, encryptedData.length);
426
+ const segment = encryptedData.slice(start, end);
427
+ // Generate IV for this segment: hash(packageSalt + block number)
428
+ // Use packageSalt from keyData, NOT passwordSalt from encryptedKey
429
+ const blockNumber = new Uint8Array(4);
430
+ new DataView(blockNumber.buffer).setUint32(0, i, true);
431
+ const ivInput = this.concatArrays(info.packageSalt, blockNumber);
432
+ const ivHash = this.hash(ivInput, info.hashAlgorithm);
433
+ const iv = ivHash.slice(0, 16); // Use first 16 bytes as IV
434
+ // Decrypt this segment
435
+ const decryptedSegment = this.decryptAESNoPadding(segment, key, iv);
436
+ decryptedSegments.push(decryptedSegment);
437
+ }
438
+ // Concatenate all decrypted segments
439
+ const totalLength = decryptedSegments.reduce((sum, seg) => sum + seg.length, 0);
440
+ const allDecrypted = new Uint8Array(totalLength);
441
+ let offset = 0;
442
+ for (const seg of decryptedSegments) {
443
+ allDecrypted.set(seg, offset);
444
+ offset += seg.length;
445
+ }
446
+ // Trim to actual package size (remove padding)
447
+ const trimmed = allDecrypted.slice(0, packageSize);
448
+ // Create a proper ArrayBuffer from the decrypted data
449
+ const result = new ArrayBuffer(trimmed.byteLength);
450
+ new Uint8Array(result).set(trimmed);
451
+ return result;
452
+ }
453
+ static decryptAESNoPadding(data, key, iv) {
454
+ const cipher = cbc(key, iv, { disablePadding: true });
455
+ return cipher.decrypt(data);
456
+ }
457
+ static deriveAgileBlockKey(passwordDerivedKey, blockKey, info) {
458
+ return this.hash(this.concatArrays(passwordDerivedKey, blockKey), info.hashAlgorithm).slice(0, info.keySize);
459
+ }
460
+ static hash(data, algorithm) {
461
+ switch (algorithm.toUpperCase()) {
462
+ case "SHA1":
463
+ return sha1(data);
464
+ case "SHA256":
465
+ return sha256(data);
466
+ case "SHA384":
467
+ return sha384(data);
468
+ case "SHA512":
469
+ return sha512(data);
470
+ default:
471
+ throw new Error(`Unsupported hash algorithm: ${algorithm}`);
472
+ }
473
+ }
474
+ static stringToUtf16LE(str) {
475
+ const bytes = new Uint8Array(str.length * 2);
476
+ for (let i = 0; i < str.length; i++) {
477
+ const code = str.charCodeAt(i);
478
+ bytes[i * 2] = code & 0xff;
479
+ bytes[i * 2 + 1] = (code >> 8) & 0xff;
480
+ }
481
+ return bytes;
482
+ }
483
+ static concatArrays(...arrays) {
484
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
485
+ const result = new Uint8Array(totalLength);
486
+ let offset = 0;
487
+ for (const arr of arrays) {
488
+ result.set(arr, offset);
489
+ offset += arr.length;
490
+ }
491
+ return result;
492
+ }
493
+ }
@@ -0,0 +1,23 @@
1
+ type EncryptOptions = {
2
+ spinCount?: number;
3
+ };
4
+ export declare class CFBEncryptor {
5
+ static encrypt(source: ArrayBuffer | Uint8Array, password: string, options?: EncryptOptions): Promise<Uint8Array>;
6
+ private static buildEncryptionInfoStream;
7
+ private static buildEncryptedPackageStream;
8
+ private static encryptPackage;
9
+ private static buildEncryptionXml;
10
+ private static derivePasswordKey;
11
+ private static deriveAgileBlockKey;
12
+ private static encryptDataIntegrityValue;
13
+ private static encryptAESNoPadding;
14
+ private static sha512Hash;
15
+ private static hmacSha512;
16
+ private static toBase64;
17
+ private static padToBlockSize;
18
+ private static stringToUtf16LE;
19
+ private static concatArrays;
20
+ private static randomBytes;
21
+ }
22
+ export {};
23
+ //# sourceMappingURL=cfb-encryptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cfb-encryptor.d.ts","sourceRoot":"","sources":["../../../excel-parser/cfb-encryptor.ts"],"names":[],"mappings":"AAMA,KAAK,cAAc,GAAG;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAwBF,qBAAa,YAAY;WACV,OAAO,CAClB,MAAM,EAAE,WAAW,GAAG,UAAU,EAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC;IA4FtB,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAWxC,OAAO,CAAC,MAAM,CAAC,2BAA2B;IAW1C,OAAO,CAAC,MAAM,CAAC,cAAc;IA0B7B,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA6CjC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAehC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAUlC,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAiBxC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IASlC,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB,OAAO,CAAC,MAAM,CAAC,QAAQ;IAQvB,OAAO,CAAC,MAAM,CAAC,cAAc;IAW7B,OAAO,CAAC,MAAM,CAAC,eAAe;IAU9B,OAAO,CAAC,MAAM,CAAC,YAAY;IAW3B,OAAO,CAAC,MAAM,CAAC,WAAW;CAc3B"}