@devmm/puredocs-excel-formula 1.0.9 → 1.1.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.
- package/dist/index.cjs +70 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +70 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -275,7 +275,7 @@ declare namespace FormulaHelper {
|
|
|
275
275
|
* Everything else — comparisons, wildcards — only gets the compiled `test`.
|
|
276
276
|
*/
|
|
277
277
|
interface CompiledCriteria {
|
|
278
|
-
readonly kind: 'equalsNumber' | 'equalsText' | 'compareNumber' | 'other';
|
|
278
|
+
readonly kind: 'equalsNumber' | 'equalsText' | 'compareNumber' | 'blankness' | 'other';
|
|
279
279
|
/** For `equalsNumber` and `compareNumber`: the number compared against. */
|
|
280
280
|
readonly number?: number;
|
|
281
281
|
/** For `equalsText`: the criterion, upper-cased (matching is case-insensitive). */
|
package/dist/index.d.ts
CHANGED
|
@@ -275,7 +275,7 @@ declare namespace FormulaHelper {
|
|
|
275
275
|
* Everything else — comparisons, wildcards — only gets the compiled `test`.
|
|
276
276
|
*/
|
|
277
277
|
interface CompiledCriteria {
|
|
278
|
-
readonly kind: 'equalsNumber' | 'equalsText' | 'compareNumber' | 'other';
|
|
278
|
+
readonly kind: 'equalsNumber' | 'equalsText' | 'compareNumber' | 'blankness' | 'other';
|
|
279
279
|
/** For `equalsNumber` and `compareNumber`: the number compared against. */
|
|
280
280
|
readonly number?: number;
|
|
281
281
|
/** For `equalsText`: the criterion, upper-cased (matching is case-insensitive). */
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,13 @@ var FormulaError = /* @__PURE__ */ ((FormulaError2) => {
|
|
|
29
29
|
FormulaError2[FormulaError2["Spill"] = 9] = "Spill";
|
|
30
30
|
return FormulaError2;
|
|
31
31
|
})(FormulaError || {});
|
|
32
|
+
var DECIMAL = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
33
|
+
function numericText(text) {
|
|
34
|
+
const trimmed = text.trim();
|
|
35
|
+
if (!DECIMAL.test(trimmed)) return null;
|
|
36
|
+
const n = Number(trimmed);
|
|
37
|
+
return Number.isFinite(n) ? n : null;
|
|
38
|
+
}
|
|
32
39
|
var TailCall = class {
|
|
33
40
|
constructor(lambda, args) {
|
|
34
41
|
this.lambda = lambda;
|
|
@@ -273,7 +280,7 @@ var _FormulaValue = class _FormulaValue {
|
|
|
273
280
|
if (value2 === null || value2 === void 0) return _FormulaValue.blank;
|
|
274
281
|
if (typeof value2 === "number") return isNaN(value2) ? _FormulaValue.errorValue : _FormulaValue.number(value2);
|
|
275
282
|
if (typeof value2 === "boolean") return _FormulaValue.boolean(value2);
|
|
276
|
-
if (typeof value2 === "string") return
|
|
283
|
+
if (typeof value2 === "string") return _FormulaValue.text(value2);
|
|
277
284
|
if (value2 instanceof Date) {
|
|
278
285
|
return _FormulaValue.number(toOADate(value2));
|
|
279
286
|
}
|
|
@@ -1441,6 +1448,7 @@ var indexes = /* @__PURE__ */ new WeakMap();
|
|
|
1441
1448
|
function build(arr) {
|
|
1442
1449
|
const byText = /* @__PURE__ */ new Map();
|
|
1443
1450
|
const byNumber = /* @__PURE__ */ new Map();
|
|
1451
|
+
const byTextNumber = /* @__PURE__ */ new Map();
|
|
1444
1452
|
const classes = /* @__PURE__ */ new Map();
|
|
1445
1453
|
const addToClass = (kind, v, i2) => {
|
|
1446
1454
|
const group = classes.get(kind);
|
|
@@ -1460,6 +1468,14 @@ function build(arr) {
|
|
|
1460
1468
|
else byNumber.set(n, [i]);
|
|
1461
1469
|
} else {
|
|
1462
1470
|
addToClass(v.kind, v, i);
|
|
1471
|
+
if (v.isText) {
|
|
1472
|
+
const n = numericText(v.textValue);
|
|
1473
|
+
if (n !== null) {
|
|
1474
|
+
const atText2 = byTextNumber.get(n);
|
|
1475
|
+
if (atText2) atText2.push(i);
|
|
1476
|
+
else byTextNumber.set(n, [i]);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1463
1479
|
}
|
|
1464
1480
|
i++;
|
|
1465
1481
|
}
|
|
@@ -1468,7 +1484,15 @@ function build(arr) {
|
|
|
1468
1484
|
for (let k = 0; k < sortedNumbers.length; k++) {
|
|
1469
1485
|
cumulative[k + 1] = cumulative[k] + byNumber.get(sortedNumbers[k]).length;
|
|
1470
1486
|
}
|
|
1471
|
-
return {
|
|
1487
|
+
return {
|
|
1488
|
+
byText,
|
|
1489
|
+
byNumber,
|
|
1490
|
+
sortedNumbers,
|
|
1491
|
+
cumulative,
|
|
1492
|
+
byTextNumber,
|
|
1493
|
+
sortedTextNumbers: Float64Array.from(byTextNumber.keys()).sort(),
|
|
1494
|
+
classes: [...classes.values()]
|
|
1495
|
+
};
|
|
1472
1496
|
}
|
|
1473
1497
|
function indexOf(arr) {
|
|
1474
1498
|
let idx = indexes.get(arr);
|
|
@@ -1506,19 +1530,25 @@ function matchingPositions(criteriaRange, criteria, minSize) {
|
|
|
1506
1530
|
if (criteria.kind === "equalsNumber") {
|
|
1507
1531
|
const target = criteria.number;
|
|
1508
1532
|
const idx = indexOf(arr);
|
|
1509
|
-
const
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1533
|
+
const groups = [];
|
|
1534
|
+
const collect = (byValue, sorted) => {
|
|
1535
|
+
const exact2 = byValue.get(target);
|
|
1536
|
+
if (exact2) groups.push(exact2);
|
|
1537
|
+
for (let k = lowerBound(sorted, target - EPSILON); k < sorted.length; k++) {
|
|
1538
|
+
const value2 = sorted[k];
|
|
1539
|
+
if (value2 > target + EPSILON) break;
|
|
1540
|
+
if (value2 === target) continue;
|
|
1541
|
+
if (!criteria.test(FormulaValue.number(value2))) continue;
|
|
1542
|
+
groups.push(byValue.get(value2));
|
|
1543
|
+
}
|
|
1544
|
+
};
|
|
1545
|
+
collect(idx.byNumber, idx.sortedNumbers);
|
|
1546
|
+
collect(idx.byTextNumber, idx.sortedTextNumbers);
|
|
1519
1547
|
const blanks = criteria.test(FormulaValue.blank) ? blankPositions(idx) : void 0;
|
|
1520
|
-
if (
|
|
1521
|
-
|
|
1548
|
+
if (blanks?.length) groups.push(blanks);
|
|
1549
|
+
if (groups.length === 0) return EMPTY;
|
|
1550
|
+
if (groups.length === 1) return groups[0];
|
|
1551
|
+
const merged = groups.flat();
|
|
1522
1552
|
merged.sort((a, b) => a - b);
|
|
1523
1553
|
return merged;
|
|
1524
1554
|
}
|
|
@@ -1788,11 +1818,14 @@ function count(a, c) {
|
|
|
1788
1818
|
function countA(a, c) {
|
|
1789
1819
|
return FormulaValue.number(FormulaHelper.flattenArgs(a, c).filter((v) => !v.isBlank).length);
|
|
1790
1820
|
}
|
|
1821
|
+
function isCountBlank(v) {
|
|
1822
|
+
return v.isBlank || v.isText && v.textValue === "";
|
|
1823
|
+
}
|
|
1791
1824
|
function countBlank(a, c) {
|
|
1792
1825
|
const v = a[0].evaluate(c);
|
|
1793
|
-
if (!v.isArray) return FormulaValue.number(v
|
|
1826
|
+
if (!v.isArray) return FormulaValue.number(isCountBlank(v) ? 1 : 0);
|
|
1794
1827
|
let n = 0;
|
|
1795
|
-
for (const item of v.arrayVal.values()) if (item
|
|
1828
|
+
for (const item of v.arrayVal.values()) if (isCountBlank(item)) n++;
|
|
1796
1829
|
return FormulaValue.number(n);
|
|
1797
1830
|
}
|
|
1798
1831
|
function countIf(a, c) {
|
|
@@ -1800,11 +1833,12 @@ function countIf(a, c) {
|
|
|
1800
1833
|
if (range.isError) return range;
|
|
1801
1834
|
const crit = a[1].evaluate(c);
|
|
1802
1835
|
if (crit.isError) return crit;
|
|
1803
|
-
const
|
|
1804
|
-
if (!range.isArray) return FormulaValue.number(
|
|
1836
|
+
const compiled = FormulaHelper.compileCriteria(crit.asText());
|
|
1837
|
+
if (!range.isArray) return FormulaValue.number(compiled.test(range) ? 1 : 0);
|
|
1838
|
+
const countBlanks = compiled.kind === "blankness";
|
|
1805
1839
|
let n = 0;
|
|
1806
1840
|
for (const item of range.arrayVal.values()) {
|
|
1807
|
-
if (!item.isBlank &&
|
|
1841
|
+
if ((countBlanks || !item.isBlank) && compiled.test(item)) n++;
|
|
1808
1842
|
}
|
|
1809
1843
|
return FormulaValue.number(n);
|
|
1810
1844
|
}
|
|
@@ -4696,11 +4730,14 @@ var FormulaHelper;
|
|
|
4696
4730
|
const rhsVal = parseFloat(rhs);
|
|
4697
4731
|
const rhsNum = isNaN(rhsVal) ? null : rhsVal;
|
|
4698
4732
|
const rhsValue = rhsNum !== null ? FormulaValue.number(rhsNum) : FormulaValue.text(rhs);
|
|
4733
|
+
if (rhs === "" && op === "=") return { kind: "blankness", test: (v) => v.isBlank };
|
|
4734
|
+
if (rhs === "" && op === "<>") return { kind: "other", test: (v) => !v.isBlank };
|
|
4699
4735
|
if (op === "=") {
|
|
4700
4736
|
return rhsNum !== null ? numberEquality(rhsNum) : textEquality(rhs);
|
|
4701
4737
|
}
|
|
4702
4738
|
if (op === "<>") {
|
|
4703
|
-
|
|
4739
|
+
const equals = rhsNum !== null ? numberEquality(rhsNum) : textEquality(rhs);
|
|
4740
|
+
return { kind: "other", test: (v) => !equals.test(v) };
|
|
4704
4741
|
}
|
|
4705
4742
|
const wanted = op === ">" ? (c) => c > 0 : op === ">=" ? (c) => c >= 0 : op === "<" ? (c) => c < 0 : (c) => c <= 0;
|
|
4706
4743
|
const test = (v) => wanted(FormulaValue.compare(v, rhsValue));
|
|
@@ -4710,13 +4747,25 @@ var FormulaHelper;
|
|
|
4710
4747
|
const pattern = wildcardToRegex(trimmed);
|
|
4711
4748
|
return { kind: "other", test: (v) => pattern.test(v.asText()) };
|
|
4712
4749
|
}
|
|
4750
|
+
if (trimmed === "") {
|
|
4751
|
+
return { kind: "blankness", test: (v) => v.isBlank || v.isText && v.textValue === "" };
|
|
4752
|
+
}
|
|
4713
4753
|
const num5 = parseFloat(trimmed);
|
|
4714
4754
|
return isNaN(num5) ? textEquality(trimmed) : numberEquality(num5);
|
|
4715
4755
|
}
|
|
4716
4756
|
FormulaHelper2.compileCriteria = compileCriteria;
|
|
4717
4757
|
function numberEquality(n) {
|
|
4718
4758
|
const target = FormulaValue.number(n);
|
|
4719
|
-
return {
|
|
4759
|
+
return {
|
|
4760
|
+
kind: "equalsNumber",
|
|
4761
|
+
number: n,
|
|
4762
|
+
test: (v) => {
|
|
4763
|
+
if (FormulaValue.areEqual(v, target)) return true;
|
|
4764
|
+
if (!v.isText) return false;
|
|
4765
|
+
const asNumber = numericText(v.textValue);
|
|
4766
|
+
return asNumber !== null && Math.abs(asNumber - n) < 1e-10;
|
|
4767
|
+
}
|
|
4768
|
+
};
|
|
4720
4769
|
}
|
|
4721
4770
|
function textEquality(s) {
|
|
4722
4771
|
const upper2 = s.toUpperCase();
|