@ricsam/formula-engine 0.0.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 (569) hide show
  1. package/README.md +100 -0
  2. package/dist/cjs/core/ast-traverser.cjs +124 -0
  3. package/dist/cjs/core/ast-traverser.cjs.map +10 -0
  4. package/dist/cjs/core/autofill-utils.cjs +304 -0
  5. package/dist/cjs/core/autofill-utils.cjs.map +10 -0
  6. package/dist/cjs/core/engine.cjs +390 -0
  7. package/dist/cjs/core/engine.cjs.map +10 -0
  8. package/dist/cjs/core/managers/cache-manager.cjs +58 -0
  9. package/dist/cjs/core/managers/cache-manager.cjs.map +10 -0
  10. package/dist/cjs/core/managers/dependency-manager.cjs +620 -0
  11. package/dist/cjs/core/managers/dependency-manager.cjs.map +10 -0
  12. package/dist/cjs/core/managers/dependency-node.cjs +24 -0
  13. package/dist/cjs/core/managers/dependency-node.cjs.map +9 -0
  14. package/dist/cjs/core/managers/evaluation-manager.cjs +433 -0
  15. package/dist/cjs/core/managers/evaluation-manager.cjs.map +10 -0
  16. package/dist/cjs/core/managers/event-manager.cjs +49 -0
  17. package/dist/cjs/core/managers/event-manager.cjs.map +10 -0
  18. package/dist/cjs/core/managers/frontier-dependency-manager.cjs +181 -0
  19. package/dist/cjs/core/managers/frontier-dependency-manager.cjs.map +10 -0
  20. package/dist/cjs/core/managers/index.cjs +49 -0
  21. package/dist/cjs/core/managers/index.cjs.map +10 -0
  22. package/dist/cjs/core/managers/isDependencyNode.cjs +44 -0
  23. package/dist/cjs/core/managers/isDependencyNode.cjs.map +10 -0
  24. package/dist/cjs/core/managers/named-expression-manager.cjs +379 -0
  25. package/dist/cjs/core/managers/named-expression-manager.cjs.map +10 -0
  26. package/dist/cjs/core/managers/range-eval-order-builder.cjs +644 -0
  27. package/dist/cjs/core/managers/range-eval-order-builder.cjs.map +10 -0
  28. package/dist/cjs/core/managers/table-manager.cjs +254 -0
  29. package/dist/cjs/core/managers/table-manager.cjs.map +10 -0
  30. package/dist/cjs/core/managers/workbook-manager.cjs +474 -0
  31. package/dist/cjs/core/managers/workbook-manager.cjs.map +10 -0
  32. package/dist/cjs/core/map-serializer.cjs +69 -0
  33. package/dist/cjs/core/map-serializer.cjs.map +10 -0
  34. package/dist/cjs/core/named-expression-renamer.cjs +88 -0
  35. package/dist/cjs/core/named-expression-renamer.cjs.map +10 -0
  36. package/dist/cjs/core/sheet-renamer.cjs +89 -0
  37. package/dist/cjs/core/sheet-renamer.cjs.map +10 -0
  38. package/dist/cjs/core/sheet-utils.cjs +39 -0
  39. package/dist/cjs/core/sheet-utils.cjs.map +10 -0
  40. package/dist/cjs/core/table-renamer.cjs +88 -0
  41. package/dist/cjs/core/table-renamer.cjs.map +10 -0
  42. package/dist/cjs/core/types.cjs +48 -0
  43. package/dist/cjs/core/types.cjs.map +10 -0
  44. package/dist/cjs/core/utils/range-serializer.cjs +65 -0
  45. package/dist/cjs/core/utils/range-serializer.cjs.map +10 -0
  46. package/dist/cjs/core/utils/spreadsheet-visualizer.cjs +142 -0
  47. package/dist/cjs/core/utils/spreadsheet-visualizer.cjs.map +10 -0
  48. package/dist/cjs/core/utils.cjs +434 -0
  49. package/dist/cjs/core/utils.cjs.map +10 -0
  50. package/dist/cjs/core/workbook-renamer.cjs +106 -0
  51. package/dist/cjs/core/workbook-renamer.cjs.map +10 -0
  52. package/dist/cjs/debug/flags.cjs +47 -0
  53. package/dist/cjs/debug/flags.cjs.map +10 -0
  54. package/dist/cjs/evaluator/arithmetic/add/add.cjs +82 -0
  55. package/dist/cjs/evaluator/arithmetic/add/add.cjs.map +10 -0
  56. package/dist/cjs/evaluator/arithmetic/divide/divide.cjs +107 -0
  57. package/dist/cjs/evaluator/arithmetic/divide/divide.cjs.map +10 -0
  58. package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs +93 -0
  59. package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs.map +10 -0
  60. package/dist/cjs/evaluator/arithmetic/power/power.cjs +125 -0
  61. package/dist/cjs/evaluator/arithmetic/power/power.cjs.map +10 -0
  62. package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs +84 -0
  63. package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs.map +10 -0
  64. package/dist/cjs/evaluator/comparison/equals.cjs +64 -0
  65. package/dist/cjs/evaluator/comparison/equals.cjs.map +10 -0
  66. package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs +61 -0
  67. package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs.map +10 -0
  68. package/dist/cjs/evaluator/comparison/greater-than.cjs +61 -0
  69. package/dist/cjs/evaluator/comparison/greater-than.cjs.map +10 -0
  70. package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs +69 -0
  71. package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs.map +10 -0
  72. package/dist/cjs/evaluator/comparison/less-than.cjs +68 -0
  73. package/dist/cjs/evaluator/comparison/less-than.cjs.map +10 -0
  74. package/dist/cjs/evaluator/comparison/not-equals.cjs +53 -0
  75. package/dist/cjs/evaluator/comparison/not-equals.cjs.map +10 -0
  76. package/dist/cjs/evaluator/concatenation/concatenate.cjs +72 -0
  77. package/dist/cjs/evaluator/concatenation/concatenate.cjs.map +10 -0
  78. package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs +58 -0
  79. package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs.map +10 -0
  80. package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs +112 -0
  81. package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs.map +10 -0
  82. package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs +54 -0
  83. package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs.map +10 -0
  84. package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs +108 -0
  85. package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs.map +10 -0
  86. package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs +50 -0
  87. package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs.map +10 -0
  88. package/dist/cjs/evaluator/evaluate-scalar-operator.cjs +254 -0
  89. package/dist/cjs/evaluator/evaluate-scalar-operator.cjs.map +10 -0
  90. package/dist/cjs/evaluator/evaluation-context.cjs +154 -0
  91. package/dist/cjs/evaluator/evaluation-context.cjs.map +10 -0
  92. package/dist/cjs/evaluator/evaluation-error.cjs +75 -0
  93. package/dist/cjs/evaluator/evaluation-error.cjs.map +10 -0
  94. package/dist/cjs/evaluator/formula-evaluator.cjs +797 -0
  95. package/dist/cjs/evaluator/formula-evaluator.cjs.map +10 -0
  96. package/dist/cjs/evaluator/range-evaluation-node.cjs +88 -0
  97. package/dist/cjs/evaluator/range-evaluation-node.cjs.map +10 -0
  98. package/dist/cjs/functions/_template/template.cjs +42 -0
  99. package/dist/cjs/functions/_template/template.cjs.map +10 -0
  100. package/dist/cjs/functions/array/sequence/sequence.cjs +315 -0
  101. package/dist/cjs/functions/array/sequence/sequence.cjs.map +10 -0
  102. package/dist/cjs/functions/criteria-parser.cjs +217 -0
  103. package/dist/cjs/functions/criteria-parser.cjs.map +10 -0
  104. package/dist/cjs/functions/criteria-utils.cjs +291 -0
  105. package/dist/cjs/functions/criteria-utils.cjs.map +10 -0
  106. package/dist/cjs/functions/function-utils.cjs +63 -0
  107. package/dist/cjs/functions/function-utils.cjs.map +10 -0
  108. package/dist/cjs/functions/index.cjs +125 -0
  109. package/dist/cjs/functions/index.cjs.map +10 -0
  110. package/dist/cjs/functions/information/cell/cell.cjs +196 -0
  111. package/dist/cjs/functions/information/cell/cell.cjs.map +10 -0
  112. package/dist/cjs/functions/information/column/column.cjs +144 -0
  113. package/dist/cjs/functions/information/column/column.cjs.map +10 -0
  114. package/dist/cjs/functions/information/row/row.cjs +150 -0
  115. package/dist/cjs/functions/information/row/row.cjs.map +10 -0
  116. package/dist/cjs/functions/logical/and/and.cjs +112 -0
  117. package/dist/cjs/functions/logical/and/and.cjs.map +10 -0
  118. package/dist/cjs/functions/logical/if/if.cjs +195 -0
  119. package/dist/cjs/functions/logical/if/if.cjs.map +10 -0
  120. package/dist/cjs/functions/logical/iferror/iferror.cjs +126 -0
  121. package/dist/cjs/functions/logical/iferror/iferror.cjs.map +10 -0
  122. package/dist/cjs/functions/logical/or/or.cjs +112 -0
  123. package/dist/cjs/functions/logical/or/or.cjs.map +10 -0
  124. package/dist/cjs/functions/lookup/count/count-utils.cjs +65 -0
  125. package/dist/cjs/functions/lookup/count/count-utils.cjs.map +10 -0
  126. package/dist/cjs/functions/lookup/count/count.cjs +48 -0
  127. package/dist/cjs/functions/lookup/count/count.cjs.map +10 -0
  128. package/dist/cjs/functions/lookup/count/countif.cjs +94 -0
  129. package/dist/cjs/functions/lookup/count/countif.cjs.map +10 -0
  130. package/dist/cjs/functions/lookup/count/countifs.cjs +63 -0
  131. package/dist/cjs/functions/lookup/count/countifs.cjs.map +10 -0
  132. package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs +187 -0
  133. package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs.map +10 -0
  134. package/dist/cjs/functions/lookup/match/match.cjs +168 -0
  135. package/dist/cjs/functions/lookup/match/match.cjs.map +10 -0
  136. package/dist/cjs/functions/lookup/xlookup/xlookup.cjs +410 -0
  137. package/dist/cjs/functions/lookup/xlookup/xlookup.cjs.map +10 -0
  138. package/dist/cjs/functions/math/average/average-utils.cjs +72 -0
  139. package/dist/cjs/functions/math/average/average-utils.cjs.map +10 -0
  140. package/dist/cjs/functions/math/average/average.cjs +48 -0
  141. package/dist/cjs/functions/math/average/average.cjs.map +10 -0
  142. package/dist/cjs/functions/math/average/averageif.cjs +83 -0
  143. package/dist/cjs/functions/math/average/averageif.cjs.map +10 -0
  144. package/dist/cjs/functions/math/average/averageifs.cjs +61 -0
  145. package/dist/cjs/functions/math/average/averageifs.cjs.map +10 -0
  146. package/dist/cjs/functions/math/ceiling/ceiling.cjs +219 -0
  147. package/dist/cjs/functions/math/ceiling/ceiling.cjs.map +10 -0
  148. package/dist/cjs/functions/math/max/max-utils.cjs +71 -0
  149. package/dist/cjs/functions/math/max/max-utils.cjs.map +10 -0
  150. package/dist/cjs/functions/math/max/max.cjs +48 -0
  151. package/dist/cjs/functions/math/max/max.cjs.map +10 -0
  152. package/dist/cjs/functions/math/max/maxif.cjs +83 -0
  153. package/dist/cjs/functions/math/max/maxif.cjs.map +10 -0
  154. package/dist/cjs/functions/math/max/maxifs.cjs +61 -0
  155. package/dist/cjs/functions/math/max/maxifs.cjs.map +10 -0
  156. package/dist/cjs/functions/math/min/min-utils.cjs +71 -0
  157. package/dist/cjs/functions/math/min/min-utils.cjs.map +10 -0
  158. package/dist/cjs/functions/math/min/min.cjs +48 -0
  159. package/dist/cjs/functions/math/min/min.cjs.map +10 -0
  160. package/dist/cjs/functions/math/min/minif.cjs +83 -0
  161. package/dist/cjs/functions/math/min/minif.cjs.map +10 -0
  162. package/dist/cjs/functions/math/min/minifs.cjs +61 -0
  163. package/dist/cjs/functions/math/min/minifs.cjs.map +10 -0
  164. package/dist/cjs/functions/math/sum/sum.cjs +48 -0
  165. package/dist/cjs/functions/math/sum/sum.cjs.map +10 -0
  166. package/dist/cjs/functions/math/sum/sumif.cjs +83 -0
  167. package/dist/cjs/functions/math/sum/sumif.cjs.map +10 -0
  168. package/dist/cjs/functions/math/sum/sumifs.cjs +60 -0
  169. package/dist/cjs/functions/math/sum/sumifs.cjs.map +10 -0
  170. package/dist/cjs/functions/math/sum/summation-utils.cjs +57 -0
  171. package/dist/cjs/functions/math/sum/summation-utils.cjs.map +10 -0
  172. package/dist/cjs/functions/reference/address/address.cjs +163 -0
  173. package/dist/cjs/functions/reference/address/address.cjs.map +10 -0
  174. package/dist/cjs/functions/reference/indirect/indirect.cjs +102 -0
  175. package/dist/cjs/functions/reference/indirect/indirect.cjs.map +10 -0
  176. package/dist/cjs/functions/reference/offset/offset.cjs +233 -0
  177. package/dist/cjs/functions/reference/offset/offset.cjs.map +10 -0
  178. package/dist/cjs/functions/text/concatenate/concatenate.cjs +167 -0
  179. package/dist/cjs/functions/text/concatenate/concatenate.cjs.map +10 -0
  180. package/dist/cjs/functions/text/exact/exact.cjs +171 -0
  181. package/dist/cjs/functions/text/exact/exact.cjs.map +10 -0
  182. package/dist/cjs/functions/text/find/find.cjs +397 -0
  183. package/dist/cjs/functions/text/find/find.cjs.map +10 -0
  184. package/dist/cjs/functions/text/left/left.cjs +109 -0
  185. package/dist/cjs/functions/text/left/left.cjs.map +10 -0
  186. package/dist/cjs/functions/text/len/len.cjs +119 -0
  187. package/dist/cjs/functions/text/len/len.cjs.map +10 -0
  188. package/dist/cjs/functions/text/mid/mid.cjs +103 -0
  189. package/dist/cjs/functions/text/mid/mid.cjs.map +10 -0
  190. package/dist/cjs/functions/text/right/right.cjs +167 -0
  191. package/dist/cjs/functions/text/right/right.cjs.map +10 -0
  192. package/dist/cjs/functions/text/text-helpers.cjs +179 -0
  193. package/dist/cjs/functions/text/text-helpers.cjs.map +10 -0
  194. package/dist/cjs/functions/text/textjoin/textjoin.cjs +173 -0
  195. package/dist/cjs/functions/text/textjoin/textjoin.cjs.map +10 -0
  196. package/dist/cjs/package.json +5 -0
  197. package/dist/cjs/parser/ast.cjs +175 -0
  198. package/dist/cjs/parser/ast.cjs.map +10 -0
  199. package/dist/cjs/parser/formatter.cjs +319 -0
  200. package/dist/cjs/parser/formatter.cjs.map +10 -0
  201. package/dist/cjs/parser/grammar.cjs +375 -0
  202. package/dist/cjs/parser/grammar.cjs.map +10 -0
  203. package/dist/cjs/parser/lexer.cjs +443 -0
  204. package/dist/cjs/parser/lexer.cjs.map +10 -0
  205. package/dist/cjs/parser/parser.cjs +1700 -0
  206. package/dist/cjs/parser/parser.cjs.map +10 -0
  207. package/dist/cjs/react/hooks.cjs +59 -0
  208. package/dist/cjs/react/hooks.cjs.map +10 -0
  209. package/dist/mjs/core/ast-traverser.mjs +94 -0
  210. package/dist/mjs/core/ast-traverser.mjs.map +10 -0
  211. package/dist/mjs/core/autofill-utils.mjs +274 -0
  212. package/dist/mjs/core/autofill-utils.mjs.map +10 -0
  213. package/dist/mjs/core/engine.mjs +366 -0
  214. package/dist/mjs/core/engine.mjs.map +10 -0
  215. package/dist/mjs/core/managers/cache-manager.mjs +27 -0
  216. package/dist/mjs/core/managers/cache-manager.mjs.map +10 -0
  217. package/dist/mjs/core/managers/dependency-manager.mjs +593 -0
  218. package/dist/mjs/core/managers/dependency-manager.mjs.map +10 -0
  219. package/dist/mjs/core/managers/dependency-node.mjs +2 -0
  220. package/dist/mjs/core/managers/dependency-node.mjs.map +9 -0
  221. package/dist/mjs/core/managers/evaluation-manager.mjs +415 -0
  222. package/dist/mjs/core/managers/evaluation-manager.mjs.map +10 -0
  223. package/dist/mjs/core/managers/event-manager.mjs +18 -0
  224. package/dist/mjs/core/managers/event-manager.mjs.map +10 -0
  225. package/dist/mjs/core/managers/frontier-dependency-manager.mjs +151 -0
  226. package/dist/mjs/core/managers/frontier-dependency-manager.mjs.map +10 -0
  227. package/dist/mjs/core/managers/index.mjs +21 -0
  228. package/dist/mjs/core/managers/index.mjs.map +10 -0
  229. package/dist/mjs/core/managers/isDependencyNode.mjs +14 -0
  230. package/dist/mjs/core/managers/isDependencyNode.mjs.map +10 -0
  231. package/dist/mjs/core/managers/named-expression-manager.mjs +348 -0
  232. package/dist/mjs/core/managers/named-expression-manager.mjs.map +10 -0
  233. package/dist/mjs/core/managers/range-eval-order-builder.mjs +618 -0
  234. package/dist/mjs/core/managers/range-eval-order-builder.mjs.map +10 -0
  235. package/dist/mjs/core/managers/table-manager.mjs +224 -0
  236. package/dist/mjs/core/managers/table-manager.mjs.map +10 -0
  237. package/dist/mjs/core/managers/workbook-manager.mjs +447 -0
  238. package/dist/mjs/core/managers/workbook-manager.mjs.map +10 -0
  239. package/dist/mjs/core/map-serializer.mjs +39 -0
  240. package/dist/mjs/core/map-serializer.mjs.map +10 -0
  241. package/dist/mjs/core/named-expression-renamer.mjs +58 -0
  242. package/dist/mjs/core/named-expression-renamer.mjs.map +10 -0
  243. package/dist/mjs/core/sheet-renamer.mjs +59 -0
  244. package/dist/mjs/core/sheet-renamer.mjs.map +10 -0
  245. package/dist/mjs/core/sheet-utils.mjs +8 -0
  246. package/dist/mjs/core/sheet-utils.mjs.map +10 -0
  247. package/dist/mjs/core/table-renamer.mjs +58 -0
  248. package/dist/mjs/core/table-renamer.mjs.map +10 -0
  249. package/dist/mjs/core/types.mjs +18 -0
  250. package/dist/mjs/core/types.mjs.map +10 -0
  251. package/dist/mjs/core/utils/range-serializer.mjs +35 -0
  252. package/dist/mjs/core/utils/range-serializer.mjs.map +10 -0
  253. package/dist/mjs/core/utils/spreadsheet-visualizer.mjs +112 -0
  254. package/dist/mjs/core/utils/spreadsheet-visualizer.mjs.map +10 -0
  255. package/dist/mjs/core/utils.mjs +409 -0
  256. package/dist/mjs/core/utils.mjs.map +10 -0
  257. package/dist/mjs/core/workbook-renamer.mjs +76 -0
  258. package/dist/mjs/core/workbook-renamer.mjs.map +10 -0
  259. package/dist/mjs/debug/flags.mjs +17 -0
  260. package/dist/mjs/debug/flags.mjs.map +10 -0
  261. package/dist/mjs/evaluator/arithmetic/add/add.mjs +52 -0
  262. package/dist/mjs/evaluator/arithmetic/add/add.mjs.map +10 -0
  263. package/dist/mjs/evaluator/arithmetic/divide/divide.mjs +77 -0
  264. package/dist/mjs/evaluator/arithmetic/divide/divide.mjs.map +10 -0
  265. package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs +63 -0
  266. package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs.map +10 -0
  267. package/dist/mjs/evaluator/arithmetic/power/power.mjs +95 -0
  268. package/dist/mjs/evaluator/arithmetic/power/power.mjs.map +10 -0
  269. package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs +54 -0
  270. package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs.map +10 -0
  271. package/dist/mjs/evaluator/comparison/equals.mjs +34 -0
  272. package/dist/mjs/evaluator/comparison/equals.mjs.map +10 -0
  273. package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs +31 -0
  274. package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs.map +10 -0
  275. package/dist/mjs/evaluator/comparison/greater-than.mjs +31 -0
  276. package/dist/mjs/evaluator/comparison/greater-than.mjs.map +10 -0
  277. package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs +39 -0
  278. package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs.map +10 -0
  279. package/dist/mjs/evaluator/comparison/less-than.mjs +38 -0
  280. package/dist/mjs/evaluator/comparison/less-than.mjs.map +10 -0
  281. package/dist/mjs/evaluator/comparison/not-equals.mjs +23 -0
  282. package/dist/mjs/evaluator/comparison/not-equals.mjs.map +10 -0
  283. package/dist/mjs/evaluator/concatenation/concatenate.mjs +42 -0
  284. package/dist/mjs/evaluator/concatenation/concatenate.mjs.map +10 -0
  285. package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs +28 -0
  286. package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs.map +10 -0
  287. package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs +81 -0
  288. package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs.map +10 -0
  289. package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs +24 -0
  290. package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs.map +10 -0
  291. package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs +78 -0
  292. package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs.map +10 -0
  293. package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs +20 -0
  294. package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs.map +10 -0
  295. package/dist/mjs/evaluator/evaluate-scalar-operator.mjs +226 -0
  296. package/dist/mjs/evaluator/evaluate-scalar-operator.mjs.map +10 -0
  297. package/dist/mjs/evaluator/evaluation-context.mjs +123 -0
  298. package/dist/mjs/evaluator/evaluation-context.mjs.map +10 -0
  299. package/dist/mjs/evaluator/evaluation-error.mjs +44 -0
  300. package/dist/mjs/evaluator/evaluation-error.mjs.map +10 -0
  301. package/dist/mjs/evaluator/formula-evaluator.mjs +780 -0
  302. package/dist/mjs/evaluator/formula-evaluator.mjs.map +10 -0
  303. package/dist/mjs/evaluator/range-evaluation-node.mjs +58 -0
  304. package/dist/mjs/evaluator/range-evaluation-node.mjs.map +10 -0
  305. package/dist/mjs/functions/_template/template.mjs +12 -0
  306. package/dist/mjs/functions/_template/template.mjs.map +10 -0
  307. package/dist/mjs/functions/array/sequence/sequence.mjs +287 -0
  308. package/dist/mjs/functions/array/sequence/sequence.mjs.map +10 -0
  309. package/dist/mjs/functions/criteria-parser.mjs +187 -0
  310. package/dist/mjs/functions/criteria-parser.mjs.map +10 -0
  311. package/dist/mjs/functions/criteria-utils.mjs +268 -0
  312. package/dist/mjs/functions/criteria-utils.mjs.map +10 -0
  313. package/dist/mjs/functions/function-utils.mjs +33 -0
  314. package/dist/mjs/functions/function-utils.mjs.map +10 -0
  315. package/dist/mjs/functions/index.mjs +95 -0
  316. package/dist/mjs/functions/index.mjs.map +10 -0
  317. package/dist/mjs/functions/information/cell/cell.mjs +168 -0
  318. package/dist/mjs/functions/information/cell/cell.mjs.map +10 -0
  319. package/dist/mjs/functions/information/column/column.mjs +120 -0
  320. package/dist/mjs/functions/information/column/column.mjs.map +10 -0
  321. package/dist/mjs/functions/information/row/row.mjs +126 -0
  322. package/dist/mjs/functions/information/row/row.mjs.map +10 -0
  323. package/dist/mjs/functions/logical/and/and.mjs +84 -0
  324. package/dist/mjs/functions/logical/and/and.mjs.map +10 -0
  325. package/dist/mjs/functions/logical/if/if.mjs +167 -0
  326. package/dist/mjs/functions/logical/if/if.mjs.map +10 -0
  327. package/dist/mjs/functions/logical/iferror/iferror.mjs +98 -0
  328. package/dist/mjs/functions/logical/iferror/iferror.mjs.map +10 -0
  329. package/dist/mjs/functions/logical/or/or.mjs +84 -0
  330. package/dist/mjs/functions/logical/or/or.mjs.map +10 -0
  331. package/dist/mjs/functions/lookup/count/count-utils.mjs +35 -0
  332. package/dist/mjs/functions/lookup/count/count-utils.mjs.map +10 -0
  333. package/dist/mjs/functions/lookup/count/count.mjs +18 -0
  334. package/dist/mjs/functions/lookup/count/count.mjs.map +10 -0
  335. package/dist/mjs/functions/lookup/count/countif.mjs +68 -0
  336. package/dist/mjs/functions/lookup/count/countif.mjs.map +10 -0
  337. package/dist/mjs/functions/lookup/count/countifs.mjs +37 -0
  338. package/dist/mjs/functions/lookup/count/countifs.mjs.map +10 -0
  339. package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs +159 -0
  340. package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs.map +10 -0
  341. package/dist/mjs/functions/lookup/match/match.mjs +140 -0
  342. package/dist/mjs/functions/lookup/match/match.mjs.map +10 -0
  343. package/dist/mjs/functions/lookup/xlookup/xlookup.mjs +382 -0
  344. package/dist/mjs/functions/lookup/xlookup/xlookup.mjs.map +10 -0
  345. package/dist/mjs/functions/math/average/average-utils.mjs +44 -0
  346. package/dist/mjs/functions/math/average/average-utils.mjs.map +10 -0
  347. package/dist/mjs/functions/math/average/average.mjs +18 -0
  348. package/dist/mjs/functions/math/average/average.mjs.map +10 -0
  349. package/dist/mjs/functions/math/average/averageif.mjs +58 -0
  350. package/dist/mjs/functions/math/average/averageif.mjs.map +10 -0
  351. package/dist/mjs/functions/math/average/averageifs.mjs +35 -0
  352. package/dist/mjs/functions/math/average/averageifs.mjs.map +10 -0
  353. package/dist/mjs/functions/math/ceiling/ceiling.mjs +191 -0
  354. package/dist/mjs/functions/math/ceiling/ceiling.mjs.map +10 -0
  355. package/dist/mjs/functions/math/max/max-utils.mjs +43 -0
  356. package/dist/mjs/functions/math/max/max-utils.mjs.map +10 -0
  357. package/dist/mjs/functions/math/max/max.mjs +18 -0
  358. package/dist/mjs/functions/math/max/max.mjs.map +10 -0
  359. package/dist/mjs/functions/math/max/maxif.mjs +58 -0
  360. package/dist/mjs/functions/math/max/maxif.mjs.map +10 -0
  361. package/dist/mjs/functions/math/max/maxifs.mjs +35 -0
  362. package/dist/mjs/functions/math/max/maxifs.mjs.map +10 -0
  363. package/dist/mjs/functions/math/min/min-utils.mjs +43 -0
  364. package/dist/mjs/functions/math/min/min-utils.mjs.map +10 -0
  365. package/dist/mjs/functions/math/min/min.mjs +18 -0
  366. package/dist/mjs/functions/math/min/min.mjs.map +10 -0
  367. package/dist/mjs/functions/math/min/minif.mjs +58 -0
  368. package/dist/mjs/functions/math/min/minif.mjs.map +10 -0
  369. package/dist/mjs/functions/math/min/minifs.mjs +35 -0
  370. package/dist/mjs/functions/math/min/minifs.mjs.map +10 -0
  371. package/dist/mjs/functions/math/sum/sum.mjs +18 -0
  372. package/dist/mjs/functions/math/sum/sum.mjs.map +10 -0
  373. package/dist/mjs/functions/math/sum/sumif.mjs +58 -0
  374. package/dist/mjs/functions/math/sum/sumif.mjs.map +10 -0
  375. package/dist/mjs/functions/math/sum/sumifs.mjs +34 -0
  376. package/dist/mjs/functions/math/sum/sumifs.mjs.map +10 -0
  377. package/dist/mjs/functions/math/sum/summation-utils.mjs +27 -0
  378. package/dist/mjs/functions/math/sum/summation-utils.mjs.map +10 -0
  379. package/dist/mjs/functions/reference/address/address.mjs +135 -0
  380. package/dist/mjs/functions/reference/address/address.mjs.map +10 -0
  381. package/dist/mjs/functions/reference/indirect/indirect.mjs +74 -0
  382. package/dist/mjs/functions/reference/indirect/indirect.mjs.map +10 -0
  383. package/dist/mjs/functions/reference/offset/offset.mjs +205 -0
  384. package/dist/mjs/functions/reference/offset/offset.mjs.map +10 -0
  385. package/dist/mjs/functions/text/concatenate/concatenate.mjs +139 -0
  386. package/dist/mjs/functions/text/concatenate/concatenate.mjs.map +10 -0
  387. package/dist/mjs/functions/text/exact/exact.mjs +143 -0
  388. package/dist/mjs/functions/text/exact/exact.mjs.map +10 -0
  389. package/dist/mjs/functions/text/find/find.mjs +369 -0
  390. package/dist/mjs/functions/text/find/find.mjs.map +10 -0
  391. package/dist/mjs/functions/text/left/left.mjs +81 -0
  392. package/dist/mjs/functions/text/left/left.mjs.map +10 -0
  393. package/dist/mjs/functions/text/len/len.mjs +91 -0
  394. package/dist/mjs/functions/text/len/len.mjs.map +10 -0
  395. package/dist/mjs/functions/text/mid/mid.mjs +75 -0
  396. package/dist/mjs/functions/text/mid/mid.mjs.map +10 -0
  397. package/dist/mjs/functions/text/right/right.mjs +143 -0
  398. package/dist/mjs/functions/text/right/right.mjs.map +10 -0
  399. package/dist/mjs/functions/text/text-helpers.mjs +151 -0
  400. package/dist/mjs/functions/text/text-helpers.mjs.map +10 -0
  401. package/dist/mjs/functions/text/textjoin/textjoin.mjs +145 -0
  402. package/dist/mjs/functions/text/textjoin/textjoin.mjs.map +10 -0
  403. package/dist/mjs/package.json +5 -0
  404. package/dist/mjs/parser/ast.mjs +145 -0
  405. package/dist/mjs/parser/ast.mjs.map +10 -0
  406. package/dist/mjs/parser/formatter.mjs +289 -0
  407. package/dist/mjs/parser/formatter.mjs.map +10 -0
  408. package/dist/mjs/parser/grammar.mjs +345 -0
  409. package/dist/mjs/parser/grammar.mjs.map +10 -0
  410. package/dist/mjs/parser/lexer.mjs +412 -0
  411. package/dist/mjs/parser/lexer.mjs.map +10 -0
  412. package/dist/mjs/parser/parser.mjs +1692 -0
  413. package/dist/mjs/parser/parser.mjs.map +10 -0
  414. package/dist/mjs/react/hooks.mjs +16 -0
  415. package/dist/mjs/react/hooks.mjs.map +10 -0
  416. package/dist/types/core/ast-traverser.d.ts +28 -0
  417. package/dist/types/core/autofill-utils.d.ts +32 -0
  418. package/dist/types/core/engine.d.ts +184 -0
  419. package/dist/types/core/managers/cache-manager.d.ts +14 -0
  420. package/dist/types/core/managers/dependency-manager.d.ts +147 -0
  421. package/dist/types/core/managers/dependency-node.d.ts +13 -0
  422. package/dist/types/core/managers/evaluation-manager.d.ts +30 -0
  423. package/dist/types/core/managers/event-manager.d.ts +8 -0
  424. package/dist/types/core/managers/frontier-dependency-manager.d.ts +69 -0
  425. package/dist/types/core/managers/index.d.ts +7 -0
  426. package/dist/types/core/managers/isDependencyNode.d.ts +2 -0
  427. package/dist/types/core/managers/named-expression-manager.d.ts +101 -0
  428. package/dist/types/core/managers/range-eval-order-builder.d.ts +33 -0
  429. package/dist/types/core/managers/table-manager.d.ts +84 -0
  430. package/dist/types/core/managers/workbook-manager.d.ts +136 -0
  431. package/dist/types/core/map-serializer.d.ts +4 -0
  432. package/dist/types/core/named-expression-renamer.d.ts +21 -0
  433. package/dist/types/core/sheet-renamer.d.ts +28 -0
  434. package/dist/types/core/sheet-utils.d.ts +2 -0
  435. package/dist/types/core/table-renamer.d.ts +21 -0
  436. package/dist/types/core/types.d.ts +272 -0
  437. package/dist/types/core/utils/cell-address-parsing.test.d.ts +1 -0
  438. package/dist/types/core/utils/range-serializer.d.ts +22 -0
  439. package/dist/types/core/utils/range-serializer.test.d.ts +1 -0
  440. package/dist/types/core/utils/spreadsheet-visualizer.d.ts +30 -0
  441. package/dist/types/core/utils.d.ts +48 -0
  442. package/dist/types/core/workbook-renamer.d.ts +28 -0
  443. package/dist/types/debug/flags.d.ts +11 -0
  444. package/dist/types/evaluator/arithmetic/add/add.d.ts +2 -0
  445. package/dist/types/evaluator/arithmetic/add/add.test.d.ts +1 -0
  446. package/dist/types/evaluator/arithmetic/divide/divide.d.ts +2 -0
  447. package/dist/types/evaluator/arithmetic/divide/divide.test.d.ts +1 -0
  448. package/dist/types/evaluator/arithmetic/multiply/multiply.d.ts +2 -0
  449. package/dist/types/evaluator/arithmetic/multiply/multiply.test.d.ts +1 -0
  450. package/dist/types/evaluator/arithmetic/power/power.d.ts +2 -0
  451. package/dist/types/evaluator/arithmetic/power/power.test.d.ts +1 -0
  452. package/dist/types/evaluator/arithmetic/subtract/subtract.d.ts +2 -0
  453. package/dist/types/evaluator/arithmetic/subtract/subtract.test.d.ts +1 -0
  454. package/dist/types/evaluator/comparison/comparison-operators.test.d.ts +1 -0
  455. package/dist/types/evaluator/comparison/equals.d.ts +6 -0
  456. package/dist/types/evaluator/comparison/greater-than-or-equal.d.ts +6 -0
  457. package/dist/types/evaluator/comparison/greater-than.d.ts +6 -0
  458. package/dist/types/evaluator/comparison/less-than-or-equal.d.ts +6 -0
  459. package/dist/types/evaluator/comparison/less-than.d.ts +6 -0
  460. package/dist/types/evaluator/comparison/not-equals.d.ts +6 -0
  461. package/dist/types/evaluator/concatenation/concatenate.d.ts +6 -0
  462. package/dist/types/evaluator/concatenation/concatenate.test.d.ts +1 -0
  463. package/dist/types/evaluator/dependency-nodes/ast-evaluation-node.d.ts +12 -0
  464. package/dist/types/evaluator/dependency-nodes/base-eval-node.d.ts +31 -0
  465. package/dist/types/evaluator/dependency-nodes/cell-value-node.d.ts +10 -0
  466. package/dist/types/evaluator/dependency-nodes/empty-cell-evaluation-node.d.ts +17 -0
  467. package/dist/types/evaluator/dependency-nodes/spill-meta-node.d.ts +7 -0
  468. package/dist/types/evaluator/evaluate-scalar-operator.d.ts +12 -0
  469. package/dist/types/evaluator/evaluation-context.d.ts +66 -0
  470. package/dist/types/evaluator/evaluation-error.d.ts +20 -0
  471. package/dist/types/evaluator/formula-evaluator.d.ts +67 -0
  472. package/dist/types/evaluator/open-range-evaluator.test.d.ts +1 -0
  473. package/dist/types/evaluator/range-evaluation-node.d.ts +16 -0
  474. package/dist/types/functions/_template/template.d.ts +5 -0
  475. package/dist/types/functions/_template/template.test.d.ts +1 -0
  476. package/dist/types/functions/array/sequence/performance-test.d.ts +1 -0
  477. package/dist/types/functions/array/sequence/sequence.d.ts +14 -0
  478. package/dist/types/functions/array/sequence/sequence.test.d.ts +1 -0
  479. package/dist/types/functions/criteria-parser.d.ts +27 -0
  480. package/dist/types/functions/criteria-utils.d.ts +61 -0
  481. package/dist/types/functions/function-utils.d.ts +21 -0
  482. package/dist/types/functions/index.d.ts +2 -0
  483. package/dist/types/functions/information/cell/cell.d.ts +24 -0
  484. package/dist/types/functions/information/cell/cell.test.d.ts +1 -0
  485. package/dist/types/functions/information/column/column.d.ts +14 -0
  486. package/dist/types/functions/information/column/column.test.d.ts +1 -0
  487. package/dist/types/functions/information/row/row.d.ts +14 -0
  488. package/dist/types/functions/information/row/row.test.d.ts +1 -0
  489. package/dist/types/functions/logical/and/and.d.ts +5 -0
  490. package/dist/types/functions/logical/and/and.test.d.ts +1 -0
  491. package/dist/types/functions/logical/if/if.d.ts +5 -0
  492. package/dist/types/functions/logical/if/if.test.d.ts +1 -0
  493. package/dist/types/functions/logical/iferror/iferror.d.ts +5 -0
  494. package/dist/types/functions/logical/iferror/iferror.test.d.ts +1 -0
  495. package/dist/types/functions/logical/or/or.d.ts +5 -0
  496. package/dist/types/functions/logical/or/or.test.d.ts +1 -0
  497. package/dist/types/functions/lookup/count/count-utils.d.ts +14 -0
  498. package/dist/types/functions/lookup/count/count.d.ts +21 -0
  499. package/dist/types/functions/lookup/count/count.test.d.ts +1 -0
  500. package/dist/types/functions/lookup/count/countif.d.ts +26 -0
  501. package/dist/types/functions/lookup/count/countif.test.d.ts +1 -0
  502. package/dist/types/functions/lookup/count/countifs.d.ts +21 -0
  503. package/dist/types/functions/lookup/count/countifs.test.d.ts +1 -0
  504. package/dist/types/functions/lookup/index-lookup/index-lookup.d.ts +2 -0
  505. package/dist/types/functions/lookup/index-lookup/index-lookup.test.d.ts +1 -0
  506. package/dist/types/functions/lookup/match/match.d.ts +2 -0
  507. package/dist/types/functions/lookup/match/match.test.d.ts +1 -0
  508. package/dist/types/functions/lookup/xlookup/xlookup.d.ts +2 -0
  509. package/dist/types/functions/lookup/xlookup/xlookup.test.d.ts +1 -0
  510. package/dist/types/functions/math/average/average-utils.d.ts +10 -0
  511. package/dist/types/functions/math/average/average.d.ts +18 -0
  512. package/dist/types/functions/math/average/average.test.d.ts +1 -0
  513. package/dist/types/functions/math/average/averageif.d.ts +23 -0
  514. package/dist/types/functions/math/average/averageif.test.d.ts +1 -0
  515. package/dist/types/functions/math/average/averageifs.d.ts +21 -0
  516. package/dist/types/functions/math/average/averageifs.test.d.ts +1 -0
  517. package/dist/types/functions/math/ceiling/ceiling.d.ts +5 -0
  518. package/dist/types/functions/math/ceiling/ceiling.test.d.ts +1 -0
  519. package/dist/types/functions/math/max/max-utils.d.ts +20 -0
  520. package/dist/types/functions/math/max/max.d.ts +18 -0
  521. package/dist/types/functions/math/max/max.test.d.ts +1 -0
  522. package/dist/types/functions/math/max/maxif.d.ts +23 -0
  523. package/dist/types/functions/math/max/maxif.test.d.ts +1 -0
  524. package/dist/types/functions/math/max/maxifs.d.ts +21 -0
  525. package/dist/types/functions/math/max/maxifs.test.d.ts +1 -0
  526. package/dist/types/functions/math/min/min-utils.d.ts +20 -0
  527. package/dist/types/functions/math/min/min.d.ts +5 -0
  528. package/dist/types/functions/math/min/min.test.d.ts +1 -0
  529. package/dist/types/functions/math/min/minif.d.ts +23 -0
  530. package/dist/types/functions/math/min/minif.test.d.ts +1 -0
  531. package/dist/types/functions/math/min/minifs.d.ts +21 -0
  532. package/dist/types/functions/math/min/minifs.test.d.ts +1 -0
  533. package/dist/types/functions/math/sum/sum.d.ts +5 -0
  534. package/dist/types/functions/math/sum/sum.test.d.ts +1 -0
  535. package/dist/types/functions/math/sum/sumif.d.ts +23 -0
  536. package/dist/types/functions/math/sum/sumif.test.d.ts +1 -0
  537. package/dist/types/functions/math/sum/sumifs.d.ts +21 -0
  538. package/dist/types/functions/math/sum/sumifs.test.d.ts +1 -0
  539. package/dist/types/functions/math/sum/summation-utils.d.ts +19 -0
  540. package/dist/types/functions/reference/address/address.d.ts +18 -0
  541. package/dist/types/functions/reference/address/address.test.d.ts +1 -0
  542. package/dist/types/functions/reference/indirect/indirect.d.ts +20 -0
  543. package/dist/types/functions/reference/indirect/indirect.test.d.ts +1 -0
  544. package/dist/types/functions/reference/offset/offset.d.ts +23 -0
  545. package/dist/types/functions/reference/offset/offset.test.d.ts +1 -0
  546. package/dist/types/functions/text/concatenate/concatenate.d.ts +5 -0
  547. package/dist/types/functions/text/concatenate/concatenate.test.d.ts +1 -0
  548. package/dist/types/functions/text/exact/exact.d.ts +5 -0
  549. package/dist/types/functions/text/exact/exact.test.d.ts +1 -0
  550. package/dist/types/functions/text/find/find.d.ts +20 -0
  551. package/dist/types/functions/text/find/find.test.d.ts +1 -0
  552. package/dist/types/functions/text/left/left.d.ts +19 -0
  553. package/dist/types/functions/text/left/left.test.d.ts +1 -0
  554. package/dist/types/functions/text/len/len.d.ts +16 -0
  555. package/dist/types/functions/text/len/len.test.d.ts +1 -0
  556. package/dist/types/functions/text/mid/mid.d.ts +20 -0
  557. package/dist/types/functions/text/mid/mid.test.d.ts +1 -0
  558. package/dist/types/functions/text/right/right.d.ts +2 -0
  559. package/dist/types/functions/text/right/right.test.d.ts +1 -0
  560. package/dist/types/functions/text/text-helpers.d.ts +27 -0
  561. package/dist/types/functions/text/textjoin/textjoin.d.ts +5 -0
  562. package/dist/types/functions/text/textjoin/textjoin.test.d.ts +1 -0
  563. package/dist/types/parser/ast.d.ts +275 -0
  564. package/dist/types/parser/formatter.d.ts +6 -0
  565. package/dist/types/parser/grammar.d.ts +203 -0
  566. package/dist/types/parser/lexer.d.ts +144 -0
  567. package/dist/types/parser/parser.d.ts +159 -0
  568. package/dist/types/react/hooks.d.ts +5 -0
  569. package/package.json +41 -0
@@ -0,0 +1,84 @@
1
+ // src/functions/logical/and/and.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ function isTruthy(value) {
6
+ switch (value.type) {
7
+ case "boolean":
8
+ return value.value;
9
+ case "number":
10
+ return value.value !== 0;
11
+ case "string":
12
+ return value.value !== "";
13
+ case "infinity":
14
+ return true;
15
+ default:
16
+ return false;
17
+ }
18
+ }
19
+ var AND = {
20
+ name: "AND",
21
+ evaluate: function(node, context) {
22
+ if (node.args.length === 0) {
23
+ return {
24
+ type: "error",
25
+ err: FormulaError.VALUE,
26
+ message: "AND function requires at least one argument",
27
+ errAddress: context.dependencyNode
28
+ };
29
+ }
30
+ for (const arg of node.args) {
31
+ const argResult = this.evaluateNode(arg, context);
32
+ if (argResult.type === "error" || argResult.type === "awaiting-evaluation") {
33
+ return argResult;
34
+ }
35
+ if (argResult.type === "value") {
36
+ if (!isTruthy(argResult.result)) {
37
+ return {
38
+ type: "value",
39
+ result: { type: "boolean", value: false }
40
+ };
41
+ }
42
+ } else if (argResult.type === "spilled-values") {
43
+ const cellValues = argResult.evaluateAllCells.call(this, {
44
+ context,
45
+ origin: context.cellAddress,
46
+ evaluate: argResult.evaluate,
47
+ lookupOrder: "col-major"
48
+ });
49
+ if (cellValues.type === "error" || cellValues.type === "awaiting-evaluation") {
50
+ return cellValues;
51
+ }
52
+ for (const cellValue of cellValues.values) {
53
+ if (cellValue.result.type === "error") {
54
+ return cellValue.result;
55
+ }
56
+ if (cellValue.result.type === "value") {
57
+ if (!isTruthy(cellValue.result.result)) {
58
+ return {
59
+ type: "value",
60
+ result: { type: "boolean", value: false }
61
+ };
62
+ }
63
+ }
64
+ }
65
+ } else {
66
+ return {
67
+ type: "error",
68
+ err: FormulaError.VALUE,
69
+ message: "Invalid argument type for AND function",
70
+ errAddress: context.dependencyNode
71
+ };
72
+ }
73
+ }
74
+ return {
75
+ type: "value",
76
+ result: { type: "boolean", value: true }
77
+ };
78
+ }
79
+ };
80
+ export {
81
+ AND
82
+ };
83
+
84
+ //# debugId=83035E28B8777BF964756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/logical/and/and.ts"],
4
+ "sourcesContent": [
5
+ "import {\n FormulaError,\n type CellValue,\n type CellNumber,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type SpilledValuesEvaluationResult,\n type SingleEvaluationResult,\n type ErrorEvaluationResult,\n} from \"src/core/types\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * AND function - Returns TRUE if all arguments are TRUE, FALSE otherwise\n *\n * Usage: AND(logical1, [logical2], ...)\n *\n * logical1, logical2, ...: Logical values or expressions to evaluate\n *\n * Examples:\n * AND(TRUE, TRUE) - returns TRUE\n * AND(TRUE, FALSE) - returns FALSE\n * AND(A1>10, B1<20) - returns TRUE if both conditions are met\n * AND(A1:A3) - returns TRUE if all values in A1:A3 are truthy\n *\n * Note:\n * - Supports spilled values (dynamic arrays) for arguments\n * - Logical evaluation: 0 and empty string are FALSE, everything else is TRUE\n * - If any argument is spilled, returns spilled results\n * - Short-circuit evaluation: stops at first FALSE value\n */\n\n/**\n * Convert a cell value to boolean for logical evaluation\n */\nfunction isTruthy(value: CellValue): boolean {\n switch (value.type) {\n case \"boolean\":\n return value.value;\n case \"number\":\n return value.value !== 0;\n case \"string\":\n return value.value !== \"\";\n case \"infinity\":\n return true; // Infinity is truthy\n default:\n return false;\n }\n}\n\n// AND function does not create spilled results - it processes all values in ranges\n// as individual logical tests and returns a single boolean result\n\n/**\n * AND function implementation\n */\nexport const AND: FunctionDefinition = {\n name: \"AND\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length === 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"AND function requires at least one argument\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Process arguments one by one (like SUM function)\n for (const arg of node.args) {\n const argResult = this.evaluateNode(arg, context);\n\n if (argResult.type === \"error\" || argResult.type === \"awaiting-evaluation\") {\n return argResult;\n }\n\n if (argResult.type === \"value\") {\n // Single value - check if truthy\n if (!isTruthy(argResult.result)) {\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n } else if (argResult.type === \"spilled-values\") {\n // Range - check all values in the range\n const cellValues = argResult.evaluateAllCells.call(this, {\n context,\n origin: context.cellAddress,\n evaluate: argResult.evaluate,\n lookupOrder: \"col-major\",\n });\n\n if (cellValues.type === \"error\" || cellValues.type === \"awaiting-evaluation\") {\n return cellValues;\n }\n\n for (const cellValue of cellValues.values) {\n if (cellValue.result.type === \"error\") {\n return cellValue.result;\n }\n if (cellValue.result.type === \"value\") {\n if (!isTruthy(cellValue.result.result)) {\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n }\n }\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument type for AND function\",\n errAddress: context.dependencyNode,\n };\n }\n }\n\n // All arguments are truthy\n return {\n type: \"value\",\n result: { type: \"boolean\", value: true },\n };\n },\n};\n"
6
+ ],
7
+ "mappings": ";AAAA;AAAA;AAAA;AAuCA,SAAS,QAAQ,CAAC,OAA2B;AAAA,EAC3C,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,MAAM;AAAA,SACV;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAUN,IAAM,MAA0B;AAAA,EACrC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,MAAM,YAAY,KAAK,aAAa,KAAK,OAAO;AAAA,MAEhD,IAAI,UAAU,SAAS,WAAW,UAAU,SAAS,uBAAuB;AAAA,QAC1E,OAAO;AAAA,MACT;AAAA,MAEA,IAAI,UAAU,SAAS,SAAS;AAAA,QAE9B,IAAI,CAAC,SAAS,UAAU,MAAM,GAAG;AAAA,UAC/B,OAAO;AAAA,YACL,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,UAC1C;AAAA,QACF;AAAA,MACF,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,QAE9C,MAAM,aAAa,UAAU,iBAAiB,KAAK,MAAM;AAAA,UACvD;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,UAAU,UAAU;AAAA,UACpB,aAAa;AAAA,QACf,CAAC;AAAA,QAED,IAAI,WAAW,SAAS,WAAW,WAAW,SAAS,uBAAuB;AAAA,UAC5E,OAAO;AAAA,QACT;AAAA,QAEA,WAAW,aAAa,WAAW,QAAQ;AAAA,UACzC,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,YACrC,OAAO,UAAU;AAAA,UACnB;AAAA,UACA,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,YACrC,IAAI,CAAC,SAAS,UAAU,OAAO,MAAM,GAAG;AAAA,cACtC,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,cAC1C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,EAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA;AAAA,IAEJ;AAAA,IAGA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,IACzC;AAAA;AAEJ;",
8
+ "debugId": "83035E28B8777BF964756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,167 @@
1
+ // src/functions/logical/if/if.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ function isTruthy(value) {
6
+ switch (value.type) {
7
+ case "boolean":
8
+ return value.value;
9
+ case "number":
10
+ return value.value !== 0;
11
+ case "string":
12
+ return value.value !== "";
13
+ case "infinity":
14
+ return true;
15
+ default:
16
+ return false;
17
+ }
18
+ }
19
+ function createIfSpilledResult({
20
+ logicalTestResult,
21
+ valueIfTrueResult,
22
+ valueIfFalseResult,
23
+ context
24
+ }) {
25
+ const hasSpilledTest = logicalTestResult.type === "spilled-values";
26
+ const hasSpilledTrue = valueIfTrueResult.type === "spilled-values";
27
+ const hasSpilledFalse = valueIfFalseResult.type === "spilled-values";
28
+ if (!hasSpilledTest && !hasSpilledTrue && !hasSpilledFalse) {
29
+ throw new Error("createIfSpilledResult called without spilled values");
30
+ }
31
+ return {
32
+ type: "spilled-values",
33
+ spillArea: (origin) => {
34
+ let spillArea;
35
+ const spilledResults = [
36
+ hasSpilledTest ? logicalTestResult : null,
37
+ hasSpilledTrue ? valueIfTrueResult : null,
38
+ hasSpilledFalse ? valueIfFalseResult : null
39
+ ].filter(Boolean);
40
+ for (const result of spilledResults) {
41
+ const currentSpillArea = result.spillArea(origin);
42
+ if (!spillArea) {
43
+ spillArea = currentSpillArea;
44
+ } else {
45
+ spillArea = this.unionRanges(this.projectRange(spillArea, origin), this.projectRange(currentSpillArea, origin));
46
+ }
47
+ }
48
+ if (!spillArea) {
49
+ throw new Error("No spilled values found");
50
+ }
51
+ return spillArea;
52
+ },
53
+ source: "IF with spilled values",
54
+ evaluate: (spilledCell, evalContext) => {
55
+ const spillLogicalResult = hasSpilledTest ? logicalTestResult.evaluate(spilledCell, evalContext) : logicalTestResult;
56
+ const spillTrueResult = hasSpilledTrue ? valueIfTrueResult.evaluate(spilledCell, evalContext) : valueIfTrueResult;
57
+ const spillFalseResult = hasSpilledFalse ? valueIfFalseResult.evaluate(spilledCell, evalContext) : valueIfFalseResult;
58
+ if (spillLogicalResult === undefined) {
59
+ return {
60
+ type: "error",
61
+ err: FormulaError.REF,
62
+ message: "The spilled logical test has not been evaluated",
63
+ errAddress: context.dependencyNode
64
+ };
65
+ }
66
+ if (spillLogicalResult.type === "error" || spillLogicalResult.type === "awaiting-evaluation") {
67
+ return spillLogicalResult;
68
+ }
69
+ if (spillTrueResult === undefined) {
70
+ return {
71
+ type: "error",
72
+ err: FormulaError.REF,
73
+ message: "The spilled true value has not been evaluated",
74
+ errAddress: context.dependencyNode
75
+ };
76
+ }
77
+ if (spillTrueResult.type === "error" || spillTrueResult.type === "awaiting-evaluation") {
78
+ return spillTrueResult;
79
+ }
80
+ if (spillFalseResult === undefined) {
81
+ return {
82
+ type: "error",
83
+ err: FormulaError.REF,
84
+ message: "The spilled false value has not been evaluated",
85
+ errAddress: context.dependencyNode
86
+ };
87
+ }
88
+ if (spillFalseResult.type === "error" || spillFalseResult.type === "awaiting-evaluation") {
89
+ return spillFalseResult;
90
+ }
91
+ if (spillLogicalResult.type !== "value") {
92
+ return {
93
+ type: "error",
94
+ err: FormulaError.VALUE,
95
+ message: "Invalid logical test result",
96
+ errAddress: context.dependencyNode
97
+ };
98
+ }
99
+ const isTrue = isTruthy(spillLogicalResult.result);
100
+ return isTrue ? spillTrueResult : spillFalseResult;
101
+ },
102
+ evaluateAllCells: (intersectingRange) => {
103
+ throw new Error("WIP: evaluateAllCells for IF is not implemented");
104
+ }
105
+ };
106
+ }
107
+ var IF = {
108
+ name: "IF",
109
+ evaluate: function(node, context) {
110
+ if (node.args.length < 2 || node.args.length > 3) {
111
+ return {
112
+ type: "error",
113
+ err: FormulaError.VALUE,
114
+ message: "IF function takes 2 or 3 arguments",
115
+ errAddress: context.dependencyNode
116
+ };
117
+ }
118
+ const logicalTestResult = this.evaluateNode(node.args[0], context);
119
+ if (logicalTestResult.type === "awaiting-evaluation" || logicalTestResult.type === "error") {
120
+ return logicalTestResult;
121
+ }
122
+ if (logicalTestResult.type === "spilled-values") {
123
+ const valueIfTrueResult = this.evaluateNode(node.args[1], context);
124
+ if (valueIfTrueResult.type === "error" || valueIfTrueResult.type === "awaiting-evaluation") {
125
+ return valueIfTrueResult;
126
+ }
127
+ let valueIfFalseResult;
128
+ if (node.args.length > 2) {
129
+ valueIfFalseResult = this.evaluateNode(node.args[2], context);
130
+ if (valueIfFalseResult.type === "error" || valueIfFalseResult.type === "awaiting-evaluation") {
131
+ return valueIfFalseResult;
132
+ }
133
+ } else {
134
+ valueIfFalseResult = {
135
+ type: "value",
136
+ result: { type: "boolean", value: false }
137
+ };
138
+ }
139
+ return createIfSpilledResult.call(this, {
140
+ logicalTestResult,
141
+ valueIfTrueResult,
142
+ valueIfFalseResult,
143
+ context
144
+ });
145
+ }
146
+ const isTrue = isTruthy(logicalTestResult.result);
147
+ if (isTrue) {
148
+ const valueIfTrueResult = this.evaluateNode(node.args[1], context);
149
+ return valueIfTrueResult;
150
+ } else {
151
+ if (node.args.length > 2) {
152
+ const valueIfFalseResult = this.evaluateNode(node.args[2], context);
153
+ return valueIfFalseResult;
154
+ } else {
155
+ return {
156
+ type: "value",
157
+ result: { type: "boolean", value: false }
158
+ };
159
+ }
160
+ }
161
+ }
162
+ };
163
+ export {
164
+ IF
165
+ };
166
+
167
+ //# debugId=B7DDA16B3C6C29FD64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/logical/if/if.ts"],
4
+ "sourcesContent": [
5
+ "import {\n FormulaError,\n type CellValue,\n type CellNumber,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type SpilledValuesEvaluationResult,\n type SingleEvaluationResult,\n type ErrorEvaluationResult,\n} from \"src/core/types\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\n\n/**\n * IF function - Returns one value if a condition is true and another value if it's false\n *\n * Usage: IF(logical_test, value_if_true, [value_if_false])\n *\n * logical_test: The condition to evaluate (required)\n * value_if_true: The value to return if the condition is true (required)\n * value_if_false: The value to return if the condition is false (optional, defaults to FALSE)\n *\n * Examples:\n * IF(A1>10, \"High\", \"Low\") - returns \"High\" if A1>10, otherwise \"Low\"\n * IF(B1=\"\", \"Empty\", B1) - returns \"Empty\" if B1 is empty, otherwise B1's value\n * IF(C1<0, \"Negative\") - returns \"Negative\" if C1<0, otherwise FALSE\n *\n * Note:\n * - Supports spilled values (dynamic arrays) for all arguments\n * - Logical test evaluation: 0 and empty string are FALSE, everything else is TRUE\n * - If logical_test is spilled, returns spilled results\n */\n\n/**\n * Convert a cell value to boolean for logical evaluation\n */\nfunction isTruthy(value: CellValue): boolean {\n switch (value.type) {\n case \"boolean\":\n return value.value;\n case \"number\":\n return value.value !== 0;\n case \"string\":\n return value.value !== \"\";\n case \"infinity\":\n return true; // Infinity is truthy\n default:\n return false;\n }\n}\n\n/**\n * Helper for creating spilled-values result for IF function\n */\nfunction createIfSpilledResult(\n this: FormulaEvaluator,\n {\n logicalTestResult,\n valueIfTrueResult,\n valueIfFalseResult,\n context,\n }: {\n logicalTestResult: FunctionEvaluationResult;\n valueIfTrueResult: FunctionEvaluationResult;\n valueIfFalseResult: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n const hasSpilledTest = logicalTestResult.type === \"spilled-values\";\n const hasSpilledTrue = valueIfTrueResult.type === \"spilled-values\";\n const hasSpilledFalse = valueIfFalseResult.type === \"spilled-values\";\n\n if (!hasSpilledTest && !hasSpilledTrue && !hasSpilledFalse) {\n throw new Error(\"createIfSpilledResult called without spilled values\");\n }\n\n return {\n type: \"spilled-values\",\n spillArea: (origin: CellAddress): SpreadsheetRange => {\n // Calculate spill area (union of all spilled ranges)\n let spillArea: SpreadsheetRange | undefined;\n\n const spilledResults = [\n hasSpilledTest ? logicalTestResult : null,\n hasSpilledTrue ? valueIfTrueResult : null,\n hasSpilledFalse ? valueIfFalseResult : null,\n ].filter(Boolean) as SpilledValuesEvaluationResult[];\n\n for (const result of spilledResults) {\n const currentSpillArea = result.spillArea(origin);\n if (!spillArea) {\n spillArea = currentSpillArea;\n } else {\n spillArea = this.unionRanges(\n this.projectRange(spillArea, origin),\n this.projectRange(currentSpillArea, origin)\n );\n }\n }\n\n if (!spillArea) {\n throw new Error(\"No spilled values found\");\n }\n return spillArea;\n },\n source: \"IF with spilled values\",\n evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n // Evaluate all arguments at this spilled position\n const spillLogicalResult = hasSpilledTest\n ? logicalTestResult.evaluate(spilledCell, evalContext)\n : logicalTestResult;\n const spillTrueResult = hasSpilledTrue\n ? valueIfTrueResult.evaluate(spilledCell, evalContext)\n : valueIfTrueResult;\n const spillFalseResult = hasSpilledFalse\n ? valueIfFalseResult.evaluate(spilledCell, evalContext)\n : valueIfFalseResult;\n\n // Check for errors\n if (spillLogicalResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled logical test has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillLogicalResult.type === \"error\" || spillLogicalResult.type === \"awaiting-evaluation\") {\n return spillLogicalResult;\n }\n\n if (spillTrueResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled true value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillTrueResult.type === \"error\" || spillTrueResult.type === \"awaiting-evaluation\") {\n return spillTrueResult;\n }\n\n if (spillFalseResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled false value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillFalseResult.type === \"error\" || spillFalseResult.type === \"awaiting-evaluation\") {\n return spillFalseResult;\n }\n\n // Perform IF logic\n if (spillLogicalResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid logical test result\",\n errAddress: context.dependencyNode,\n };\n }\n\n const isTrue = isTruthy(spillLogicalResult.result);\n return isTrue ? spillTrueResult : spillFalseResult;\n },\n evaluateAllCells: (intersectingRange: any) => {\n throw new Error(\"WIP: evaluateAllCells for IF is not implemented\");\n },\n };\n}\n\n/**\n * IF function implementation\n */\nexport const IF: FunctionDefinition = {\n name: \"IF\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 2 || node.args.length > 3) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"IF function takes 2 or 3 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate logical test\n const logicalTestResult = this.evaluateNode(node.args[0]!, context);\n if (\n logicalTestResult.type === \"awaiting-evaluation\" ||\n logicalTestResult.type === \"error\"\n ) {\n return logicalTestResult;\n }\n\n // Handle spilled values - we need to evaluate both branches\n // because different cells might take different paths\n if (logicalTestResult.type === \"spilled-values\") {\n // Evaluate value_if_true\n const valueIfTrueResult = this.evaluateNode(node.args[1]!, context);\n if (valueIfTrueResult.type === \"error\" || valueIfTrueResult.type === \"awaiting-evaluation\") {\n return valueIfTrueResult;\n }\n\n // Evaluate value_if_false (optional, defaults to FALSE)\n let valueIfFalseResult: FunctionEvaluationResult;\n if (node.args.length > 2) {\n valueIfFalseResult = this.evaluateNode(node.args[2]!, context);\n if (valueIfFalseResult.type === \"error\" || valueIfFalseResult.type === \"awaiting-evaluation\") {\n return valueIfFalseResult;\n }\n } else {\n valueIfFalseResult = {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n\n return createIfSpilledResult.call(this, {\n logicalTestResult,\n valueIfTrueResult,\n valueIfFalseResult,\n context,\n });\n }\n\n // Evaluate the logical test\n const isTrue = isTruthy(logicalTestResult.result);\n\n // LAZY EVALUATION: Only evaluate the branch we need\n if (isTrue) {\n // Evaluate value_if_true\n const valueIfTrueResult = this.evaluateNode(node.args[1]!, context);\n return valueIfTrueResult;\n } else {\n // Evaluate value_if_false (optional, defaults to FALSE)\n if (node.args.length > 2) {\n const valueIfFalseResult = this.evaluateNode(node.args[2]!, context);\n return valueIfFalseResult;\n } else {\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n }\n },\n};\n"
6
+ ],
7
+ "mappings": ";AAAA;AAAA;AAAA;AAuCA,SAAS,QAAQ,CAAC,OAA2B;AAAA,EAC3C,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,MAAM;AAAA,SACV;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAOb,SAAS,qBAAqB;AAAA,EAG1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,GAOqD;AAAA,EACvD,MAAM,iBAAiB,kBAAkB,SAAS;AAAA,EAClD,MAAM,iBAAiB,kBAAkB,SAAS;AAAA,EAClD,MAAM,kBAAkB,mBAAmB,SAAS;AAAA,EAEpD,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,iBAAiB;AAAA,IAC1D,MAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,WAAW,CAAC,WAA0C;AAAA,MAEpD,IAAI;AAAA,MAEJ,MAAM,iBAAiB;AAAA,QACrB,iBAAiB,oBAAoB;AAAA,QACrC,iBAAiB,oBAAoB;AAAA,QACrC,kBAAkB,qBAAqB;AAAA,MACzC,EAAE,OAAO,OAAO;AAAA,MAEhB,WAAW,UAAU,gBAAgB;AAAA,QACnC,MAAM,mBAAmB,OAAO,UAAU,MAAM;AAAA,QAChD,IAAI,CAAC,WAAW;AAAA,UACd,YAAY;AAAA,QACd,EAAO;AAAA,UACL,YAAY,KAAK,YACf,KAAK,aAAa,WAAW,MAAM,GACnC,KAAK,aAAa,kBAAkB,MAAM,CAC5C;AAAA;AAAA,MAEJ;AAAA,MAEA,IAAI,CAAC,WAAW;AAAA,QACd,MAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AAAA,MACA,OAAO;AAAA;AAAA,IAET,QAAQ;AAAA,IACR,UAAU,CAAC,aAAkB,gBAA6C;AAAA,MAExE,MAAM,qBAAqB,iBACvB,kBAAkB,SAAS,aAAa,WAAW,IACnD;AAAA,MACJ,MAAM,kBAAkB,iBACpB,kBAAkB,SAAS,aAAa,WAAW,IACnD;AAAA,MACJ,MAAM,mBAAmB,kBACrB,mBAAmB,SAAS,aAAa,WAAW,IACpD;AAAA,MAGJ,IAAI,uBAAuB,WAAW;AAAA,QACpC,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MACA,IAAI,mBAAmB,SAAS,WAAW,mBAAmB,SAAS,uBAAuB;AAAA,QAC5F,OAAO;AAAA,MACT;AAAA,MAEA,IAAI,oBAAoB,WAAW;AAAA,QACjC,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MACA,IAAI,gBAAgB,SAAS,WAAW,gBAAgB,SAAS,uBAAuB;AAAA,QACtF,OAAO;AAAA,MACT;AAAA,MAEA,IAAI,qBAAqB,WAAW;AAAA,QAClC,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MACA,IAAI,iBAAiB,SAAS,WAAW,iBAAiB,SAAS,uBAAuB;AAAA,QACxF,OAAO;AAAA,MACT;AAAA,MAGA,IAAI,mBAAmB,SAAS,SAAS;AAAA,QACvC,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,MAEA,MAAM,SAAS,SAAS,mBAAmB,MAAM;AAAA,MACjD,OAAO,SAAS,kBAAkB;AAAA;AAAA,IAEpC,kBAAkB,CAAC,sBAA2B;AAAA,MAC5C,MAAM,IAAI,MAAM,iDAAiD;AAAA;AAAA,EAErE;AAAA;AAMK,IAAM,KAAyB;AAAA,EACpC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,GAAG;AAAA,MAChD,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,oBAAoB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAClE,IACE,kBAAkB,SAAS,yBAC3B,kBAAkB,SAAS,SAC3B;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAIA,IAAI,kBAAkB,SAAS,kBAAkB;AAAA,MAE/C,MAAM,oBAAoB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,MAClE,IAAI,kBAAkB,SAAS,WAAW,kBAAkB,SAAS,uBAAuB;AAAA,QAC1F,OAAO;AAAA,MACT;AAAA,MAGA,IAAI;AAAA,MACJ,IAAI,KAAK,KAAK,SAAS,GAAG;AAAA,QACxB,qBAAqB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,QAC7D,IAAI,mBAAmB,SAAS,WAAW,mBAAmB,SAAS,uBAAuB;AAAA,UAC5F,OAAO;AAAA,QACT;AAAA,MACF,EAAO;AAAA,QACL,qBAAqB;AAAA,UACnB,MAAM;AAAA,UACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,QAC1C;AAAA;AAAA,MAGF,OAAO,sBAAsB,KAAK,MAAM;AAAA,QACtC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAGA,MAAM,SAAS,SAAS,kBAAkB,MAAM;AAAA,IAGhD,IAAI,QAAQ;AAAA,MAEV,MAAM,oBAAoB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,MAClE,OAAO;AAAA,IACT,EAAO;AAAA,MAEL,IAAI,KAAK,KAAK,SAAS,GAAG;AAAA,QACxB,MAAM,qBAAqB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,QACnE,OAAO;AAAA,MACT,EAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,QAC1C;AAAA;AAAA;AAAA;AAIR;",
8
+ "debugId": "B7DDA16B3C6C29FD64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,98 @@
1
+ // src/functions/logical/iferror/iferror.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ import { captureEvaluationErrors } from "src/core/utils";
6
+ function createIfErrorSpilledResult({
7
+ valueResult,
8
+ valueIfErrorResult,
9
+ context
10
+ }) {
11
+ const hasSpilledValue = valueResult.type === "spilled-values";
12
+ const hasSpilledError = valueIfErrorResult.type === "spilled-values";
13
+ if (!hasSpilledValue && !hasSpilledError) {
14
+ throw new Error("createIfErrorSpilledResult called without spilled values");
15
+ }
16
+ return {
17
+ type: "spilled-values",
18
+ spillArea: (origin) => {
19
+ if (hasSpilledValue && valueResult.type === "spilled-values") {
20
+ const spillArea = valueResult.spillArea(origin);
21
+ if (hasSpilledError && valueIfErrorResult.type === "spilled-values") {
22
+ return this.unionRanges(this.projectRange(spillArea, origin), this.projectRange(valueIfErrorResult.spillArea(origin), origin));
23
+ }
24
+ return spillArea;
25
+ } else if (hasSpilledError && valueIfErrorResult.type === "spilled-values") {
26
+ return valueIfErrorResult.spillArea(origin);
27
+ } else {
28
+ throw new Error("No spilled values found");
29
+ }
30
+ },
31
+ source: "IFERROR with spilled values",
32
+ evaluate: (spilledCell, evalContext) => {
33
+ const spillValueResult = hasSpilledValue ? valueResult.evaluate(spilledCell, evalContext) : valueResult;
34
+ const spillErrorResult = hasSpilledError ? valueIfErrorResult.evaluate(spilledCell, evalContext) : valueIfErrorResult;
35
+ if (spillValueResult === undefined) {
36
+ return {
37
+ type: "error",
38
+ err: FormulaError.REF,
39
+ message: "The spilled value has not been evaluated",
40
+ errAddress: context.dependencyNode
41
+ };
42
+ }
43
+ if (spillErrorResult === undefined) {
44
+ return {
45
+ type: "error",
46
+ err: FormulaError.REF,
47
+ message: "The spilled error value has not been evaluated",
48
+ errAddress: context.dependencyNode
49
+ };
50
+ }
51
+ if (spillValueResult.type === "error" || spillValueResult.type === "awaiting-evaluation") {
52
+ return spillErrorResult;
53
+ }
54
+ return spillValueResult;
55
+ },
56
+ evaluateAllCells: (intersectingRange) => {
57
+ throw new Error("WIP: evaluateAllCells for IFERROR is not implemented");
58
+ }
59
+ };
60
+ }
61
+ var IFERROR = {
62
+ name: "IFERROR",
63
+ evaluate: function(node, context) {
64
+ if (node.args.length !== 2) {
65
+ return {
66
+ type: "error",
67
+ err: FormulaError.VALUE,
68
+ message: "IFERROR function takes exactly 2 arguments",
69
+ errAddress: context.dependencyNode
70
+ };
71
+ }
72
+ const valueResult = captureEvaluationErrors(context.dependencyNode, () => this.evaluateNode(node.args[0], context));
73
+ if (valueResult.type === "awaiting-evaluation") {
74
+ return valueResult;
75
+ }
76
+ if (valueResult.type === "spilled-values") {
77
+ const valueIfErrorResult = this.evaluateNode(node.args[1], context);
78
+ if (valueIfErrorResult.type === "error" || valueIfErrorResult.type === "awaiting-evaluation") {
79
+ return valueIfErrorResult;
80
+ }
81
+ return createIfErrorSpilledResult.call(this, {
82
+ valueResult,
83
+ valueIfErrorResult,
84
+ context
85
+ });
86
+ }
87
+ if (valueResult.type === "error") {
88
+ const valueIfErrorResult = this.evaluateNode(node.args[1], context);
89
+ return valueIfErrorResult;
90
+ }
91
+ return valueResult;
92
+ }
93
+ };
94
+ export {
95
+ IFERROR
96
+ };
97
+
98
+ //# debugId=CC626D59CFEBD9BB64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/logical/iferror/iferror.ts"],
4
+ "sourcesContent": [
5
+ "import {\n FormulaError,\n type CellValue,\n type CellNumber,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type SpilledValuesEvaluationResult,\n type SingleEvaluationResult,\n type ErrorEvaluationResult,\n} from \"src/core/types\";\nimport { captureEvaluationErrors } from \"src/core/utils\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\n\n/**\n * IFERROR function - Returns a value you specify if a formula evaluates to an error\n *\n * Usage: IFERROR(value, value_if_error)\n *\n * value: The expression to check for errors (required)\n * value_if_error: The value to return if the expression is an error (required)\n *\n * Examples:\n * IFERROR(A1/B1, \"Division error\") - returns \"Division error\" if B1 is 0\n * IFERROR(VLOOKUP(A1, table, 2), \"Not found\") - returns \"Not found\" if lookup fails\n * IFERROR(1/0, 0) - returns 0 instead of #DIV/0! error\n *\n * Note:\n * - If value is not an error, returns the value unchanged\n * - If value is an error, returns value_if_error\n * - Supports spilled values (dynamic arrays) for both arguments\n * - Any error type (#VALUE!, #DIV/0!, #N/A, etc.) triggers the error handling\n */\n\n/**\n * Helper for creating spilled-values result for IFERROR function\n */\nfunction createIfErrorSpilledResult(\n this: FormulaEvaluator,\n {\n valueResult,\n valueIfErrorResult,\n context,\n }: {\n valueResult: FunctionEvaluationResult;\n valueIfErrorResult: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n const hasSpilledValue = valueResult.type === \"spilled-values\";\n const hasSpilledError = valueIfErrorResult.type === \"spilled-values\";\n\n if (!hasSpilledValue && !hasSpilledError) {\n throw new Error(\"createIfErrorSpilledResult called without spilled values\");\n }\n\n return {\n type: \"spilled-values\",\n spillArea: (origin: CellAddress): SpreadsheetRange => {\n // Calculate spill area (union of spilled ranges)\n if (hasSpilledValue && valueResult.type === \"spilled-values\") {\n const spillArea = valueResult.spillArea(origin);\n if (hasSpilledError && valueIfErrorResult.type === \"spilled-values\") {\n return this.unionRanges(\n this.projectRange(spillArea, origin),\n this.projectRange(valueIfErrorResult.spillArea(origin), origin)\n );\n }\n return spillArea;\n } else if (\n hasSpilledError &&\n valueIfErrorResult.type === \"spilled-values\"\n ) {\n return valueIfErrorResult.spillArea(origin);\n } else {\n throw new Error(\"No spilled values found\");\n }\n },\n source: \"IFERROR with spilled values\",\n evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n // Evaluate arguments at this spilled position\n const spillValueResult = hasSpilledValue\n ? valueResult.evaluate(spilledCell, evalContext)\n : valueResult;\n const spillErrorResult = hasSpilledError\n ? valueIfErrorResult.evaluate(spilledCell, evalContext)\n : valueIfErrorResult;\n\n if (spillValueResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (spillErrorResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled error value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n\n // IFERROR logic: if first argument is error, return second argument\n if (\n spillValueResult.type === \"error\" ||\n spillValueResult.type === \"awaiting-evaluation\"\n ) {\n return spillErrorResult;\n }\n\n // If first argument is not an error, return it\n return spillValueResult;\n },\n evaluateAllCells: (intersectingRange: any) => {\n throw new Error(\"WIP: evaluateAllCells for IFERROR is not implemented\");\n },\n };\n}\n\n/**\n * IFERROR function implementation\n */\nexport const IFERROR: FunctionDefinition = {\n name: \"IFERROR\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length !== 2) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"IFERROR function takes exactly 2 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate the value argument (the expression to check for errors)\n const valueResult = captureEvaluationErrors(\n context.dependencyNode,\n () => this.evaluateNode(node.args[0]!, context)\n );\n\n if (valueResult.type === \"awaiting-evaluation\") {\n return valueResult;\n }\n\n // Handle spilled values - we need to evaluate both branches\n // because different cells might have errors or not\n if (valueResult.type === \"spilled-values\") {\n // Evaluate the value_if_error argument\n const valueIfErrorResult = this.evaluateNode(node.args[1]!, context);\n if (\n valueIfErrorResult.type === \"error\" ||\n valueIfErrorResult.type === \"awaiting-evaluation\"\n ) {\n return valueIfErrorResult; // Error in the error handler itself\n }\n\n return createIfErrorSpilledResult.call(this, {\n valueResult,\n valueIfErrorResult,\n context,\n });\n }\n\n // LAZY EVALUATION: Only evaluate error handler if we have an error\n // IFERROR logic: if first argument is error, return second argument\n if (valueResult.type === \"error\") {\n const valueIfErrorResult = this.evaluateNode(node.args[1]!, context);\n return valueIfErrorResult;\n }\n\n // If first argument is not an error, return it unchanged\n // WITHOUT evaluating the error handler\n return valueResult;\n },\n};\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "CC626D59CFEBD9BB64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,84 @@
1
+ // src/functions/logical/or/or.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ function isTruthy(value) {
6
+ switch (value.type) {
7
+ case "boolean":
8
+ return value.value;
9
+ case "number":
10
+ return value.value !== 0;
11
+ case "string":
12
+ return value.value !== "";
13
+ case "infinity":
14
+ return true;
15
+ default:
16
+ return false;
17
+ }
18
+ }
19
+ var OR = {
20
+ name: "OR",
21
+ evaluate: function(node, context) {
22
+ if (node.args.length === 0) {
23
+ return {
24
+ type: "error",
25
+ err: FormulaError.VALUE,
26
+ message: "OR function requires at least one argument",
27
+ errAddress: context.dependencyNode
28
+ };
29
+ }
30
+ for (const arg of node.args) {
31
+ const argResult = this.evaluateNode(arg, context);
32
+ if (argResult.type === "error" || argResult.type === "awaiting-evaluation") {
33
+ return argResult;
34
+ }
35
+ if (argResult.type === "value") {
36
+ if (isTruthy(argResult.result)) {
37
+ return {
38
+ type: "value",
39
+ result: { type: "boolean", value: true }
40
+ };
41
+ }
42
+ } else if (argResult.type === "spilled-values") {
43
+ const cellValues = argResult.evaluateAllCells.call(this, {
44
+ context,
45
+ origin: context.cellAddress,
46
+ evaluate: argResult.evaluate,
47
+ lookupOrder: "col-major"
48
+ });
49
+ if (cellValues.type === "error" || cellValues.type === "awaiting-evaluation") {
50
+ return cellValues;
51
+ }
52
+ for (const cellValue of cellValues.values) {
53
+ if (cellValue.result.type === "error" || cellValue.result.type === "awaiting-evaluation") {
54
+ return cellValue.result;
55
+ }
56
+ if (cellValue.result.type === "value") {
57
+ if (isTruthy(cellValue.result.result)) {
58
+ return {
59
+ type: "value",
60
+ result: { type: "boolean", value: true }
61
+ };
62
+ }
63
+ }
64
+ }
65
+ } else {
66
+ return {
67
+ type: "error",
68
+ err: FormulaError.VALUE,
69
+ message: "Invalid argument type for OR function",
70
+ errAddress: context.dependencyNode
71
+ };
72
+ }
73
+ }
74
+ return {
75
+ type: "value",
76
+ result: { type: "boolean", value: false }
77
+ };
78
+ }
79
+ };
80
+ export {
81
+ OR
82
+ };
83
+
84
+ //# debugId=1823CFBC008C71DB64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/logical/or/or.ts"],
4
+ "sourcesContent": [
5
+ "import {\n FormulaError,\n type CellValue,\n type CellNumber,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type SpilledValuesEvaluationResult,\n type SingleEvaluationResult,\n type ErrorEvaluationResult,\n} from \"src/core/types\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * OR function - Returns TRUE if any argument is TRUE, FALSE otherwise\n *\n * Usage: OR(logical1, [logical2], ...)\n *\n * logical1, logical2, ...: Logical values or expressions to evaluate\n *\n * Examples:\n * OR(TRUE, FALSE) - returns TRUE\n * OR(FALSE, FALSE) - returns FALSE\n * OR(A1>10, B1<20) - returns TRUE if either condition is met\n * OR(A1:A3) - returns TRUE if any value in A1:A3 is truthy\n *\n * Note:\n * - Supports spilled values (dynamic arrays) for arguments\n * - Logical evaluation: 0 and empty string are FALSE, everything else is TRUE\n * - If any argument is spilled, processes all values in the range\n * - Short-circuit evaluation: stops at first TRUE value\n */\n\n/**\n * Convert a cell value to boolean for logical evaluation\n */\nfunction isTruthy(value: CellValue): boolean {\n switch (value.type) {\n case \"boolean\":\n return value.value;\n case \"number\":\n return value.value !== 0;\n case \"string\":\n return value.value !== \"\";\n case \"infinity\":\n return true; // Infinity is truthy\n default:\n return false;\n }\n}\n\n// OR function does not create spilled results - it processes all values in ranges\n// as individual logical tests and returns a single boolean result\n\n/**\n * OR function implementation\n */\nexport const OR: FunctionDefinition = {\n name: \"OR\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length === 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OR function requires at least one argument\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Process arguments one by one (like AND function)\n for (const arg of node.args) {\n const argResult = this.evaluateNode(arg, context);\n\n if (argResult.type === \"error\" || argResult.type === \"awaiting-evaluation\") {\n return argResult;\n }\n\n if (argResult.type === \"value\") {\n // Single value - check if truthy\n if (isTruthy(argResult.result)) {\n // Short-circuit: return TRUE on first truthy value\n return {\n type: \"value\",\n result: { type: \"boolean\", value: true },\n };\n }\n } else if (argResult.type === \"spilled-values\") {\n // Range - check all values in the range\n const cellValues = argResult.evaluateAllCells.call(this, {\n context,\n origin: context.cellAddress,\n evaluate: argResult.evaluate,\n lookupOrder: \"col-major\",\n });\n if (cellValues.type === \"error\" || cellValues.type === \"awaiting-evaluation\") {\n return cellValues;\n }\n for (const cellValue of cellValues.values) {\n if (cellValue.result.type === \"error\" || cellValue.result.type === \"awaiting-evaluation\") {\n return cellValue.result;\n }\n if (cellValue.result.type === \"value\") {\n if (isTruthy(cellValue.result.result)) {\n // Short-circuit: return TRUE on first truthy value\n return {\n type: \"value\",\n result: { type: \"boolean\", value: true },\n };\n }\n }\n }\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument type for OR function\",\n errAddress: context.dependencyNode,\n };\n }\n }\n\n // All arguments are falsy\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n },\n};\n"
6
+ ],
7
+ "mappings": ";AAAA;AAAA;AAAA;AAuCA,SAAS,QAAQ,CAAC,OAA2B;AAAA,EAC3C,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,MAAM;AAAA,SACV;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAUN,IAAM,KAAyB;AAAA,EACpC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,MAAM,YAAY,KAAK,aAAa,KAAK,OAAO;AAAA,MAEhD,IAAI,UAAU,SAAS,WAAW,UAAU,SAAS,uBAAuB;AAAA,QAC1E,OAAO;AAAA,MACT;AAAA,MAEA,IAAI,UAAU,SAAS,SAAS;AAAA,QAE9B,IAAI,SAAS,UAAU,MAAM,GAAG;AAAA,UAE9B,OAAO;AAAA,YACL,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,UACzC;AAAA,QACF;AAAA,MACF,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,QAE9C,MAAM,aAAa,UAAU,iBAAiB,KAAK,MAAM;AAAA,UACvD;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,UAAU,UAAU;AAAA,UACpB,aAAa;AAAA,QACf,CAAC;AAAA,QACD,IAAI,WAAW,SAAS,WAAW,WAAW,SAAS,uBAAuB;AAAA,UAC5E,OAAO;AAAA,QACT;AAAA,QACA,WAAW,aAAa,WAAW,QAAQ;AAAA,UACzC,IAAI,UAAU,OAAO,SAAS,WAAW,UAAU,OAAO,SAAS,uBAAuB;AAAA,YACxF,OAAO,UAAU;AAAA,UACnB;AAAA,UACA,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,YACrC,IAAI,SAAS,UAAU,OAAO,MAAM,GAAG;AAAA,cAErC,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,cACzC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,EAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA;AAAA,IAEJ;AAAA,IAGA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,IAC1C;AAAA;AAEJ;",
8
+ "debugId": "1823CFBC008C71DB64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,35 @@
1
+ // src/functions/lookup/count/count-utils.ts
2
+ function performCount(results) {
3
+ let count = 0;
4
+ for (const result of results) {
5
+ if (result.type === "error" || result.type === "awaiting-evaluation") {
6
+ return result;
7
+ }
8
+ if (result.type === "value") {
9
+ if (result.result.type === "number" || result.result.type === "infinity") {
10
+ count++;
11
+ }
12
+ }
13
+ }
14
+ return {
15
+ type: "value",
16
+ result: { type: "number", value: count }
17
+ };
18
+ }
19
+ function countEmptyCells(criteriaRangeResult, parsedCriteria, currentCell) {
20
+ if (criteriaRangeResult.type === "spilled-values" && parsedCriteria.type === "exact" && parsedCriteria.value.type === "string" && parsedCriteria.value.value === "") {
21
+ const spillArea = criteriaRangeResult.spillArea(currentCell);
22
+ if (spillArea.end.col.type === "infinity" || spillArea.end.row.type === "infinity") {
23
+ return {
24
+ type: "value",
25
+ result: { type: "infinity", sign: "positive" }
26
+ };
27
+ }
28
+ }
29
+ }
30
+ export {
31
+ performCount,
32
+ countEmptyCells
33
+ };
34
+
35
+ //# debugId=27BAB068756EB60864756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/lookup/count/count-utils.ts"],
4
+ "sourcesContent": [
5
+ "import {\n type CellAddress,\n type FunctionEvaluationResult,\n type SingleEvaluationResult,\n} from \"src/core/types\";\nimport type { ParsedCriteria } from \"src/functions/criteria-parser\";\n\n/**\n * Performs counting of numeric values from an iterable of SingleEvaluationResult values\n * Handles numbers and infinities according to Excel's COUNT behavior\n * - Propagates errors immediately\n * - Only counts numeric values (numbers and infinities)\n * - Ignores non-numeric values (strings, booleans, empty cells)\n *\n * @param results - Iterable of SingleEvaluationResult to count\n * @returns FunctionEvaluationResult with the count\n */\nexport function performCount(\n results: Iterable<SingleEvaluationResult>\n): FunctionEvaluationResult {\n let count = 0;\n\n for (const result of results) {\n if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n // Propagate errors immediately\n return result;\n }\n\n if (result.type === \"value\") {\n if (\n result.result.type === \"number\" ||\n result.result.type === \"infinity\"\n ) {\n count++;\n }\n // Non-numeric values (strings, booleans) are ignored\n }\n }\n\n return {\n type: \"value\",\n result: { type: \"number\", value: count },\n };\n}\n\nexport function countEmptyCells(\n criteriaRangeResult: FunctionEvaluationResult,\n parsedCriteria: ParsedCriteria,\n currentCell: CellAddress\n): FunctionEvaluationResult | undefined {\n // Special case: counting empty cells over infinite ranges\n if (\n criteriaRangeResult.type === \"spilled-values\" &&\n parsedCriteria.type === \"exact\" &&\n parsedCriteria.value.type === \"string\" &&\n parsedCriteria.value.value === \"\"\n ) {\n const spillArea = criteriaRangeResult.spillArea(currentCell);\n\n // Check if this is an infinite range\n if (\n spillArea.end.col.type === \"infinity\" ||\n spillArea.end.row.type === \"infinity\"\n ) {\n // Return infinity for infinite empty cell count\n return {\n type: \"value\",\n result: { type: \"infinity\", sign: \"positive\" },\n };\n }\n }\n}\n"
6
+ ],
7
+ "mappings": ";AAiBO,SAAS,YAAY,CAC1B,SAC0B;AAAA,EAC1B,IAAI,QAAQ;AAAA,EAEZ,WAAW,UAAU,SAAS;AAAA,IAC5B,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,uBAAuB;AAAA,MAEpE,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,OAAO,SAAS,SAAS;AAAA,MAC3B,IACE,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,SAAS,YACvB;AAAA,QACA;AAAA,MACF;AAAA,IAEF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,EACzC;AAAA;AAGK,SAAS,eAAe,CAC7B,qBACA,gBACA,aACsC;AAAA,EAEtC,IACE,oBAAoB,SAAS,oBAC7B,eAAe,SAAS,WACxB,eAAe,MAAM,SAAS,YAC9B,eAAe,MAAM,UAAU,IAC/B;AAAA,IACA,MAAM,YAAY,oBAAoB,UAAU,WAAW;AAAA,IAG3D,IACE,UAAU,IAAI,IAAI,SAAS,cAC3B,UAAU,IAAI,IAAI,SAAS,YAC3B;AAAA,MAEA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,YAAY,MAAM,WAAW;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAAA;",
8
+ "debugId": "27BAB068756EB60864756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,18 @@
1
+ // src/functions/lookup/count/count.ts
2
+ import { createArgumentIterator } from "src/functions/function-utils";
3
+ import { performCount } from "./count-utils.mjs";
4
+ var COUNT = {
5
+ name: "COUNT",
6
+ evaluate: function(node, context) {
7
+ const argumentValues = createArgumentIterator(this, node, context, "col-major");
8
+ if (argumentValues.type !== "values") {
9
+ return argumentValues;
10
+ }
11
+ return performCount(argumentValues.values);
12
+ }
13
+ };
14
+ export {
15
+ COUNT
16
+ };
17
+
18
+ //# debugId=06386725A95B4B8F64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/lookup/count/count.ts"],
4
+ "sourcesContent": [
5
+ "import {\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"src/core/types\";\nimport { createArgumentIterator } from \"src/functions/function-utils\";\nimport { performCount } from \"./count-utils.mjs\";\n\n/**\n * COUNT function - Counts the number of cells that contain numbers\n * \n * Usage: COUNT(value1, [value2], ...)\n * \n * Examples:\n * COUNT(1, 2, 3) - returns 3\n * COUNT(A1:A10) - counts numeric values in the range A1:A10\n * COUNT(A1:A5, B1:B5) - counts numeric values in both ranges\n * \n * Note:\n * - Only numeric values are counted (numbers and infinities)\n * - Text, logical values, and empty cells are ignored\n * - Errors propagate immediately\n * \n * From Excel documentation:\n * \"The COUNT function counts the number of cells that contain numbers, \n * and counts numbers within the list of arguments.\"\n */\nexport const COUNT: FunctionDefinition = {\n name: \"COUNT\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // Create iterator over all argument values\n const argumentValues = createArgumentIterator(this, node, context, \"col-major\");\n\n if (argumentValues.type !== \"values\") {\n return argumentValues;\n }\n // Use shared counting utility\n return performCount(argumentValues.values);\n },\n};\n"
6
+ ],
7
+ "mappings": ";AAIA;AACA;AAqBO,IAAM,QAA4B;AAAA,EACvC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAE3D,MAAM,iBAAiB,uBAAuB,MAAM,MAAM,SAAS,WAAW;AAAA,IAE9E,IAAI,eAAe,SAAS,UAAU;AAAA,MACpC,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,aAAa,eAAe,MAAM;AAAA;AAE7C;",
8
+ "debugId": "06386725A95B4B8F64756E2164756E21",
9
+ "names": []
10
+ }