@cj-tech-master/excelts 9.2.1 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/README.md +25 -2
  2. package/README_zh.md +29 -6
  3. package/dist/browser/index.browser.d.ts +1 -1
  4. package/dist/browser/index.browser.js +4 -0
  5. package/dist/browser/index.d.ts +1 -1
  6. package/dist/browser/index.js +4 -0
  7. package/dist/browser/modules/excel/cell.d.ts +17 -3
  8. package/dist/browser/modules/excel/cell.js +170 -22
  9. package/dist/browser/modules/excel/defined-names.d.ts +96 -1
  10. package/dist/browser/modules/excel/defined-names.js +411 -21
  11. package/dist/browser/modules/excel/image.d.ts +11 -0
  12. package/dist/browser/modules/excel/image.js +24 -1
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  14. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
  15. package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  17. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
  18. package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
  19. package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
  20. package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
  21. package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
  22. package/dist/browser/modules/excel/table.js +15 -2
  23. package/dist/browser/modules/excel/types.d.ts +133 -2
  24. package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
  25. package/dist/browser/modules/excel/utils/col-cache.js +15 -0
  26. package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
  27. package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
  28. package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
  29. package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
  30. package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
  31. package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
  32. package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
  33. package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
  34. package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
  35. package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
  36. package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
  37. package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
  38. package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
  39. package/dist/browser/modules/excel/workbook.browser.js +318 -34
  40. package/dist/browser/modules/excel/workbook.d.ts +1 -1
  41. package/dist/browser/modules/excel/worksheet.d.ts +3 -1
  42. package/dist/browser/modules/excel/worksheet.js +21 -2
  43. package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
  44. package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
  45. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  46. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  47. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  48. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  49. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  50. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  51. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  52. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  53. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  54. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  55. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  56. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  57. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  58. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  59. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  60. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  61. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  62. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  63. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  64. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  65. package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  66. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  67. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  68. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  69. package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  70. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  71. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
  72. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
  73. package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
  74. package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
  75. package/dist/browser/modules/formula/compile/address-utils.js +83 -0
  76. package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
  77. package/dist/browser/modules/formula/compile/binder.js +487 -0
  78. package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
  79. package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
  80. package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
  81. package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
  82. package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
  83. package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
  84. package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  85. package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
  86. package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
  87. package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
  88. package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
  89. package/dist/browser/modules/formula/functions/_date-context.js +29 -0
  90. package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
  91. package/dist/browser/modules/formula/functions/_shared.js +381 -0
  92. package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
  93. package/dist/browser/modules/formula/functions/conditional.js +343 -0
  94. package/dist/browser/modules/formula/functions/database.d.ts +37 -0
  95. package/dist/browser/modules/formula/functions/database.js +274 -0
  96. package/dist/browser/modules/formula/functions/date.d.ts +61 -0
  97. package/dist/browser/modules/formula/functions/date.js +855 -0
  98. package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
  99. package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
  100. package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
  101. package/dist/browser/modules/formula/functions/engineering.js +1128 -0
  102. package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
  103. package/dist/browser/modules/formula/functions/financial.js +2296 -0
  104. package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
  105. package/dist/browser/modules/formula/functions/lookup.js +886 -0
  106. package/dist/browser/modules/formula/functions/math.d.ts +114 -0
  107. package/dist/browser/modules/formula/functions/math.js +1406 -0
  108. package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
  109. package/dist/browser/modules/formula/functions/statistical.js +3390 -0
  110. package/dist/browser/modules/formula/functions/text.d.ts +86 -0
  111. package/dist/browser/modules/formula/functions/text.js +1845 -0
  112. package/dist/browser/modules/formula/host-registry.d.ts +53 -0
  113. package/dist/browser/modules/formula/host-registry.js +69 -0
  114. package/dist/browser/modules/formula/index.d.ts +39 -0
  115. package/dist/browser/modules/formula/index.js +49 -0
  116. package/dist/browser/modules/formula/install.d.ts +62 -0
  117. package/dist/browser/modules/formula/install.js +88 -0
  118. package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  119. package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
  120. package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  121. package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
  122. package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
  123. package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
  124. package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
  125. package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
  126. package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
  127. package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
  128. package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  129. package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
  130. package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  131. package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
  132. package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
  133. package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
  134. package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
  135. package/dist/browser/modules/formula/materialize/types.js +29 -0
  136. package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
  137. package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
  138. package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
  139. package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
  140. package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
  141. package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
  142. package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
  143. package/dist/browser/modules/formula/runtime/values.js +385 -0
  144. package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
  145. package/dist/browser/modules/formula/syntax/ast.js +28 -0
  146. package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
  147. package/dist/browser/modules/formula/syntax/parser.js +439 -0
  148. package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
  149. package/dist/browser/modules/formula/syntax/token-types.js +59 -0
  150. package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
  151. package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
  152. package/dist/browser/modules/pdf/excel-bridge.js +9 -0
  153. package/dist/cjs/index.js +4 -0
  154. package/dist/cjs/modules/excel/cell.js +170 -22
  155. package/dist/cjs/modules/excel/defined-names.js +411 -21
  156. package/dist/cjs/modules/excel/image.js +24 -1
  157. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
  158. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
  159. package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
  160. package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
  161. package/dist/cjs/modules/excel/table.js +15 -2
  162. package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
  163. package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
  164. package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
  165. package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
  166. package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
  167. package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
  168. package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
  169. package/dist/cjs/modules/excel/workbook.browser.js +318 -34
  170. package/dist/cjs/modules/excel/worksheet.js +20 -1
  171. package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
  172. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  173. package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
  174. package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
  175. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  176. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
  177. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  178. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
  179. package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
  180. package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
  181. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  182. package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  183. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  184. package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  185. package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
  186. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  187. package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  188. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
  189. package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
  190. package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
  191. package/dist/cjs/modules/formula/compile/binder.js +489 -0
  192. package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
  193. package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
  194. package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
  195. package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
  196. package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
  197. package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
  198. package/dist/cjs/modules/formula/functions/_shared.js +396 -0
  199. package/dist/cjs/modules/formula/functions/conditional.js +354 -0
  200. package/dist/cjs/modules/formula/functions/database.js +288 -0
  201. package/dist/cjs/modules/formula/functions/date.js +883 -0
  202. package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
  203. package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
  204. package/dist/cjs/modules/formula/functions/financial.js +2348 -0
  205. package/dist/cjs/modules/formula/functions/lookup.js +902 -0
  206. package/dist/cjs/modules/formula/functions/math.js +1487 -0
  207. package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
  208. package/dist/cjs/modules/formula/functions/text.js +1889 -0
  209. package/dist/cjs/modules/formula/host-registry.js +75 -0
  210. package/dist/cjs/modules/formula/index.js +58 -0
  211. package/dist/cjs/modules/formula/install.js +93 -0
  212. package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
  213. package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
  214. package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
  215. package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
  216. package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
  217. package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
  218. package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
  219. package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
  220. package/dist/cjs/modules/formula/materialize/types.js +32 -0
  221. package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
  222. package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
  223. package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
  224. package/dist/cjs/modules/formula/runtime/values.js +385 -0
  225. package/dist/cjs/modules/formula/syntax/ast.js +8 -0
  226. package/dist/cjs/modules/formula/syntax/parser.js +440 -0
  227. package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
  228. package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
  229. package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
  230. package/dist/esm/index.browser.js +4 -0
  231. package/dist/esm/index.js +4 -0
  232. package/dist/esm/modules/excel/cell.js +170 -22
  233. package/dist/esm/modules/excel/defined-names.js +411 -21
  234. package/dist/esm/modules/excel/image.js +24 -1
  235. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
  236. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
  237. package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
  238. package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
  239. package/dist/esm/modules/excel/table.js +15 -2
  240. package/dist/esm/modules/excel/utils/col-cache.js +15 -0
  241. package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
  242. package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
  243. package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
  244. package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
  245. package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
  246. package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
  247. package/dist/esm/modules/excel/workbook.browser.js +318 -34
  248. package/dist/esm/modules/excel/worksheet.js +21 -2
  249. package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
  250. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  251. package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  252. package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  253. package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  254. package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  255. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  256. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  257. package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  258. package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  259. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  260. package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  261. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  262. package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  263. package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  264. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  265. package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  266. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
  267. package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
  268. package/dist/esm/modules/formula/compile/address-utils.js +83 -0
  269. package/dist/esm/modules/formula/compile/binder.js +487 -0
  270. package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
  271. package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
  272. package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
  273. package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
  274. package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
  275. package/dist/esm/modules/formula/functions/_date-context.js +29 -0
  276. package/dist/esm/modules/formula/functions/_shared.js +381 -0
  277. package/dist/esm/modules/formula/functions/conditional.js +343 -0
  278. package/dist/esm/modules/formula/functions/database.js +274 -0
  279. package/dist/esm/modules/formula/functions/date.js +855 -0
  280. package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
  281. package/dist/esm/modules/formula/functions/engineering.js +1128 -0
  282. package/dist/esm/modules/formula/functions/financial.js +2296 -0
  283. package/dist/esm/modules/formula/functions/lookup.js +886 -0
  284. package/dist/esm/modules/formula/functions/math.js +1406 -0
  285. package/dist/esm/modules/formula/functions/statistical.js +3390 -0
  286. package/dist/esm/modules/formula/functions/text.js +1845 -0
  287. package/dist/esm/modules/formula/host-registry.js +69 -0
  288. package/dist/esm/modules/formula/index.js +49 -0
  289. package/dist/esm/modules/formula/install.js +88 -0
  290. package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
  291. package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
  292. package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
  293. package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
  294. package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
  295. package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
  296. package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
  297. package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
  298. package/dist/esm/modules/formula/materialize/types.js +29 -0
  299. package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
  300. package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
  301. package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
  302. package/dist/esm/modules/formula/runtime/values.js +385 -0
  303. package/dist/esm/modules/formula/syntax/ast.js +28 -0
  304. package/dist/esm/modules/formula/syntax/parser.js +439 -0
  305. package/dist/esm/modules/formula/syntax/token-types.js +59 -0
  306. package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
  307. package/dist/esm/modules/pdf/excel-bridge.js +9 -0
  308. package/dist/iife/excelts.iife.js +2302 -373
  309. package/dist/iife/excelts.iife.js.map +1 -1
  310. package/dist/iife/excelts.iife.min.js +34 -34
  311. package/dist/types/index.browser.d.ts +1 -1
  312. package/dist/types/index.d.ts +1 -1
  313. package/dist/types/modules/excel/cell.d.ts +17 -3
  314. package/dist/types/modules/excel/defined-names.d.ts +96 -1
  315. package/dist/types/modules/excel/image.d.ts +11 -0
  316. package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  317. package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
  318. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  319. package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
  320. package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
  321. package/dist/types/modules/excel/types.d.ts +133 -2
  322. package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
  323. package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
  324. package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
  325. package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
  326. package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
  327. package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
  328. package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
  329. package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
  330. package/dist/types/modules/excel/workbook.d.ts +1 -1
  331. package/dist/types/modules/excel/worksheet.d.ts +3 -1
  332. package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
  333. package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  334. package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  335. package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  336. package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  337. package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  338. package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  339. package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  340. package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  341. package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  342. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  343. package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
  344. package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
  345. package/dist/types/modules/formula/compile/binder.d.ts +42 -0
  346. package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
  347. package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
  348. package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
  349. package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  350. package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
  351. package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
  352. package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
  353. package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
  354. package/dist/types/modules/formula/functions/database.d.ts +37 -0
  355. package/dist/types/modules/formula/functions/date.d.ts +61 -0
  356. package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
  357. package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
  358. package/dist/types/modules/formula/functions/financial.d.ts +202 -0
  359. package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
  360. package/dist/types/modules/formula/functions/math.d.ts +114 -0
  361. package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
  362. package/dist/types/modules/formula/functions/text.d.ts +86 -0
  363. package/dist/types/modules/formula/host-registry.d.ts +53 -0
  364. package/dist/types/modules/formula/index.d.ts +39 -0
  365. package/dist/types/modules/formula/install.d.ts +62 -0
  366. package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  367. package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  368. package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
  369. package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
  370. package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
  371. package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  372. package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  373. package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
  374. package/dist/types/modules/formula/materialize/types.d.ts +179 -0
  375. package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
  376. package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
  377. package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
  378. package/dist/types/modules/formula/runtime/values.d.ts +211 -0
  379. package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
  380. package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
  381. package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
  382. package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
  383. package/package.json +28 -28
@@ -4,10 +4,226 @@ exports.DefinedNames = void 0;
4
4
  const range_1 = require("./range.js");
5
5
  const cell_matrix_1 = require("./utils/cell-matrix.js");
6
6
  const col_cache_1 = require("./utils/col-cache.js");
7
+ const default_syntax_probe_1 = require("../formula/default-syntax-probe.js");
7
8
  const rangeRegexp = /[$](\w+)[$](\d+)(:[$](\w+)[$](\d+))?/;
9
+ // ============================================================================
10
+ // Range validation helpers (moved from defined-name-xform.ts)
11
+ // ============================================================================
12
+ // Regex to validate cell range format:
13
+ // - Cell: $A$1 or A1
14
+ // - Range: $A$1:$B$10 or A1:B10
15
+ // - Row range: $1:$2 (for print titles)
16
+ // - Column range: $A:$B (for print titles)
17
+ const cellRangeRegexp = /^[$]?[A-Za-z]{1,3}[$]?\d+(:[$]?[A-Za-z]{1,3}[$]?\d+)?$/;
18
+ const rowRangeRegexp = /^[$]?\d+:[$]?\d+$/;
19
+ const colRangeRegexp = /^[$]?[A-Za-z]{1,3}:[$]?[A-Za-z]{1,3}$/;
20
+ function isValidRange(range) {
21
+ // Skip array constants wrapped in {} - these are not valid cell ranges
22
+ if (range.startsWith("{") || range.endsWith("}")) {
23
+ return false;
24
+ }
25
+ // Extract the cell reference part (after the sheet name if present)
26
+ const cellRef = range.split("!").pop() ?? "";
27
+ // Must match one of the valid patterns
28
+ if (!cellRangeRegexp.test(cellRef) &&
29
+ !rowRangeRegexp.test(cellRef) &&
30
+ !colRangeRegexp.test(cellRef)) {
31
+ return false;
32
+ }
33
+ try {
34
+ const decoded = col_cache_1.colCache.decodeEx(range);
35
+ if (("row" in decoded && typeof decoded.row === "number") ||
36
+ ("top" in decoded && typeof decoded.top === "number") ||
37
+ ("left" in decoded && typeof decoded.left === "number")) {
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ /**
47
+ * Extract valid cell/range references from a raw defined name text string.
48
+ * Handles comma-separated ranges and quoted sheet names that may contain commas.
49
+ */
50
+ function extractRanges(parsedText) {
51
+ const trimmed = parsedText.trim();
52
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
53
+ return [];
54
+ }
55
+ const ranges = [];
56
+ let quotesOpened = false;
57
+ let last = "";
58
+ parsedText.split(",").forEach(item => {
59
+ if (!item) {
60
+ return;
61
+ }
62
+ const quotes = (item.match(/'/g) ?? []).length;
63
+ if (!quotes) {
64
+ if (quotesOpened) {
65
+ last += `${item},`;
66
+ }
67
+ else if (isValidRange(item)) {
68
+ ranges.push(item);
69
+ }
70
+ return;
71
+ }
72
+ const quotesEven = quotes % 2 === 0;
73
+ if (!quotesOpened && quotesEven && isValidRange(item)) {
74
+ ranges.push(item);
75
+ }
76
+ else if (quotesOpened && !quotesEven) {
77
+ quotesOpened = false;
78
+ if (isValidRange(last + item)) {
79
+ ranges.push(last + item);
80
+ }
81
+ last = "";
82
+ }
83
+ else {
84
+ quotesOpened = true;
85
+ last += `${item},`;
86
+ }
87
+ });
88
+ return ranges;
89
+ }
90
+ // ============================================================================
91
+ // Classifier — Stage 2 of the two-phase defined name design
92
+ // ============================================================================
93
+ /**
94
+ * Check whether a string contains a '(' character outside of single-quoted
95
+ * sheet name segments. Sheet names in cell references use single quotes:
96
+ * e.g. `'Sheet (1)'!$A$1` — the '(' is inside quotes and does NOT indicate
97
+ * a function call. A genuine formula like `OFFSET(Sheet1!$A$1,0,0,3,1)`
98
+ * has '(' outside of any quotes.
99
+ */
100
+ function hasUnquotedParen(s) {
101
+ let inQuote = false;
102
+ for (let i = 0; i < s.length; i++) {
103
+ const ch = s[i];
104
+ if (ch === "'") {
105
+ inQuote = !inQuote;
106
+ }
107
+ else if (ch === "(" && !inQuote) {
108
+ return true;
109
+ }
110
+ }
111
+ return false;
112
+ }
113
+ /**
114
+ * Classify a raw defined name text into one of three categories:
115
+ * 1. **reference** — pure cell/range union (goes into matrixMap)
116
+ * 2. **formula** — parseable expression (goes into formulaMap)
117
+ * 3. **opaque** — unrecognised content preserved for round-trip
118
+ *
119
+ * Classification order matters:
120
+ * - If the text contains an unquoted `(`, it is likely a formula — try the
121
+ * formula parser first (this prevents `extractRanges` from misinterpreting
122
+ * function arguments as partial range references).
123
+ * - Otherwise try to extract ranges (pure cell references).
124
+ * - If neither works, fall back to opaque.
125
+ *
126
+ * **Probe semantics:** `probe` is the formula tokenizer+parser oracle. It
127
+ * is the *only* authority for deciding whether a non-range, non-wrapper
128
+ * string is a formula. When `probe` is `null` (no formula engine
129
+ * installed and no probe injected), any such string is classified as
130
+ * **opaque** — we have no evidence it is a formula, and leaving it
131
+ * opaque preserves round-trip bytes via `rawText`.
132
+ *
133
+ * This function is pure: the classification of a given input depends
134
+ * entirely on (rawText, ranges, probe) and no global state. Two calls
135
+ * with the same arguments always produce the same result.
136
+ */
137
+ function classifyDefinedName(rawText, ranges, probe) {
138
+ // If rawText is missing, fall back to existing ranges (programmatic API path)
139
+ if (rawText === undefined) {
140
+ if (ranges.length > 0) {
141
+ return { kind: "reference", ranges };
142
+ }
143
+ return { kind: "opaque", ranges: [] };
144
+ }
145
+ const trimmed = rawText.trim();
146
+ if (trimmed.length === 0) {
147
+ return { kind: "opaque", ranges: [] };
148
+ }
149
+ // Opaque-looking wrappers — array constants, string literals, error
150
+ // values — are preserved verbatim and never routed through formula
151
+ // parsing. Detect them once, up front.
152
+ const isArrayConst = trimmed.startsWith("{") && trimmed.endsWith("}");
153
+ const isStringLit = trimmed.startsWith('"') && trimmed.endsWith('"');
154
+ const isErrorVal = trimmed.startsWith("#");
155
+ const isOpaqueWrapper = isArrayConst || isStringLit || isErrorVal;
156
+ const hasParen = hasUnquotedParen(trimmed);
157
+ // If the text contains an unquoted parenthesis (e.g. OFFSET(...),
158
+ // LAMBDA(...)), it is either a formula or a malformed expression —
159
+ // never a cell-range union. `extractRanges` is not safe to call on
160
+ // such text because it splits on commas and can mis-identify
161
+ // `OFFSET(Sheet1` as a partial range reference.
162
+ //
163
+ // With a probe: confirm the expression parses before classifying as
164
+ // formula; if the probe rejects it, fall through to opaque.
165
+ // Without a probe: we cannot confirm it parses, so preserve the text
166
+ // verbatim as opaque. This is deliberately strict — the alternative
167
+ // (silently promoting unverified text to `formula`) produced
168
+ // classification results that depended on global install state.
169
+ if (hasParen && !isOpaqueWrapper) {
170
+ if (probe && probe(trimmed)) {
171
+ return { kind: "formula", ranges: [trimmed], formulaExpression: trimmed };
172
+ }
173
+ return { kind: "opaque", ranges: [] };
174
+ }
175
+ // Try to extract cell/range references (handles comma-separated
176
+ // multi-area names). Safe to call only after the paren check above,
177
+ // because `extractRanges` splits on commas.
178
+ const extracted = extractRanges(rawText);
179
+ if (extracted.length > 0) {
180
+ return { kind: "reference", ranges: extracted };
181
+ }
182
+ // Opaque wrappers that didn't pass as a formula above classify
183
+ // straight to opaque — we preserve them verbatim without calculating.
184
+ if (isOpaqueWrapper) {
185
+ return { kind: "opaque", ranges: [] };
186
+ }
187
+ // No parens and not a range — could still be a parseable constant
188
+ // expression or a reference to another defined name. Only classify as
189
+ // formula if a probe can confirm it parses; otherwise stay opaque so
190
+ // round-trip text is preserved without silently promoting unparseable
191
+ // content to the formula bucket.
192
+ if (probe && probe(trimmed)) {
193
+ return { kind: "formula", ranges: [trimmed], formulaExpression: trimmed };
194
+ }
195
+ // Nothing worked — opaque
196
+ return { kind: "opaque", ranges: [] };
197
+ }
198
+ // ============================================================================
199
+ // Internal Key — disambiguates same-name entries with different scopes
200
+ // ============================================================================
201
+ /**
202
+ * Build the internal storage key for a defined name entry.
203
+ * Workbook-scoped: just the bare name.
204
+ * Sheet-scoped: `"name\0sheetId"` (null char separator avoids collisions).
205
+ */
206
+ function storageKey(name, localSheetId) {
207
+ return localSheetId !== undefined ? `${name}\0${localSheetId}` : name;
208
+ }
209
+ // ============================================================================
210
+ // DefinedNames class
211
+ // ============================================================================
8
212
  class DefinedNames {
9
- constructor() {
213
+ /**
214
+ * @param probe Optional formula-syntax probe used when classifying
215
+ * defined-name text. Injecting a probe here makes classification
216
+ * deterministic for this instance regardless of process-global
217
+ * `installFormulaEngine()` state. When omitted, the instance defers
218
+ * to the default probe at classification time (see `set model`).
219
+ */
220
+ constructor(probe) {
10
221
  this.matrixMap = {};
222
+ this.formulaMap = {};
223
+ this.localSheetIdMap = {};
224
+ this.opaqueMap = {};
225
+ this.nameForKey = {};
226
+ this._explicitProbe = probe ?? null;
11
227
  }
12
228
  getMatrix(name) {
13
229
  const matrix = this.matrixMap[name] || (this.matrixMap[name] = new cell_matrix_1.CellMatrix());
@@ -19,6 +235,11 @@ class DefinedNames {
19
235
  if ("error" in location) {
20
236
  return; // Invalid reference, skip
21
237
  }
238
+ // A name is either cell-reference or formula — clear any formula/opaque binding
239
+ // (programmatic API always operates on workbook-scoped names)
240
+ delete this.formulaMap[name];
241
+ delete this.opaqueMap[name];
242
+ this.nameForKey[name] = name;
22
243
  this.addEx(location, name);
23
244
  }
24
245
  addEx(location, name) {
@@ -42,6 +263,24 @@ class DefinedNames {
42
263
  matrix.addCellEx(location);
43
264
  }
44
265
  }
266
+ /**
267
+ * Register a formula-based defined name.
268
+ *
269
+ * Unlike `add()` which binds a name to a cell/range reference, this binds
270
+ * a name to an arbitrary formula expression that will be evaluated at
271
+ * calculation time.
272
+ *
273
+ * @param name - The defined name (e.g. "MyArray")
274
+ * @param expression - The formula expression (e.g. "{1,2;3,4}", "LAMBDA(x,y,x+y)")
275
+ */
276
+ addFormula(name, expression) {
277
+ // A name is either formula or cell-reference — clear any cell-reference/opaque binding
278
+ // (programmatic API always operates on workbook-scoped names)
279
+ delete this.matrixMap[name];
280
+ delete this.opaqueMap[name];
281
+ this.nameForKey[name] = name;
282
+ this.formulaMap[name] = expression;
283
+ }
45
284
  remove(locStr, name) {
46
285
  const location = col_cache_1.colCache.decodeEx(locStr);
47
286
  if ("error" in location) {
@@ -89,9 +328,10 @@ class DefinedNames {
89
328
  });
90
329
  }
91
330
  forEach(callback) {
92
- Object.entries(this.matrixMap).forEach(([name, matrix]) => {
331
+ Object.entries(this.matrixMap).forEach(([sKey, matrix]) => {
332
+ const bareName = this.nameForKey[sKey] ?? sKey;
93
333
  matrix.forEach((cell) => {
94
- callback(name, cell);
334
+ callback(bareName, cell);
95
335
  });
96
336
  });
97
337
  }
@@ -105,20 +345,73 @@ class DefinedNames {
105
345
  }
106
346
  getNamesEx(address) {
107
347
  return Object.entries(this.matrixMap)
108
- .map(([name, matrix]) => matrix.findCellEx(address, false) && name)
348
+ .map(([sKey, matrix]) => matrix.findCellEx(address, false) && (this.nameForKey[sKey] ?? sKey))
109
349
  .filter((name) => Boolean(name));
110
350
  }
351
+ /**
352
+ * Return all defined name entries in this collection, including scope info.
353
+ * Each entry has the bare name and optional localSheetId.
354
+ * Same bare name may appear multiple times with different scopes.
355
+ */
356
+ getAllNames() {
357
+ return this.getAllEntries().map(e => e.localSheetId !== undefined
358
+ ? { name: e.name, localSheetId: e.localSheetId }
359
+ : { name: e.name });
360
+ }
361
+ /**
362
+ * Return all defined name entries with full details (name, ranges, scope).
363
+ *
364
+ * This is the primary enumeration API. Each entry is self-contained —
365
+ * no second lookup is needed. Same bare name may appear multiple times
366
+ * with different scopes.
367
+ */
368
+ getAllEntries() {
369
+ const result = [];
370
+ const seen = new Set();
371
+ for (const sKey of Object.keys(this.matrixMap)) {
372
+ if (seen.has(sKey)) {
373
+ continue;
374
+ }
375
+ seen.add(sKey);
376
+ const model = this.getRanges(sKey);
377
+ const localSheetId = this.localSheetIdMap[sKey];
378
+ result.push(localSheetId !== undefined ? { ...model, localSheetId } : model);
379
+ }
380
+ for (const sKey of Object.keys(this.formulaMap)) {
381
+ if (seen.has(sKey)) {
382
+ continue;
383
+ }
384
+ seen.add(sKey);
385
+ const model = this.getRanges(sKey);
386
+ const localSheetId = this.localSheetIdMap[sKey];
387
+ result.push(localSheetId !== undefined ? { ...model, localSheetId } : model);
388
+ }
389
+ for (const sKey of Object.keys(this.opaqueMap)) {
390
+ if (seen.has(sKey)) {
391
+ continue;
392
+ }
393
+ seen.add(sKey);
394
+ const bareName = this.nameForKey[sKey] ?? sKey;
395
+ const entry = this.opaqueMap[sKey];
396
+ result.push({
397
+ name: bareName,
398
+ ranges: [],
399
+ rawText: entry.rawText,
400
+ localSheetId: entry.localSheetId,
401
+ kind: "opaque"
402
+ });
403
+ }
404
+ return result;
405
+ }
111
406
  _explore(matrix, cell) {
112
407
  cell.mark = false;
113
- const sheetName = cell.sheetName; // Always set for cells in defined names
408
+ const sheetName = cell.sheetName;
114
409
  const range = new range_1.Range(cell.row, cell.col, cell.row, cell.col, sheetName);
115
410
  let x;
116
411
  let y;
117
- // Helper to get cell with proper type
118
412
  const getCell = (row, col) => {
119
413
  return matrix.findCellAt(sheetName, row, col);
120
414
  };
121
- // grow vertical - only one col to worry about
122
415
  function vGrow(yy, edge) {
123
416
  const c = getCell(yy, cell.col);
124
417
  if (!c || !c.mark) {
@@ -134,7 +427,6 @@ class DefinedNames {
134
427
  for (y = cell.row + 1; vGrow(y, "bottom"); y++) {
135
428
  /* advance */
136
429
  }
137
- // grow horizontal - ensure all rows can grow
138
430
  function hGrow(xx, edge) {
139
431
  const cells = [];
140
432
  for (y = range.top; y <= range.bottom; y++) {
@@ -160,10 +452,28 @@ class DefinedNames {
160
452
  }
161
453
  return range;
162
454
  }
455
+ /**
456
+ * Get ranges for a specific scoped entry.
457
+ *
458
+ * Unlike `getRanges(name)` which uses the bare name (and may hit the
459
+ * wrong scope when the same name exists both globally and locally),
460
+ * this method uses the internal `storageKey` to look up the exact entry.
461
+ */
462
+ getRangesScoped(name, localSheetId) {
463
+ const sKey = storageKey(name, localSheetId);
464
+ return this.getRanges(sKey);
465
+ }
163
466
  getRanges(name, matrix) {
467
+ // `name` can be a bare name (backward compat) or a storageKey.
468
+ // Try storageKey first, then bare name (workbook-scoped).
469
+ const formula = this.formulaMap[name];
164
470
  matrix = matrix || this.matrixMap[name];
471
+ const bareName = this.nameForKey[name] ?? name;
165
472
  if (!matrix) {
166
- return { name, ranges: [] };
473
+ if (formula) {
474
+ return { name: bareName, ranges: [formula], formulaExpression: formula };
475
+ }
476
+ return { name: bareName, ranges: [] };
167
477
  }
168
478
  // mark and sweep!
169
479
  matrix.forEach((cell) => {
@@ -174,7 +484,7 @@ class DefinedNames {
174
484
  .filter((range) => Boolean(range))
175
485
  .map((range) => range.$shortRange);
176
486
  return {
177
- name,
487
+ name: bareName,
178
488
  ranges
179
489
  };
180
490
  }
@@ -204,22 +514,102 @@ class DefinedNames {
204
514
  });
205
515
  }
206
516
  get model() {
207
- // To get names per cell - just iterate over all names finding cells if they exist
208
- return Object.entries(this.matrixMap)
209
- .map(([name, matrix]) => this.getRanges(name, matrix))
517
+ // Cell-reference based names from matrixMap
518
+ const cellNames = Object.entries(this.matrixMap)
519
+ .map(([sKey, matrix]) => {
520
+ const result = this.getRanges(sKey, matrix);
521
+ const localSheetId = this.localSheetIdMap[sKey];
522
+ if (localSheetId !== undefined) {
523
+ return { ...result, localSheetId };
524
+ }
525
+ return result;
526
+ })
210
527
  .filter((definedName) => definedName.ranges.length);
528
+ // Formula-based names from formulaMap (only include names not already in matrixMap)
529
+ const formulaNames = Object.entries(this.formulaMap)
530
+ .filter(([sKey]) => !this.matrixMap[sKey])
531
+ .map(([sKey, expression]) => {
532
+ const bareName = this.nameForKey[sKey] ?? sKey;
533
+ const result = {
534
+ name: bareName,
535
+ ranges: [expression],
536
+ formulaExpression: expression
537
+ };
538
+ const localSheetId = this.localSheetIdMap[sKey];
539
+ if (localSheetId !== undefined) {
540
+ return { ...result, localSheetId };
541
+ }
542
+ return result;
543
+ });
544
+ // Opaque names — rawText preserved for round-trip
545
+ const opaqueNames = Object.entries(this.opaqueMap).map(([sKey, entry]) => {
546
+ const bareName = this.nameForKey[sKey] ?? sKey;
547
+ return {
548
+ name: bareName,
549
+ ranges: [],
550
+ rawText: entry.rawText,
551
+ localSheetId: entry.localSheetId,
552
+ kind: "opaque"
553
+ };
554
+ });
555
+ return [...cellNames, ...formulaNames, ...opaqueNames];
211
556
  }
557
+ /**
558
+ * Deserialise an array of `DefinedNameModel` entries (typically from XLSX parsing).
559
+ *
560
+ * Stage 2 of the two-phase design: each entry's `rawText` is classified
561
+ * into reference / formula / opaque by `classifyDefinedName()`. Entries
562
+ * that arrive without `rawText` (programmatic API) fall back to inspecting
563
+ * the existing `ranges` and `formulaExpression` fields for compatibility.
564
+ */
212
565
  set model(value) {
213
- // value is [ { name, ranges }, ... ]
214
566
  const matrixMap = (this.matrixMap = {});
215
- value.forEach(definedName => {
216
- const matrix = (matrixMap[definedName.name] = new cell_matrix_1.CellMatrix());
217
- definedName.ranges.forEach(rangeStr => {
218
- if (rangeRegexp.test(rangeStr.split("!").pop() ?? "")) {
219
- matrix.addCell(rangeStr);
567
+ const formulaMap = (this.formulaMap = {});
568
+ const localSheetIdMap = (this.localSheetIdMap = {});
569
+ const opaqueMap = (this.opaqueMap = {});
570
+ const nameForKeyMap = (this.nameForKey = {});
571
+ // Resolve probe lazily: a caller may have constructed the Workbook
572
+ // before `installFormulaEngine()` but load XLSX data afterwards. We
573
+ // want whichever probe is registered at *load* time, not construct
574
+ // time. An explicit per-instance probe always wins when provided.
575
+ const probe = this._explicitProbe ?? (0, default_syntax_probe_1.getDefaultSyntaxProbe)();
576
+ for (const definedName of value) {
577
+ const sKey = storageKey(definedName.name, definedName.localSheetId);
578
+ nameForKeyMap[sKey] = definedName.name;
579
+ // Track localSheetId for all name kinds
580
+ if (definedName.localSheetId !== undefined) {
581
+ localSheetIdMap[sKey] = definedName.localSheetId;
582
+ }
583
+ // Programmatic API path: formulaExpression already set and no rawText
584
+ if (definedName.formulaExpression && definedName.rawText === undefined) {
585
+ formulaMap[sKey] = definedName.formulaExpression;
586
+ continue;
587
+ }
588
+ // XLSX parse path (rawText present) or programmatic path with ranges only
589
+ const classified = classifyDefinedName(definedName.rawText, definedName.ranges, probe);
590
+ switch (classified.kind) {
591
+ case "reference": {
592
+ const matrix = (matrixMap[sKey] = new cell_matrix_1.CellMatrix());
593
+ for (const rangeStr of classified.ranges) {
594
+ if (rangeRegexp.test(rangeStr.split("!").pop() ?? "")) {
595
+ matrix.addCell(rangeStr);
596
+ }
597
+ }
598
+ break;
220
599
  }
221
- });
222
- });
600
+ case "formula":
601
+ formulaMap[sKey] = classified.formulaExpression;
602
+ break;
603
+ case "opaque":
604
+ if (definedName.rawText) {
605
+ opaqueMap[sKey] = {
606
+ rawText: definedName.rawText,
607
+ localSheetId: definedName.localSheetId
608
+ };
609
+ }
610
+ break;
611
+ }
612
+ }
223
613
  }
224
614
  }
225
615
  exports.DefinedNames = DefinedNames;
@@ -37,6 +37,19 @@ class Image {
37
37
  if (!range) {
38
38
  throw new errors_1.ImageError("Image has no range");
39
39
  }
40
+ // Absolute positioning — no cell anchors
41
+ if (range.pos) {
42
+ return {
43
+ type: this.type,
44
+ imageId: this.imageId ?? "",
45
+ hyperlinks: range.hyperlinks,
46
+ range: {
47
+ tl: { nativeCol: 0, nativeColOff: 0, nativeRow: 0, nativeRowOff: 0 },
48
+ ext: range.ext,
49
+ pos: range.pos
50
+ }
51
+ };
52
+ }
40
53
  return {
41
54
  type: this.type,
42
55
  imageId: this.imageId ?? "",
@@ -72,6 +85,15 @@ class Image {
72
85
  };
73
86
  }
74
87
  }
88
+ else if (range && "pos" in range && range.pos) {
89
+ // Absolute positioning — preserve pos/ext, use dummy tl anchor
90
+ this.range = {
91
+ tl: new anchor_1.Anchor(this.worksheet, null, 0),
92
+ ext: range.ext,
93
+ hyperlinks: hyperlinks || ("hyperlinks" in range ? range.hyperlinks : undefined),
94
+ pos: range.pos
95
+ };
96
+ }
75
97
  else if (range) {
76
98
  this.range = {
77
99
  tl: new anchor_1.Anchor(this.worksheet, range.tl, 0),
@@ -98,7 +120,8 @@ class Image {
98
120
  br: this.range.br ? this.range.br.clone(target) : undefined,
99
121
  ext: this.range.ext ? { ...this.range.ext } : undefined,
100
122
  editAs: this.range.editAs,
101
- hyperlinks: this.range.hyperlinks ? { ...this.range.hyperlinks } : undefined
123
+ hyperlinks: this.range.hyperlinks ? { ...this.range.hyperlinks } : undefined,
124
+ pos: this.range.pos ? { ...this.range.pos } : undefined
102
125
  };
103
126
  }
104
127
  return cloned;
@@ -18,6 +18,7 @@ const worksheet_reader_1 = require("./worksheet-reader.js");
18
18
  const iterate_stream_1 = require("../utils/iterate-stream.js");
19
19
  const ooxml_paths_1 = require("../utils/ooxml-paths.js");
20
20
  const workbook_xform_1 = require("../xlsx/xform/book/workbook-xform.js");
21
+ const metadata_xform_1 = require("../xlsx/xform/core/metadata-xform.js");
21
22
  const relationships_xform_1 = require("../xlsx/xform/core/relationships-xform.js");
22
23
  const styles_xform_1 = require("../xlsx/xform/style/styles-xform.js");
23
24
  const _stream_1 = require("../../stream/index.js");
@@ -39,6 +40,8 @@ class WorkbookReaderBase extends event_emitter_1.EventEmitter {
39
40
  }
40
41
  constructor(input, options, WorksheetReaderClass, HyperlinkReaderClass) {
41
42
  super();
43
+ /** Whether xl/metadata.xml contains XLDAPR dynamic array metadata */
44
+ this.hasDynamicArrayMetadata = false;
42
45
  /** Running total of bytes buffered for waiting worksheets. */
43
46
  this._totalBufferedBytes = 0;
44
47
  this.input = input;
@@ -446,6 +449,14 @@ class WorkbookReaderBase extends event_emitter_1.EventEmitter {
446
449
  await this.styles.parseStream((0, iterate_stream_1.iterateStream)(entry));
447
450
  }
448
451
  }
452
+ async _parseMetadata(entry) {
453
+ const xform = new metadata_xform_1.MetadataXform();
454
+ const result = await xform.parseStream((0, iterate_stream_1.iterateStream)(entry));
455
+ if (result) {
456
+ this.hasDynamicArrayMetadata = !!result.hasDynamicArrays;
457
+ this.dynamicArrayCmIndices = result.dynamicArrayCmIndices;
458
+ }
459
+ }
449
460
  *_parseWorksheet(iterator, sheetNo) {
450
461
  this._emitEntry({ type: "worksheet", id: sheetNo });
451
462
  const sheetNoNumber = parseInt(sheetNo, 10);
@@ -514,6 +525,9 @@ class WorkbookReaderBase extends event_emitter_1.EventEmitter {
514
525
  case ooxml_paths_1.OOXML_PATHS.xlStyles:
515
526
  await this._parseStyles(entry);
516
527
  break;
528
+ case ooxml_paths_1.OOXML_PATHS.xlMetadata:
529
+ await this._parseMetadata(entry);
530
+ break;
517
531
  default:
518
532
  sheetNo = (0, ooxml_paths_1.getWorksheetNoFromWorksheetPath)(normalizedPath)?.toString();
519
533
  if (sheetNo) {