@danielsimonjr/mathts-expression 0.11.1 → 0.12.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/evaluator/evaluate.d.ts +10 -1
- package/dist/evaluator/evaluate.d.ts.map +1 -1
- package/dist/index.js +184 -69
- package/dist/node/AccessorNode.d.ts +128 -122
- package/dist/node/AccessorNode.d.ts.map +1 -1
- package/dist/node/ArrayNode.d.ts +130 -122
- package/dist/node/ArrayNode.d.ts.map +1 -1
- package/dist/node/BlockNode.d.ts +8 -2
- package/dist/node/BlockNode.d.ts.map +1 -1
- package/dist/node/ConditionalNode.d.ts +134 -126
- package/dist/node/ConditionalNode.d.ts.map +1 -1
- package/dist/node/FunctionAssignmentNode.d.ts +76 -70
- package/dist/node/FunctionAssignmentNode.d.ts.map +1 -1
- package/dist/node/FunctionNode.d.ts.map +1 -1
- package/dist/node/IndexNode.d.ts +146 -136
- package/dist/node/IndexNode.d.ts.map +1 -1
- package/dist/node/ObjectNode.d.ts +130 -122
- package/dist/node/ObjectNode.d.ts.map +1 -1
- package/dist/node/RangeNode.d.ts +76 -70
- package/dist/node/RangeNode.d.ts.map +1 -1
- package/dist/node/utils/access.d.ts.map +1 -1
- package/dist/node/utils/assign.d.ts.map +1 -1
- package/dist/node/utils/describeType.d.ts +3 -0
- package/dist/node/utils/describeType.d.ts.map +1 -0
- package/dist/parse.d.ts.map +1 -1
- package/dist/scalar-builder.d.ts +2 -0
- package/dist/scalar-builder.d.ts.map +1 -1
- package/dist/scalar-structure.d.ts +6 -1
- package/dist/scalar-structure.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -35,7 +35,16 @@ export interface EvaluateOptions {
|
|
|
35
35
|
* evaluate('x^2', { x: 3 }); // 9
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
|
-
export declare function createEvaluate(parseFn: (expr: string) => MathNode, mathScope: Record<string, unknown
|
|
38
|
+
export declare function createEvaluate(parseFn: (expr: string) => MathNode, mathScope: Record<string, unknown>,
|
|
39
|
+
/**
|
|
40
|
+
* Optional fingerprint of the state `parseFn` depends on besides the text
|
|
41
|
+
* (for example the live `number` / `precision` config, which decides the
|
|
42
|
+
* numeric type of literals at parse time). Called on every evaluate; its
|
|
43
|
+
* value becomes part of the cache key, so a parse made under one config is
|
|
44
|
+
* never reused under another. Omit when `parseFn` is a pure function of its
|
|
45
|
+
* input.
|
|
46
|
+
*/
|
|
47
|
+
cacheKey?: () => string): {
|
|
39
48
|
(expr: string, scope?: Record<string, unknown> | Scope, options?: EvaluateOptions): unknown;
|
|
40
49
|
(exprs: string[], scope?: Record<string, unknown> | Scope, options?: EvaluateOptions): unknown[];
|
|
41
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/evaluator/evaluate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAmJD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,EACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;AAClC;;;;;;;GAOG;AACH,QAAQ,CAAC,EAAE,MAAM,MAAM;WAWf,MAAM,UACJ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,YAC7B,eAAe,GACxB,OAAO;YAUD,MAAM,EAAE,UACP,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,YAC7B,eAAe,GACxB,OAAO,EAAE;EA2Cb;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,EACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,eAAe,GACxB,kBAAkB,CAMpB"}
|
package/dist/index.js
CHANGED
|
@@ -470,7 +470,7 @@ const MAX_EXPRESSION_LENGTH = 1e6;
|
|
|
470
470
|
//#endregion
|
|
471
471
|
//#region src/parse.ts
|
|
472
472
|
const name$45 = "parse";
|
|
473
|
-
const
|
|
473
|
+
const dependencies$45 = [
|
|
474
474
|
"typed",
|
|
475
475
|
"numeric",
|
|
476
476
|
"config",
|
|
@@ -489,7 +489,47 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
489
489
|
"RangeNode",
|
|
490
490
|
"RelationalNode",
|
|
491
491
|
"SymbolNode"
|
|
492
|
-
]
|
|
492
|
+
];
|
|
493
|
+
const RELATIONAL_OPERATORS = Object.freeze({
|
|
494
|
+
"==": "equal",
|
|
495
|
+
"!=": "unequal",
|
|
496
|
+
"<": "smaller",
|
|
497
|
+
">": "larger",
|
|
498
|
+
"<=": "smallerEq",
|
|
499
|
+
">=": "largerEq"
|
|
500
|
+
});
|
|
501
|
+
const SHIFT_OPERATORS = Object.freeze({
|
|
502
|
+
"<<": "leftShift",
|
|
503
|
+
">>": "rightArithShift",
|
|
504
|
+
">>>": "rightLogShift"
|
|
505
|
+
});
|
|
506
|
+
const CONVERSION_OPERATORS = Object.freeze({
|
|
507
|
+
to: "to",
|
|
508
|
+
in: "to"
|
|
509
|
+
});
|
|
510
|
+
const ADD_SUBTRACT_OPERATORS = Object.freeze({
|
|
511
|
+
"+": "add",
|
|
512
|
+
"-": "subtract"
|
|
513
|
+
});
|
|
514
|
+
const MULTIPLY_DIVIDE_OPERATORS = Object.freeze({
|
|
515
|
+
"*": "multiply",
|
|
516
|
+
".*": "dotMultiply",
|
|
517
|
+
"/": "divide",
|
|
518
|
+
"./": "dotDivide",
|
|
519
|
+
"%": "mod",
|
|
520
|
+
mod: "mod"
|
|
521
|
+
});
|
|
522
|
+
const UNARY_OPERATORS = Object.freeze({
|
|
523
|
+
"-": "unaryMinus",
|
|
524
|
+
"+": "unaryPlus",
|
|
525
|
+
"~": "bitNot",
|
|
526
|
+
not: "not"
|
|
527
|
+
});
|
|
528
|
+
const POSTFIX_OPERATORS = Object.freeze({
|
|
529
|
+
"!": "factorial",
|
|
530
|
+
"'": "ctranspose"
|
|
531
|
+
});
|
|
532
|
+
const createParse = /* #__PURE__ */ factory(name$45, dependencies$45, ({ typed, numeric, config, AccessorNode, ArrayNode, AssignmentNode, BlockNode, ConditionalNode, ConstantNode, FunctionAssignmentNode, FunctionNode, IndexNode, ObjectNode, OperatorNode, ParenthesisNode, RangeNode, RelationalNode, SymbolNode }) => {
|
|
493
533
|
const parse = typed(name$45, {
|
|
494
534
|
string: function(expression) {
|
|
495
535
|
if (expression.length > 1e6) throw new SyntaxError(`expression exceeds ${MAX_EXPRESSION_LENGTH} characters`);
|
|
@@ -931,18 +971,10 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
931
971
|
function parseRelational(state) {
|
|
932
972
|
const params = [parseShift(state)];
|
|
933
973
|
const conditionals = [];
|
|
934
|
-
|
|
935
|
-
"==": "equal",
|
|
936
|
-
"!=": "unequal",
|
|
937
|
-
"<": "smaller",
|
|
938
|
-
">": "larger",
|
|
939
|
-
"<=": "smallerEq",
|
|
940
|
-
">=": "largerEq"
|
|
941
|
-
};
|
|
942
|
-
while (hasOwnProperty(operators, state.token)) {
|
|
974
|
+
while (hasOwnProperty(RELATIONAL_OPERATORS, state.token)) {
|
|
943
975
|
const cond = {
|
|
944
976
|
name: state.token,
|
|
945
|
-
fn:
|
|
977
|
+
fn: RELATIONAL_OPERATORS[state.token]
|
|
946
978
|
};
|
|
947
979
|
conditionals.push(cond);
|
|
948
980
|
getTokenSkipNewline(state);
|
|
@@ -958,14 +990,9 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
958
990
|
let fn;
|
|
959
991
|
let params;
|
|
960
992
|
node = parseConversion(state);
|
|
961
|
-
|
|
962
|
-
"<<": "leftShift",
|
|
963
|
-
">>": "rightArithShift",
|
|
964
|
-
">>>": "rightLogShift"
|
|
965
|
-
};
|
|
966
|
-
while (hasOwnProperty(operators, state.token)) {
|
|
993
|
+
while (hasOwnProperty(SHIFT_OPERATORS, state.token)) {
|
|
967
994
|
name = state.token;
|
|
968
|
-
fn =
|
|
995
|
+
fn = SHIFT_OPERATORS[name];
|
|
969
996
|
getTokenSkipNewline(state);
|
|
970
997
|
params = [node, parseConversion(state)];
|
|
971
998
|
node = new OperatorNode(name, fn, params);
|
|
@@ -978,13 +1005,9 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
978
1005
|
let fn;
|
|
979
1006
|
let params;
|
|
980
1007
|
node = parseRange(state);
|
|
981
|
-
|
|
982
|
-
to: "to",
|
|
983
|
-
in: "to"
|
|
984
|
-
};
|
|
985
|
-
while (hasOwnProperty(operators, state.token)) {
|
|
1008
|
+
while (hasOwnProperty(CONVERSION_OPERATORS, state.token)) {
|
|
986
1009
|
name = state.token;
|
|
987
|
-
fn =
|
|
1010
|
+
fn = CONVERSION_OPERATORS[name];
|
|
988
1011
|
getTokenSkipNewline(state);
|
|
989
1012
|
if (name === "in" && "])},;".includes(state.token)) node = new OperatorNode("*", "multiply", [node, new SymbolNode("in")], true);
|
|
990
1013
|
else {
|
|
@@ -1019,13 +1042,9 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
1019
1042
|
let fn;
|
|
1020
1043
|
let params;
|
|
1021
1044
|
node = parseMultiplyDivideModulus(state);
|
|
1022
|
-
|
|
1023
|
-
"+": "add",
|
|
1024
|
-
"-": "subtract"
|
|
1025
|
-
};
|
|
1026
|
-
while (hasOwnProperty(operators, state.token)) {
|
|
1045
|
+
while (hasOwnProperty(ADD_SUBTRACT_OPERATORS, state.token)) {
|
|
1027
1046
|
name = state.token;
|
|
1028
|
-
fn =
|
|
1047
|
+
fn = ADD_SUBTRACT_OPERATORS[name];
|
|
1029
1048
|
getTokenSkipNewline(state);
|
|
1030
1049
|
const rightNode = parseMultiplyDivideModulus(state);
|
|
1031
1050
|
if (rightNode.isPercentage) params = [node, new OperatorNode("*", "multiply", [node, rightNode])];
|
|
@@ -1040,17 +1059,9 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
1040
1059
|
let name;
|
|
1041
1060
|
let fn;
|
|
1042
1061
|
node = parseImplicitMultiplication(state);
|
|
1043
|
-
|
|
1044
|
-
"*": "multiply",
|
|
1045
|
-
".*": "dotMultiply",
|
|
1046
|
-
"/": "divide",
|
|
1047
|
-
"./": "dotDivide",
|
|
1048
|
-
"%": "mod",
|
|
1049
|
-
mod: "mod"
|
|
1050
|
-
};
|
|
1051
|
-
while (true) if (hasOwnProperty(operators, state.token)) {
|
|
1062
|
+
while (true) if (hasOwnProperty(MULTIPLY_DIVIDE_OPERATORS, state.token)) {
|
|
1052
1063
|
name = state.token;
|
|
1053
|
-
fn =
|
|
1064
|
+
fn = MULTIPLY_DIVIDE_OPERATORS[name];
|
|
1054
1065
|
getTokenSkipNewline(state);
|
|
1055
1066
|
last = parseImplicitMultiplication(state);
|
|
1056
1067
|
node = new OperatorNode(name, fn, [node, last]);
|
|
@@ -1121,14 +1132,8 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
1121
1132
|
let name;
|
|
1122
1133
|
let params;
|
|
1123
1134
|
let fn;
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
"+": "unaryPlus",
|
|
1127
|
-
"~": "bitNot",
|
|
1128
|
-
not: "not"
|
|
1129
|
-
};
|
|
1130
|
-
if (hasOwnProperty(operators, state.token)) {
|
|
1131
|
-
fn = operators[state.token];
|
|
1135
|
+
if (hasOwnProperty(UNARY_OPERATORS, state.token)) {
|
|
1136
|
+
fn = UNARY_OPERATORS[state.token];
|
|
1132
1137
|
name = state.token;
|
|
1133
1138
|
getTokenSkipNewline(state);
|
|
1134
1139
|
params = [parseUnary(state)];
|
|
@@ -1165,13 +1170,9 @@ const createParse = /* #__PURE__ */ factory(name$45, [
|
|
|
1165
1170
|
let fn;
|
|
1166
1171
|
let params;
|
|
1167
1172
|
node = parseCustomNodes(state);
|
|
1168
|
-
|
|
1169
|
-
"!": "factorial",
|
|
1170
|
-
"'": "ctranspose"
|
|
1171
|
-
};
|
|
1172
|
-
while (hasOwnProperty(operators, state.token)) {
|
|
1173
|
+
while (hasOwnProperty(POSTFIX_OPERATORS, state.token)) {
|
|
1173
1174
|
name = state.token;
|
|
1174
|
-
fn =
|
|
1175
|
+
fn = POSTFIX_OPERATORS[name];
|
|
1175
1176
|
getToken(state);
|
|
1176
1177
|
params = [node];
|
|
1177
1178
|
node = new OperatorNode(name, fn, params);
|
|
@@ -7564,15 +7565,45 @@ function validateAst(node, depth = 0) {
|
|
|
7564
7565
|
for (const k of Object.keys(properties)) validateAst(properties[k], depth + 1);
|
|
7565
7566
|
}
|
|
7566
7567
|
}
|
|
7567
|
-
|
|
7568
|
+
const COMPILE_CACHE_SIZE = 256;
|
|
7569
|
+
const compileCaches = /* @__PURE__ */ new WeakMap();
|
|
7570
|
+
function cacheFor(mathScope, parseFn) {
|
|
7571
|
+
let byParser = compileCaches.get(mathScope);
|
|
7572
|
+
if (!byParser) {
|
|
7573
|
+
byParser = /* @__PURE__ */ new WeakMap();
|
|
7574
|
+
compileCaches.set(mathScope, byParser);
|
|
7575
|
+
}
|
|
7576
|
+
let cache = byParser.get(parseFn);
|
|
7577
|
+
if (!cache) {
|
|
7578
|
+
cache = /* @__PURE__ */ new Map();
|
|
7579
|
+
byParser.set(parseFn, cache);
|
|
7580
|
+
}
|
|
7581
|
+
return cache;
|
|
7582
|
+
}
|
|
7583
|
+
function createEvaluate(parseFn, mathScope, cacheKey) {
|
|
7568
7584
|
function evaluate(exprOrExprs, scope, options) {
|
|
7569
7585
|
if (Array.isArray(exprOrExprs)) return exprOrExprs.map((expr) => evaluateOne(expr, scope, options));
|
|
7570
7586
|
return evaluateOne(exprOrExprs, scope, options);
|
|
7571
7587
|
}
|
|
7588
|
+
const cache = cacheFor(mathScope, parseFn);
|
|
7572
7589
|
function evaluateOne(expr, scope, options) {
|
|
7573
|
-
const
|
|
7574
|
-
|
|
7575
|
-
|
|
7590
|
+
const unsafe = options?.unsafe === true;
|
|
7591
|
+
const key = (unsafe ? "u:" : "s:") + (cacheKey ? cacheKey() + "\0" : "") + expr;
|
|
7592
|
+
let compiled = cache.get(key);
|
|
7593
|
+
if (compiled !== void 0) {
|
|
7594
|
+
cache.delete(key);
|
|
7595
|
+
cache.set(key, compiled);
|
|
7596
|
+
} else {
|
|
7597
|
+
const node = parseFn(expr);
|
|
7598
|
+
if (!unsafe) validateAst(node);
|
|
7599
|
+
compiled = compile(node, mathScope);
|
|
7600
|
+
cache.set(key, compiled);
|
|
7601
|
+
if (cache.size > COMPILE_CACHE_SIZE) {
|
|
7602
|
+
const oldest = cache.keys().next().value;
|
|
7603
|
+
if (oldest !== void 0) cache.delete(oldest);
|
|
7604
|
+
}
|
|
7605
|
+
}
|
|
7606
|
+
return compiled.evaluate(scope);
|
|
7576
7607
|
}
|
|
7577
7608
|
return evaluate;
|
|
7578
7609
|
}
|
|
@@ -7878,6 +7909,17 @@ function errorTransform(err) {
|
|
|
7878
7909
|
return err;
|
|
7879
7910
|
}
|
|
7880
7911
|
//#endregion
|
|
7912
|
+
//#region src/node/utils/describeType.ts
|
|
7913
|
+
function describeType(value) {
|
|
7914
|
+
if (value === null) return "null";
|
|
7915
|
+
if (Array.isArray(value)) return "array";
|
|
7916
|
+
if (typeof value === "object") {
|
|
7917
|
+
const name = value.constructor?.name;
|
|
7918
|
+
return typeof name === "string" && name !== "" ? name : "object";
|
|
7919
|
+
}
|
|
7920
|
+
return typeof value;
|
|
7921
|
+
}
|
|
7922
|
+
//#endregion
|
|
7881
7923
|
//#region src/node/utils/stringSubset.ts
|
|
7882
7924
|
function getStringSubset(str, index, invalidIndexMessage = "Index expected") {
|
|
7883
7925
|
if (!isIndex(index)) throw new TypeError(invalidIndexMessage);
|
|
@@ -7931,9 +7973,9 @@ function accessFactory({ subset }) {
|
|
|
7931
7973
|
else if (object && typeof object.subset === "function") return object.subset(index);
|
|
7932
7974
|
else if (typeof object === "string") return getStringSubset(object, index);
|
|
7933
7975
|
else if (typeof object === "object") {
|
|
7934
|
-
if (!index.isObjectProperty()) throw new TypeError(
|
|
7976
|
+
if (!index.isObjectProperty()) throw new TypeError(`Cannot apply a numeric index as object property (object is ${describeType(object)})`);
|
|
7935
7977
|
return getSafeProperty(object, index.getObjectProperty());
|
|
7936
|
-
} else throw new TypeError(
|
|
7978
|
+
} else throw new TypeError(`Cannot apply index: unsupported type of object (got ${describeType(object)})`);
|
|
7937
7979
|
} catch (err) {
|
|
7938
7980
|
throw errorTransform(err);
|
|
7939
7981
|
}
|
|
@@ -8025,6 +8067,12 @@ const createAccessorNode = /* #__PURE__ */ factory(name$40, ["subset", "Node"],
|
|
|
8025
8067
|
if (needParenthesis(this.object)) object = "\\left(' + object + '\\right)";
|
|
8026
8068
|
return object + this.index.toTex(options);
|
|
8027
8069
|
}
|
|
8070
|
+
_toMathML() {
|
|
8071
|
+
let object = this.object.toMathML();
|
|
8072
|
+
if (needParenthesis(this.object)) object = `<mrow><mo>(</mo>${object}<mo>)</mo></mrow>`;
|
|
8073
|
+
if (this.index.dotNotation) return `<mrow>${object}${this.index.toMathML()}</mrow>`;
|
|
8074
|
+
return `<msub><mrow>${object}</mrow>${this.index.toMathML()}</msub>`;
|
|
8075
|
+
}
|
|
8028
8076
|
toJSON() {
|
|
8029
8077
|
return {
|
|
8030
8078
|
mathjs: name$40,
|
|
@@ -8109,6 +8157,26 @@ const createArrayNode = /* #__PURE__ */ factory(name$39, ["Node"], ({ Node }) =>
|
|
|
8109
8157
|
return node.toHTML(options);
|
|
8110
8158
|
}).join("<span class=\"math-separator\">,</span>") + "<span class=\"math-parenthesis math-square-parenthesis\">]</span>";
|
|
8111
8159
|
}
|
|
8160
|
+
_toMathML() {
|
|
8161
|
+
const tableOf = (rows) => "<mrow><mo>[</mo><mtable>" + rows.map((row) => "<mtr>" + row.map((cell) => `<mtd>${cell}</mtd>`).join("") + "</mtr>").join("") + "</mtable><mo>]</mo></mrow>";
|
|
8162
|
+
const build = (items, nested) => {
|
|
8163
|
+
const mixedItems = items.some(isArrayNode) && !items.every(isArrayNode);
|
|
8164
|
+
const itemsFormRow = nested || mixedItems;
|
|
8165
|
+
const pieces = items.map((node) => {
|
|
8166
|
+
const arrayItems = node.items;
|
|
8167
|
+
if (arrayItems) {
|
|
8168
|
+
const sub = build(arrayItems, !nested);
|
|
8169
|
+
return sub.wrapped ? [tableOf(sub.rows)] : sub.rows[0];
|
|
8170
|
+
}
|
|
8171
|
+
return [node.toMathML()];
|
|
8172
|
+
});
|
|
8173
|
+
return {
|
|
8174
|
+
wrapped: mixedItems || !itemsFormRow || itemsFormRow && !nested,
|
|
8175
|
+
rows: itemsFormRow ? [pieces.flat()] : pieces
|
|
8176
|
+
};
|
|
8177
|
+
};
|
|
8178
|
+
return tableOf(build(this.items, false).rows);
|
|
8179
|
+
}
|
|
8112
8180
|
_toTex(options) {
|
|
8113
8181
|
function itemsToTex(items, nested) {
|
|
8114
8182
|
const mixedItems = items.some(isArrayNode) && !items.every(isArrayNode);
|
|
@@ -8142,10 +8210,10 @@ function assignFactory({ subset }) {
|
|
|
8142
8210
|
} else if (object && typeof object.subset === "function") return object.subset(index, value);
|
|
8143
8211
|
else if (typeof object === "string") return setStringSubset(object, index, String(value));
|
|
8144
8212
|
else if (typeof object === "object") {
|
|
8145
|
-
if (!index.isObjectProperty()) throw TypeError(
|
|
8213
|
+
if (!index.isObjectProperty()) throw TypeError(`Cannot apply a numeric index as object property (object is ${describeType(object)})`);
|
|
8146
8214
|
setSafeProperty(object, index.getObjectProperty(), value);
|
|
8147
8215
|
return object;
|
|
8148
|
-
} else throw new TypeError(
|
|
8216
|
+
} else throw new TypeError(`Cannot apply index: unsupported type of object (got ${describeType(object)})`);
|
|
8149
8217
|
} catch (err) {
|
|
8150
8218
|
throw errorTransform(err);
|
|
8151
8219
|
}
|
|
@@ -8392,6 +8460,9 @@ const createBlockNode = /* #__PURE__ */ factory(name$37, ["ResultSet", "Node"],
|
|
|
8392
8460
|
return param.node.toHTML(options) + (param.visible ? "" : "<span class=\"math-separator\">;</span>");
|
|
8393
8461
|
}).join("<span class=\"math-separator\"><br /></span>");
|
|
8394
8462
|
}
|
|
8463
|
+
_toMathML() {
|
|
8464
|
+
return `<mrow>${this.blocks.map((param) => param.node.toMathML() + (param.visible ? "" : "<mo>;</mo>")).join("<mspace width=\"1em\"/>")}</mrow>`;
|
|
8465
|
+
}
|
|
8395
8466
|
_toTex(options) {
|
|
8396
8467
|
return this.blocks.map(function(param) {
|
|
8397
8468
|
return param.node.toTex(options) + (param.visible ? "" : ";");
|
|
@@ -8486,6 +8557,9 @@ const createConditionalNode = /* #__PURE__ */ factory(name$36, ["Node"], ({ Node
|
|
|
8486
8557
|
const parenClose = "<span class=\"math-parenthesis math-round-parenthesis\">)</span>";
|
|
8487
8558
|
return formatConditionalBranches(this, options, (node) => node.toHTML(options), (inner) => parenOpen + inner + parenClose, (condition, trueExpr, falseExpr) => condition + "<span class=\"math-operator math-conditional-operator\">?</span>" + trueExpr + "<span class=\"math-operator math-conditional-operator\">:</span>" + falseExpr);
|
|
8488
8559
|
}
|
|
8560
|
+
_toMathML() {
|
|
8561
|
+
return `<mrow><mo>{</mo><mtable columnalign="left left"><mtr><mtd>${this.trueExpr.toMathML()}</mtd><mtd><mtext>if </mtext>${this.condition.toMathML()}</mtd></mtr><mtr><mtd>${this.falseExpr.toMathML()}</mtd><mtd><mtext>otherwise</mtext></mtd></mtr></mtable></mrow>`;
|
|
8562
|
+
}
|
|
8489
8563
|
_toTex(options) {
|
|
8490
8564
|
return "\\begin{cases} {" + this.trueExpr.toTex(options) + "}, &\\quad{\\text{if }\\;" + this.condition.toTex(options) + "}\\\\{" + this.falseExpr.toTex(options) + "}, &\\quad{\\text{otherwise}}\\end{cases}";
|
|
8491
8565
|
}
|
|
@@ -9011,6 +9085,12 @@ const createFunctionAssignmentNode = /* #__PURE__ */ factory(name$34, ["typed",
|
|
|
9011
9085
|
if (needParenthesis(this, parenthesis, options && options.implicit)) expr = "<span class=\"math-parenthesis math-round-parenthesis\">(</span>" + expr + "<span class=\"math-parenthesis math-round-parenthesis\">)</span>";
|
|
9012
9086
|
return "<span class=\"math-function\">" + escape(this.name) + "</span><span class=\"math-parenthesis math-round-parenthesis\">(</span>" + params.join("<span class=\"math-separator\">,</span>") + "<span class=\"math-parenthesis math-round-parenthesis\">)</span><span class=\"math-operator math-assignment-operator math-variable-assignment-operator math-binary-operator\">=</span>" + expr;
|
|
9013
9087
|
}
|
|
9088
|
+
_toMathML() {
|
|
9089
|
+
let expr = this.expr.toMathML();
|
|
9090
|
+
if (needParenthesis(this, "keep", void 0)) expr = `<mrow><mo>(</mo>${expr}<mo>)</mo></mrow>`;
|
|
9091
|
+
const params = this.params.map((p) => toMathMLSymbol(p)).join("<mo>,</mo>");
|
|
9092
|
+
return `<mrow>${toMathMLSymbol(this.name)}<mo>⁡</mo><mrow><mo>(</mo>${params}<mo>)</mo></mrow><mo>=</mo>${expr}</mrow>`;
|
|
9093
|
+
}
|
|
9014
9094
|
_toTex(options) {
|
|
9015
9095
|
const parenthesis = options && options.parenthesis ? options.parenthesis : "keep";
|
|
9016
9096
|
let expr = this.expr.toTex(options);
|
|
@@ -9031,11 +9111,18 @@ function createSubScope(parentScope, args) {
|
|
|
9031
9111
|
//#endregion
|
|
9032
9112
|
//#region src/node/FunctionNode.ts
|
|
9033
9113
|
const name$33 = "FunctionNode";
|
|
9034
|
-
const
|
|
9114
|
+
const dependencies$33 = [
|
|
9035
9115
|
"math",
|
|
9036
9116
|
"Node",
|
|
9037
9117
|
"SymbolNode"
|
|
9038
|
-
]
|
|
9118
|
+
];
|
|
9119
|
+
function isMissingMember(object, prop) {
|
|
9120
|
+
if (!(prop in Object(object))) return true;
|
|
9121
|
+
if (isSafeMethod(object, prop)) return false;
|
|
9122
|
+
if (isSafeProperty(object, prop)) return getSafeProperty(object, prop) === void 0;
|
|
9123
|
+
return false;
|
|
9124
|
+
}
|
|
9125
|
+
const createFunctionNode = /* #__PURE__ */ factory(name$33, dependencies$33, ({ math, Node, SymbolNode }) => {
|
|
9039
9126
|
const strin = (entity) => format(entity, { truncate: 78 });
|
|
9040
9127
|
function expandTemplate(template, node, options) {
|
|
9041
9128
|
let latex = "";
|
|
@@ -9171,7 +9258,7 @@ const createFunctionNode = /* #__PURE__ */ factory(name$33, [
|
|
|
9171
9258
|
const rawArgs = this.args;
|
|
9172
9259
|
return function evalFunctionNode(scope, args, context) {
|
|
9173
9260
|
const object = evalObject(scope, args, context);
|
|
9174
|
-
if (fromOptionalChaining && (object == null || object
|
|
9261
|
+
if (fromOptionalChaining && (object == null || isMissingMember(object, prop))) return;
|
|
9175
9262
|
const fn = getSafeMethod(object, prop);
|
|
9176
9263
|
if (fn?.rawArgs) return fn(rawArgs, math, createSubScope(scope, args));
|
|
9177
9264
|
else {
|
|
@@ -9296,6 +9383,15 @@ const createFunctionNode = /* #__PURE__ */ factory(name$33, [
|
|
|
9296
9383
|
});
|
|
9297
9384
|
//#endregion
|
|
9298
9385
|
//#region src/node/IndexNode.ts
|
|
9386
|
+
function coerceIndexValue(value) {
|
|
9387
|
+
if (isBigNumber(value)) {
|
|
9388
|
+
const big = value;
|
|
9389
|
+
const n = big.toNumber();
|
|
9390
|
+
if (!big.isInteger() || !Number.isSafeInteger(n)) throw new RangeError(`Index must be an integer within the safe range, got BigNumber ${big.toString()}`);
|
|
9391
|
+
return n;
|
|
9392
|
+
}
|
|
9393
|
+
return value;
|
|
9394
|
+
}
|
|
9299
9395
|
const name$32 = "IndexNode";
|
|
9300
9396
|
const createIndexNode = /* #__PURE__ */ factory(name$32, ["Node", "size"], ({ Node, size }) => {
|
|
9301
9397
|
class IndexNode extends Node {
|
|
@@ -9333,7 +9429,7 @@ const createIndexNode = /* #__PURE__ */ factory(name$32, ["Node", "size"], ({ No
|
|
|
9333
9429
|
const index = getSafeProperty(math, "index");
|
|
9334
9430
|
return function evalIndexNode(scope, args, context) {
|
|
9335
9431
|
const dimensions = map(evalDimensions, function(evalDimension) {
|
|
9336
|
-
return evalDimension(scope, args, context);
|
|
9432
|
+
return coerceIndexValue(evalDimension(scope, args, context));
|
|
9337
9433
|
});
|
|
9338
9434
|
return index(...dimensions);
|
|
9339
9435
|
};
|
|
@@ -9374,6 +9470,10 @@ const createIndexNode = /* #__PURE__ */ factory(name$32, ["Node", "size"], ({ No
|
|
|
9374
9470
|
if (this.dotNotation) return "<span class=\"math-operator math-accessor-operator\">.</span><span class=\"math-symbol math-property\">" + escape(this.getObjectProperty()) + "</span>";
|
|
9375
9471
|
else return "<span class=\"math-parenthesis math-square-parenthesis\">[</span>" + dimensions.join("<span class=\"math-separator\">,</span>") + "<span class=\"math-parenthesis math-square-parenthesis\">]</span>";
|
|
9376
9472
|
}
|
|
9473
|
+
_toMathML() {
|
|
9474
|
+
if (this.dotNotation) return `<mo>.</mo>${toMathMLSymbol(String(this.getObjectProperty()))}`;
|
|
9475
|
+
return `<mrow>${this.dimensions.map((range) => range.toMathML()).join("<mo>,</mo>")}</mrow>`;
|
|
9476
|
+
}
|
|
9377
9477
|
_toTex(options) {
|
|
9378
9478
|
const dimensions = this.dimensions.map(function(range) {
|
|
9379
9479
|
return range.toTex(options);
|
|
@@ -9453,6 +9553,9 @@ const createObjectNode = /* #__PURE__ */ factory(name$31, ["Node"], ({ Node }) =
|
|
|
9453
9553
|
_toHTML(options) {
|
|
9454
9554
|
return renderObjectEntries(this.properties, (key, node) => "<span class=\"math-symbol math-property\">" + escape(key) + "</span><span class=\"math-operator math-assignment-operator math-property-assignment-operator math-binary-operator\">:</span>" + node.toHTML(options), "<span class=\"math-separator\">,</span>", (joined) => "<span class=\"math-parenthesis math-curly-parenthesis\">{</span>" + joined + "<span class=\"math-parenthesis math-curly-parenthesis\">}</span>");
|
|
9455
9555
|
}
|
|
9556
|
+
_toMathML() {
|
|
9557
|
+
return renderObjectEntries(this.properties, (key, node) => `<mtr><mtd><mtext>${escapeMathML(key)}:</mtext></mtd><mtd>${node.toMathML()}</mtd></mtr>`, "", (joined) => `<mrow><mo>{</mo><mtable columnalign="left left">${joined}</mtable><mo>}</mo></mrow>`);
|
|
9558
|
+
}
|
|
9456
9559
|
_toTex(options) {
|
|
9457
9560
|
return renderObjectEntries(this.properties, (key, node) => "\\mathbf{" + key + ":} & " + node.toTex(options) + "\\\\", "\n", (joined) => "\\left\\{\\begin{array}{ll}" + joined + "\\end{array}\\right\\}");
|
|
9458
9561
|
}
|
|
@@ -9974,6 +10077,14 @@ const createRangeNode = /* #__PURE__ */ factory(name$28, ["Node"], ({ Node }) =>
|
|
|
9974
10077
|
const parenClose = "<span class=\"math-parenthesis math-round-parenthesis\">)</span>";
|
|
9975
10078
|
return formatRangeDisplay(this, options, (child) => child.toHTML(options), (inner) => parenOpen + inner + parenClose, () => "<span class=\"math-operator math-range-operator\">:</span>");
|
|
9976
10079
|
}
|
|
10080
|
+
_toMathML() {
|
|
10081
|
+
const parens = calculateNecessaryParentheses(this, "keep", "hide");
|
|
10082
|
+
const wrap = (s, need) => need ? `<mrow><mo>(</mo>${s}<mo>)</mo></mrow>` : s;
|
|
10083
|
+
let str = wrap(this.start.toMathML(), parens.start);
|
|
10084
|
+
if (this.step) str += "<mo>:</mo>" + wrap(this.step.toMathML(), parens.step);
|
|
10085
|
+
str += "<mo>:</mo>" + wrap(this.end.toMathML(), parens.end);
|
|
10086
|
+
return `<mrow>${str}</mrow>`;
|
|
10087
|
+
}
|
|
9977
10088
|
_toTex(options) {
|
|
9978
10089
|
const parenthesis = options && options.parenthesis ? options.parenthesis : "keep";
|
|
9979
10090
|
const parens = calculateNecessaryParentheses(this, parenthesis, options && options.implicit || "hide");
|
|
@@ -10194,7 +10305,9 @@ const SCALAR_FUNCTION_LOWERING = {
|
|
|
10194
10305
|
sinh: "sinh",
|
|
10195
10306
|
cosh: "cosh",
|
|
10196
10307
|
tanh: "tanh",
|
|
10197
|
-
abs: "abs"
|
|
10308
|
+
abs: "abs",
|
|
10309
|
+
sqrt: "sqrt",
|
|
10310
|
+
atan: "atan"
|
|
10198
10311
|
};
|
|
10199
10312
|
const SCALAR_FUNCTIONS = [
|
|
10200
10313
|
"exp",
|
|
@@ -10208,7 +10321,9 @@ const SCALAR_FUNCTIONS = [
|
|
|
10208
10321
|
"sinh",
|
|
10209
10322
|
"cosh",
|
|
10210
10323
|
"tanh",
|
|
10211
|
-
"abs"
|
|
10324
|
+
"abs",
|
|
10325
|
+
"sqrt",
|
|
10326
|
+
"atan"
|
|
10212
10327
|
];
|
|
10213
10328
|
const LOWERED_FUNCTIONS$1 = new Set(Object.values(SCALAR_FUNCTION_LOWERING));
|
|
10214
10329
|
var ScalarBuildError = class extends Error {
|