@cj-tech-master/excelts 9.3.1 → 9.4.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 (109) hide show
  1. package/dist/browser/index.d.ts +1 -0
  2. package/dist/browser/index.js +2 -0
  3. package/dist/browser/modules/excel/cell.d.ts +18 -0
  4. package/dist/browser/modules/excel/cell.js +21 -0
  5. package/dist/browser/modules/excel/utils/cell-format.js +85 -13
  6. package/dist/browser/modules/excel/workbook.browser.d.ts +57 -0
  7. package/dist/browser/modules/excel/workbook.browser.js +49 -0
  8. package/dist/browser/modules/excel/xlsx/defaultnumformats.js +3 -3
  9. package/dist/browser/modules/formula/compile/binder.js +48 -6
  10. package/dist/browser/modules/formula/compile/bound-ast.d.ts +16 -2
  11. package/dist/browser/modules/formula/compile/bound-ast.js +1 -0
  12. package/dist/browser/modules/formula/compile/compiled-formula.js +41 -8
  13. package/dist/browser/modules/formula/functions/_shared.d.ts +19 -0
  14. package/dist/browser/modules/formula/functions/_shared.js +47 -0
  15. package/dist/browser/modules/formula/functions/conditional.js +103 -22
  16. package/dist/browser/modules/formula/functions/date.js +105 -23
  17. package/dist/browser/modules/formula/functions/dynamic-array.js +173 -69
  18. package/dist/browser/modules/formula/functions/engineering.d.ts +2 -2
  19. package/dist/browser/modules/formula/functions/engineering.js +103 -151
  20. package/dist/browser/modules/formula/functions/financial.js +210 -184
  21. package/dist/browser/modules/formula/functions/lookup.js +224 -157
  22. package/dist/browser/modules/formula/functions/math.d.ts +26 -0
  23. package/dist/browser/modules/formula/functions/math.js +249 -69
  24. package/dist/browser/modules/formula/functions/statistical.js +221 -171
  25. package/dist/browser/modules/formula/functions/text.js +112 -52
  26. package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +20 -1
  27. package/dist/browser/modules/formula/materialize/build-writeback-plan.js +10 -6
  28. package/dist/browser/modules/formula/materialize/types.d.ts +15 -0
  29. package/dist/browser/modules/formula/runtime/evaluator.d.ts +8 -0
  30. package/dist/browser/modules/formula/runtime/evaluator.js +582 -162
  31. package/dist/browser/modules/formula/runtime/function-registry.d.ts +5 -0
  32. package/dist/browser/modules/formula/runtime/function-registry.js +59 -13
  33. package/dist/browser/modules/formula/runtime/values.d.ts +13 -0
  34. package/dist/browser/modules/formula/runtime/values.js +20 -2
  35. package/dist/browser/modules/formula/syntax/ast.d.ts +14 -2
  36. package/dist/browser/modules/formula/syntax/ast.js +1 -0
  37. package/dist/browser/modules/formula/syntax/parser.js +29 -7
  38. package/dist/browser/modules/formula/syntax/token-types.d.ts +4 -0
  39. package/dist/browser/modules/formula/syntax/token-types.js +9 -0
  40. package/dist/browser/modules/formula/syntax/tokenizer.js +76 -19
  41. package/dist/cjs/index.js +7 -2
  42. package/dist/cjs/modules/excel/cell.js +21 -0
  43. package/dist/cjs/modules/excel/utils/cell-format.js +85 -13
  44. package/dist/cjs/modules/excel/workbook.browser.js +49 -0
  45. package/dist/cjs/modules/excel/xlsx/defaultnumformats.js +3 -3
  46. package/dist/cjs/modules/formula/compile/binder.js +48 -6
  47. package/dist/cjs/modules/formula/compile/compiled-formula.js +41 -8
  48. package/dist/cjs/modules/formula/functions/_shared.js +48 -0
  49. package/dist/cjs/modules/formula/functions/conditional.js +103 -22
  50. package/dist/cjs/modules/formula/functions/date.js +104 -22
  51. package/dist/cjs/modules/formula/functions/dynamic-array.js +173 -69
  52. package/dist/cjs/modules/formula/functions/engineering.js +109 -157
  53. package/dist/cjs/modules/formula/functions/financial.js +209 -183
  54. package/dist/cjs/modules/formula/functions/lookup.js +224 -157
  55. package/dist/cjs/modules/formula/functions/math.js +254 -70
  56. package/dist/cjs/modules/formula/functions/statistical.js +222 -172
  57. package/dist/cjs/modules/formula/functions/text.js +112 -52
  58. package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +20 -1
  59. package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +10 -6
  60. package/dist/cjs/modules/formula/runtime/evaluator.js +581 -161
  61. package/dist/cjs/modules/formula/runtime/function-registry.js +57 -11
  62. package/dist/cjs/modules/formula/runtime/values.js +21 -2
  63. package/dist/cjs/modules/formula/syntax/parser.js +29 -7
  64. package/dist/cjs/modules/formula/syntax/token-types.js +9 -0
  65. package/dist/cjs/modules/formula/syntax/tokenizer.js +76 -19
  66. package/dist/esm/index.js +2 -0
  67. package/dist/esm/modules/excel/cell.js +21 -0
  68. package/dist/esm/modules/excel/utils/cell-format.js +85 -13
  69. package/dist/esm/modules/excel/workbook.browser.js +49 -0
  70. package/dist/esm/modules/excel/xlsx/defaultnumformats.js +3 -3
  71. package/dist/esm/modules/formula/compile/binder.js +48 -6
  72. package/dist/esm/modules/formula/compile/bound-ast.js +1 -0
  73. package/dist/esm/modules/formula/compile/compiled-formula.js +41 -8
  74. package/dist/esm/modules/formula/functions/_shared.js +47 -0
  75. package/dist/esm/modules/formula/functions/conditional.js +103 -22
  76. package/dist/esm/modules/formula/functions/date.js +105 -23
  77. package/dist/esm/modules/formula/functions/dynamic-array.js +173 -69
  78. package/dist/esm/modules/formula/functions/engineering.js +103 -151
  79. package/dist/esm/modules/formula/functions/financial.js +210 -184
  80. package/dist/esm/modules/formula/functions/lookup.js +224 -157
  81. package/dist/esm/modules/formula/functions/math.js +249 -69
  82. package/dist/esm/modules/formula/functions/statistical.js +221 -171
  83. package/dist/esm/modules/formula/functions/text.js +112 -52
  84. package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +20 -1
  85. package/dist/esm/modules/formula/materialize/build-writeback-plan.js +10 -6
  86. package/dist/esm/modules/formula/runtime/evaluator.js +582 -162
  87. package/dist/esm/modules/formula/runtime/function-registry.js +59 -13
  88. package/dist/esm/modules/formula/runtime/values.js +20 -2
  89. package/dist/esm/modules/formula/syntax/ast.js +1 -0
  90. package/dist/esm/modules/formula/syntax/parser.js +29 -7
  91. package/dist/esm/modules/formula/syntax/token-types.js +9 -0
  92. package/dist/esm/modules/formula/syntax/tokenizer.js +76 -19
  93. package/dist/iife/excelts.iife.js +1502 -1379
  94. package/dist/iife/excelts.iife.js.map +1 -1
  95. package/dist/iife/excelts.iife.min.js +26 -26
  96. package/dist/types/index.d.ts +1 -0
  97. package/dist/types/modules/excel/cell.d.ts +18 -0
  98. package/dist/types/modules/excel/workbook.browser.d.ts +57 -0
  99. package/dist/types/modules/formula/compile/bound-ast.d.ts +16 -2
  100. package/dist/types/modules/formula/functions/_shared.d.ts +19 -0
  101. package/dist/types/modules/formula/functions/engineering.d.ts +2 -2
  102. package/dist/types/modules/formula/functions/math.d.ts +26 -0
  103. package/dist/types/modules/formula/materialize/types.d.ts +15 -0
  104. package/dist/types/modules/formula/runtime/evaluator.d.ts +8 -0
  105. package/dist/types/modules/formula/runtime/function-registry.d.ts +5 -0
  106. package/dist/types/modules/formula/runtime/values.d.ts +13 -0
  107. package/dist/types/modules/formula/syntax/ast.d.ts +14 -2
  108. package/dist/types/modules/formula/syntax/token-types.d.ts +4 -0
  109. package/package.json +1 -1
@@ -6,147 +6,92 @@ import { checkError } from "./_shared.js";
6
6
  // ============================================================================
7
7
  // Base Conversion Functions
8
8
  // ============================================================================
9
- export const fnBIN2DEC = args => {
10
- const err = checkError(args[0]);
11
- if (err) {
12
- return err;
13
- }
14
- const s = toStringRV(args[0]);
15
- if (!/^[01]{1,10}$/.test(s)) {
16
- return ERRORS.NUM;
17
- }
18
- // 10-bit two's complement
19
- if (s.length === 10 && s[0] === "1") {
20
- return rvNumber(parseInt(s.slice(1), 2) - 512);
21
- }
22
- return rvNumber(parseInt(s, 2));
23
- };
24
- export const fnDEC2BIN = args => {
25
- const nRV = toNumberRV(args[0]);
9
+ export const fnBIN2DEC = args => baseToDec(args, 2, /^[01]{1,10}$/);
10
+ export const fnDEC2BIN = args => decToBase(args, 2, -512, 511);
11
+ export const fnDEC2HEX = args => decToBase(args, 16, -549755813888, 549755813887);
12
+ export const fnDEC2OCT = args => decToBase(args, 8, -536870912, 536870911);
13
+ /**
14
+ * Shared implementation of `DEC2BIN`, `DEC2HEX`, `DEC2OCT`.
15
+ *
16
+ * Excel's three numeric-to-base converters differ only in the target
17
+ * base, the signed range they accept, and whether the output is
18
+ * uppercased (hex). The `places` semantics (1..10, validated only when
19
+ * supplied and the input is non-negative) are identical across all three.
20
+ *
21
+ * Factored here so the three converters share a single source of truth —
22
+ * when the Excel rules are refined (e.g. additional validations or a new
23
+ * `places` upper bound), all three stay in lockstep.
24
+ */
25
+ function decToBase(args, base, minValue, maxValue) {
26
+ const nRV = toNumberRV(topLeft(args[0]));
26
27
  if (isError(nRV)) {
27
28
  return nRV;
28
29
  }
29
30
  // Excel's DEC→BASE family truncates toward zero, so negative fractions
30
31
  // become `0`, not `-1` as `Math.floor` would produce.
31
32
  const n = Math.trunc(nRV.value);
32
- if (n < -512 || n > 511) {
33
+ if (n < minValue || n > maxValue) {
33
34
  return ERRORS.NUM;
34
35
  }
35
36
  // `places` is only meaningful when supplied and the input is non-negative.
36
- // Excel restricts it to the [1, 10] range and returns #NUM! otherwise.
37
- // For negative inputs Excel ignores `places` entirely, so we validate it
38
- // only on the non-negative branch below.
37
+ // Excel restricts it to [1, 10] and returns #NUM! outside that range.
38
+ // Negative inputs ignore `places` entirely we validate it only when
39
+ // we've confirmed the input is non-negative.
39
40
  const hasPlaces = args.length > 1 && args[1].kind !== RVKind.Blank;
40
- const placesRV = hasPlaces ? toNumberRV(args[1]) : rvNumber(0);
41
+ const placesRV = hasPlaces ? toNumberRV(topLeft(args[1])) : rvNumber(0);
41
42
  if (isError(placesRV)) {
42
43
  return placesRV;
43
44
  }
44
45
  const places = Math.trunc(placesRV.value);
46
+ const toUpper = base === 16;
45
47
  if (n < 0) {
46
- return rvString((n + 1024).toString(2));
48
+ const raw = (n + Math.pow(base, 10)).toString(base);
49
+ return rvString(toUpper ? raw.toUpperCase() : raw);
47
50
  }
48
51
  if (hasPlaces && (places < 1 || places > 10)) {
49
52
  return ERRORS.NUM;
50
53
  }
51
- const result = n.toString(2);
52
- return rvString(places > 0 ? result.padStart(places, "0") : result);
53
- };
54
- export const fnHEX2DEC = args => {
55
- const err = checkError(args[0]);
56
- if (err) {
57
- return err;
58
- }
59
- const s = toStringRV(args[0]);
60
- if (!/^[0-9A-Fa-f]{1,10}$/.test(s)) {
61
- return ERRORS.NUM;
62
- }
63
- const num = parseInt(s, 16);
64
- // 10-digit hex: 40-bit two's complement
65
- if (s.length === 10 && parseInt(s[0], 16) >= 8) {
66
- return rvNumber(num - Math.pow(16, 10));
67
- }
68
- return rvNumber(num);
69
- };
70
- export const fnDEC2HEX = args => {
71
- const nRV = toNumberRV(args[0]);
72
- if (isError(nRV)) {
73
- return nRV;
74
- }
75
- // Excel's DEC→BASE family truncates toward zero, so negative fractions
76
- // become `0`, not `-1` as `Math.floor` would produce.
77
- const n = Math.trunc(nRV.value);
78
- // Excel rejects anything outside the 40-bit signed range.
79
- // Without this check, inputs like 1e14 produce a 13-digit hex string
80
- // and inputs below -2^39 wrap into spurious positive values prefixed
81
- // with `-`. See R6-P0-1.
82
- if (n < -549755813888 || n > 549755813887) {
54
+ const raw = n.toString(base);
55
+ const result = toUpper ? raw.toUpperCase() : raw;
56
+ // When `places` is supplied but smaller than the natural representation,
57
+ // Excel returns `#NUM!` rather than silently ignoring the width. `padStart`
58
+ // alone would leave the wider result unchanged — a soft deviation.
59
+ if (hasPlaces && places > 0 && result.length > places) {
83
60
  return ERRORS.NUM;
84
61
  }
85
- // Same places semantics as DEC2BIN: validate only when `places` is
86
- // supplied and the input is non-negative; Excel ignores `places` for
87
- // negative numbers.
88
- const hasPlaces = args.length > 1 && args[1].kind !== RVKind.Blank;
89
- const placesRV = hasPlaces ? toNumberRV(args[1]) : rvNumber(0);
90
- if (isError(placesRV)) {
91
- return placesRV;
92
- }
93
- const places = Math.trunc(placesRV.value);
94
- if (n < 0) {
95
- return rvString((n + Math.pow(16, 10)).toString(16).toUpperCase());
96
- }
97
- if (hasPlaces && (places < 1 || places > 10)) {
98
- return ERRORS.NUM;
99
- }
100
- const result = n.toString(16).toUpperCase();
101
62
  return rvString(places > 0 ? result.padStart(places, "0") : result);
102
- };
103
- export const fnOCT2DEC = args => {
63
+ }
64
+ export const fnHEX2DEC = args => baseToDec(args, 16, /^[0-9A-Fa-f]{1,10}$/);
65
+ export const fnOCT2DEC = args => baseToDec(args, 8, /^[0-7]{1,10}$/);
66
+ /**
67
+ * Shared implementation of `BIN2DEC`, `OCT2DEC`, `HEX2DEC`.
68
+ *
69
+ * Each source base has the same "string of up to 10 digits, 10th digit
70
+ * sets the sign bit for two's-complement" semantics. The only
71
+ * differences are the allowed digit alphabet (passed as `pattern`) and
72
+ * the base (passed as `base`). The `isNegativeMsd` helper detects the
73
+ * sign bit by re-parsing the top digit; it works for binary (MSD=1),
74
+ * octal (MSD>=4) and hex (MSD>=8).
75
+ */
76
+ function baseToDec(args, base, pattern) {
104
77
  const err = checkError(args[0]);
105
78
  if (err) {
106
79
  return err;
107
80
  }
108
- const s = toStringRV(args[0]);
109
- if (!/^[0-7]{1,10}$/.test(s)) {
81
+ const s = toStringRV(topLeft(args[0]));
82
+ if (!pattern.test(s)) {
110
83
  return ERRORS.NUM;
111
84
  }
112
- const num = parseInt(s, 8);
113
- if (s.length === 10 && parseInt(s[0]) >= 4) {
114
- return rvNumber(num - Math.pow(8, 10));
85
+ const num = parseInt(s, base);
86
+ // 10-digit form triggers two's-complement interpretation. The sign bit
87
+ // is the top bit of the top digit — for binary that's the literal MSD,
88
+ // for octal it's `>= 4`, for hex it's `>= 8`. We compute the threshold
89
+ // from the base instead of hard-coding it.
90
+ if (s.length === 10 && parseInt(s[0], base) >= base / 2) {
91
+ return rvNumber(num - Math.pow(base, 10));
115
92
  }
116
93
  return rvNumber(num);
117
- };
118
- export const fnDEC2OCT = args => {
119
- const nRV = toNumberRV(args[0]);
120
- if (isError(nRV)) {
121
- return nRV;
122
- }
123
- // Excel's DEC→BASE family truncates toward zero, so negative fractions
124
- // become `0`, not `-1` as `Math.floor` would produce.
125
- const n = Math.trunc(nRV.value);
126
- // Excel's DEC2OCT range is the 30-bit signed range (-2^29 .. 2^29-1).
127
- // Values outside this range are #NUM! in Excel; we silently wrapped
128
- // into bogus sign-prefixed strings without this guard. See R6-P0-1.
129
- if (n < -536870912 || n > 536870911) {
130
- return ERRORS.NUM;
131
- }
132
- // Same places semantics as DEC2BIN: validate only when `places` is
133
- // supplied and the input is non-negative; Excel ignores `places` for
134
- // negative numbers.
135
- const hasPlaces = args.length > 1 && args[1].kind !== RVKind.Blank;
136
- const placesRV = hasPlaces ? toNumberRV(args[1]) : rvNumber(0);
137
- if (isError(placesRV)) {
138
- return placesRV;
139
- }
140
- const places = Math.trunc(placesRV.value);
141
- if (n < 0) {
142
- return rvString((n + Math.pow(8, 10)).toString(8));
143
- }
144
- if (hasPlaces && (places < 1 || places > 10)) {
145
- return ERRORS.NUM;
146
- }
147
- const result = n.toString(8);
148
- return rvString(places > 0 ? result.padStart(places, "0") : result);
149
- };
94
+ }
150
95
  /**
151
96
  * Generic helper for the X2Y conversion family (BIN2HEX, HEX2BIN, …).
152
97
  *
@@ -162,13 +107,13 @@ function convertBase(args, parseNInput, format) {
162
107
  if (err) {
163
108
  return err;
164
109
  }
165
- const s = toStringRV(args[0]);
110
+ const s = toStringRV(topLeft(args[0]));
166
111
  const n = parseNInput(s);
167
112
  if (typeof n !== "number") {
168
113
  return n;
169
114
  }
170
115
  const hasPlaces = args.length > 1 && args[1].kind !== RVKind.Blank;
171
- const placesRV = hasPlaces ? toNumberRV(args[1]) : rvNumber(0);
116
+ const placesRV = hasPlaces ? toNumberRV(topLeft(args[1])) : rvNumber(0);
172
117
  if (isError(placesRV)) {
173
118
  return placesRV;
174
119
  }
@@ -207,6 +152,11 @@ function formatToBase(n, base, maxDigits, places, hasPlaces) {
207
152
  return ERRORS.NUM;
208
153
  }
209
154
  const result = n.toString(base).toUpperCase();
155
+ // `places` smaller than the natural representation is a #NUM! in Excel —
156
+ // `padStart` alone would silently emit the wider form.
157
+ if (hasPlaces && places > 0 && result.length > places) {
158
+ return ERRORS.NUM;
159
+ }
210
160
  return rvString(places > 0 ? result.padStart(places, "0") : result);
211
161
  }
212
162
  export const fnBIN2HEX = args => convertBase(args, parseBinInput, (n, places, hasPlaces) => formatToBase(n, 16, 10, places, hasPlaces));
@@ -462,11 +412,11 @@ function besselK(n, x) {
462
412
  }
463
413
  /** Common validation + dispatch for the four BESSEL* functions. */
464
414
  function bessel(args, compute, allowZeroX) {
465
- const xRV = toNumberRV(args[0]);
415
+ const xRV = toNumberRV(topLeft(args[0]));
466
416
  if (isError(xRV)) {
467
417
  return xRV;
468
418
  }
469
- const nRV = toNumberRV(args[1]);
419
+ const nRV = toNumberRV(topLeft(args[1]));
470
420
  if (isError(nRV)) {
471
421
  return nRV;
472
422
  }
@@ -491,22 +441,22 @@ export const fnBESSELI = args => bessel(args, besselI, true);
491
441
  export const fnBESSELK = args => bessel(args, besselK, false);
492
442
  export const fnBESSELY = args => bessel(args, besselY, false);
493
443
  export const fnDELTA = args => {
494
- const n1 = toNumberRV(args[0]);
444
+ const n1 = toNumberRV(topLeft(args[0]));
495
445
  if (isError(n1)) {
496
446
  return n1;
497
447
  }
498
- const n2 = args.length > 1 ? toNumberRV(args[1]) : rvNumber(0);
448
+ const n2 = args.length > 1 ? toNumberRV(topLeft(args[1])) : rvNumber(0);
499
449
  if (isError(n2)) {
500
450
  return n2;
501
451
  }
502
452
  return rvNumber(n1.value === n2.value ? 1 : 0);
503
453
  };
504
454
  export const fnGESTEP = args => {
505
- const n = toNumberRV(args[0]);
455
+ const n = toNumberRV(topLeft(args[0]));
506
456
  if (isError(n)) {
507
457
  return n;
508
458
  }
509
- const step = args.length > 1 ? toNumberRV(args[1]) : rvNumber(0);
459
+ const step = args.length > 1 ? toNumberRV(topLeft(args[1])) : rvNumber(0);
510
460
  if (isError(step)) {
511
461
  return step;
512
462
  }
@@ -588,22 +538,24 @@ function formatComplex(re, im, suffix = "i") {
588
538
  return re + imStr;
589
539
  }
590
540
  export const fnCOMPLEX = args => {
591
- const re = toNumberRV(args[0]);
541
+ const re = toNumberRV(topLeft(args[0]));
592
542
  if (isError(re)) {
593
543
  return re;
594
544
  }
595
- const im = toNumberRV(args[1]);
545
+ const im = toNumberRV(topLeft(args[1]));
596
546
  if (isError(im)) {
597
547
  return im;
598
548
  }
599
549
  let suffix = "i";
600
- if (args.length > 2) {
550
+ if (args.length > 2 && args[2].kind !== RVKind.Blank) {
601
551
  const e2 = checkError(args[2]);
602
552
  if (e2) {
603
553
  return e2;
604
554
  }
605
- suffix = toStringRV(args[2]);
555
+ suffix = toStringRV(topLeft(args[2]));
606
556
  }
557
+ // Blank 3rd arg → default "i". Previously a blank coerced to empty
558
+ // string then tripped the `suffix !== "i"` validation.
607
559
  if (suffix !== "i" && suffix !== "j") {
608
560
  return ERRORS.VALUE;
609
561
  }
@@ -614,7 +566,7 @@ export const fnIMREAL = args => {
614
566
  if (err) {
615
567
  return err;
616
568
  }
617
- const c = parseComplex(toStringRV(args[0]));
569
+ const c = parseComplex(toStringRV(topLeft(args[0])));
618
570
  return c ? rvNumber(c[0]) : ERRORS.NUM;
619
571
  };
620
572
  export const fnIMAGINARY = args => {
@@ -622,7 +574,7 @@ export const fnIMAGINARY = args => {
622
574
  if (err) {
623
575
  return err;
624
576
  }
625
- const c = parseComplex(toStringRV(args[0]));
577
+ const c = parseComplex(toStringRV(topLeft(args[0])));
626
578
  return c ? rvNumber(c[1]) : ERRORS.NUM;
627
579
  };
628
580
  export const fnIMABS = args => {
@@ -630,7 +582,7 @@ export const fnIMABS = args => {
630
582
  if (err) {
631
583
  return err;
632
584
  }
633
- const c = parseComplex(toStringRV(args[0]));
585
+ const c = parseComplex(toStringRV(topLeft(args[0])));
634
586
  if (!c) {
635
587
  return ERRORS.NUM;
636
588
  }
@@ -641,7 +593,7 @@ export const fnIMARGUMENT = args => {
641
593
  if (err) {
642
594
  return err;
643
595
  }
644
- const c = parseComplex(toStringRV(args[0]));
596
+ const c = parseComplex(toStringRV(topLeft(args[0])));
645
597
  if (!c) {
646
598
  return ERRORS.NUM;
647
599
  }
@@ -655,7 +607,7 @@ export const fnIMCONJUGATE = args => {
655
607
  if (err) {
656
608
  return err;
657
609
  }
658
- const c = parseComplex(toStringRV(args[0]));
610
+ const c = parseComplex(toStringRV(topLeft(args[0])));
659
611
  if (!c) {
660
612
  return ERRORS.NUM;
661
613
  }
@@ -735,8 +687,8 @@ export const fnIMSUB = args => {
735
687
  if (e1) {
736
688
  return e1;
737
689
  }
738
- const c1 = parseComplex(toStringRV(args[0]));
739
- const c2 = parseComplex(toStringRV(args[1]));
690
+ const c1 = parseComplex(toStringRV(topLeft(args[0])));
691
+ const c2 = parseComplex(toStringRV(topLeft(args[1])));
740
692
  if (!c1 || !c2) {
741
693
  return ERRORS.NUM;
742
694
  }
@@ -771,8 +723,8 @@ export const fnIMDIV = args => {
771
723
  if (e1) {
772
724
  return e1;
773
725
  }
774
- const c1 = parseComplex(toStringRV(args[0]));
775
- const c2 = parseComplex(toStringRV(args[1]));
726
+ const c1 = parseComplex(toStringRV(topLeft(args[0])));
727
+ const c2 = parseComplex(toStringRV(topLeft(args[1])));
776
728
  if (!c1 || !c2) {
777
729
  return ERRORS.NUM;
778
730
  }
@@ -792,11 +744,11 @@ export const fnIMPOWER = args => {
792
744
  if (err) {
793
745
  return err;
794
746
  }
795
- const c = parseComplex(toStringRV(args[0]));
747
+ const c = parseComplex(toStringRV(topLeft(args[0])));
796
748
  if (!c) {
797
749
  return ERRORS.NUM;
798
750
  }
799
- const n = toNumberRV(args[1]);
751
+ const n = toNumberRV(topLeft(args[1]));
800
752
  if (isError(n)) {
801
753
  return n;
802
754
  }
@@ -810,7 +762,7 @@ export const fnIMSQRT = args => {
810
762
  if (err) {
811
763
  return err;
812
764
  }
813
- const c = parseComplex(toStringRV(args[0]));
765
+ const c = parseComplex(toStringRV(topLeft(args[0])));
814
766
  if (!c) {
815
767
  return ERRORS.NUM;
816
768
  }
@@ -824,7 +776,7 @@ export const fnIMLN = args => {
824
776
  if (err) {
825
777
  return err;
826
778
  }
827
- const c = parseComplex(toStringRV(args[0]));
779
+ const c = parseComplex(toStringRV(topLeft(args[0])));
828
780
  if (!c) {
829
781
  return ERRORS.NUM;
830
782
  }
@@ -839,7 +791,7 @@ export const fnIMLOG2 = args => {
839
791
  if (err) {
840
792
  return err;
841
793
  }
842
- const c = parseComplex(toStringRV(args[0]));
794
+ const c = parseComplex(toStringRV(topLeft(args[0])));
843
795
  if (!c) {
844
796
  return ERRORS.NUM;
845
797
  }
@@ -855,7 +807,7 @@ export const fnIMLOG10 = args => {
855
807
  if (err) {
856
808
  return err;
857
809
  }
858
- const c = parseComplex(toStringRV(args[0]));
810
+ const c = parseComplex(toStringRV(topLeft(args[0])));
859
811
  if (!c) {
860
812
  return ERRORS.NUM;
861
813
  }
@@ -871,7 +823,7 @@ export const fnIMEXP = args => {
871
823
  if (err) {
872
824
  return err;
873
825
  }
874
- const c = parseComplex(toStringRV(args[0]));
826
+ const c = parseComplex(toStringRV(topLeft(args[0])));
875
827
  if (!c) {
876
828
  return ERRORS.NUM;
877
829
  }
@@ -883,7 +835,7 @@ export const fnIMSIN = args => {
883
835
  if (err) {
884
836
  return err;
885
837
  }
886
- const c = parseComplex(toStringRV(args[0]));
838
+ const c = parseComplex(toStringRV(topLeft(args[0])));
887
839
  if (!c) {
888
840
  return ERRORS.NUM;
889
841
  }
@@ -894,7 +846,7 @@ export const fnIMCOS = args => {
894
846
  if (err) {
895
847
  return err;
896
848
  }
897
- const c = parseComplex(toStringRV(args[0]));
849
+ const c = parseComplex(toStringRV(topLeft(args[0])));
898
850
  if (!c) {
899
851
  return ERRORS.NUM;
900
852
  }
@@ -1024,11 +976,11 @@ function validateBitOperand(v) {
1024
976
  return v;
1025
977
  }
1026
978
  export const fnBITAND = args => {
1027
- const a = toNumberRV(args[0]);
979
+ const a = toNumberRV(topLeft(args[0]));
1028
980
  if (isError(a)) {
1029
981
  return a;
1030
982
  }
1031
- const b = toNumberRV(args[1]);
983
+ const b = toNumberRV(topLeft(args[1]));
1032
984
  if (isError(b)) {
1033
985
  return b;
1034
986
  }
@@ -1043,11 +995,11 @@ export const fnBITAND = args => {
1043
995
  return rvNumber(bitAnd48(av, bv));
1044
996
  };
1045
997
  export const fnBITOR = args => {
1046
- const a = toNumberRV(args[0]);
998
+ const a = toNumberRV(topLeft(args[0]));
1047
999
  if (isError(a)) {
1048
1000
  return a;
1049
1001
  }
1050
- const b = toNumberRV(args[1]);
1002
+ const b = toNumberRV(topLeft(args[1]));
1051
1003
  if (isError(b)) {
1052
1004
  return b;
1053
1005
  }
@@ -1062,11 +1014,11 @@ export const fnBITOR = args => {
1062
1014
  return rvNumber(bitOr48(av, bv));
1063
1015
  };
1064
1016
  export const fnBITXOR = args => {
1065
- const a = toNumberRV(args[0]);
1017
+ const a = toNumberRV(topLeft(args[0]));
1066
1018
  if (isError(a)) {
1067
1019
  return a;
1068
1020
  }
1069
- const b = toNumberRV(args[1]);
1021
+ const b = toNumberRV(topLeft(args[1]));
1070
1022
  if (isError(b)) {
1071
1023
  return b;
1072
1024
  }
@@ -1081,11 +1033,11 @@ export const fnBITXOR = args => {
1081
1033
  return rvNumber(bitXor48(av, bv));
1082
1034
  };
1083
1035
  export const fnBITLSHIFT = args => {
1084
- const num = toNumberRV(args[0]);
1036
+ const num = toNumberRV(topLeft(args[0]));
1085
1037
  if (isError(num)) {
1086
1038
  return num;
1087
1039
  }
1088
- const shift = toNumberRV(args[1]);
1040
+ const shift = toNumberRV(topLeft(args[1]));
1089
1041
  if (isError(shift)) {
1090
1042
  return shift;
1091
1043
  }
@@ -1104,11 +1056,11 @@ export const fnBITLSHIFT = args => {
1104
1056
  return rvNumber(result);
1105
1057
  };
1106
1058
  export const fnBITRSHIFT = args => {
1107
- const num = toNumberRV(args[0]);
1059
+ const num = toNumberRV(topLeft(args[0]));
1108
1060
  if (isError(num)) {
1109
1061
  return num;
1110
1062
  }
1111
- const shift = toNumberRV(args[1]);
1063
+ const shift = toNumberRV(topLeft(args[1]));
1112
1064
  if (isError(shift)) {
1113
1065
  return shift;
1114
1066
  }