Socket
Socket
Sign inDemoInstall

@oat-sa/expr-eval

Package Overview
Dependencies
Maintainers
18
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@oat-sa/expr-eval - npm Package Compare versions

Comparing version 1.3.2 to 2.0.0

CHANGELOG.md

559

dist/bundle.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.exprEval = factory());
}(this, (function () { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.exprEval = {}));
}(this, (function (exports) { 'use strict';

@@ -12,6 +12,11 @@ var INUMBER = 'INUMBER';

var IVAR = 'IVAR';
var IVARNAME = 'IVARNAME';
var IFUNCOP = 'IFUNCOP';
var IFUNCALL = 'IFUNCALL';
var IFUNDEF = 'IFUNDEF';
var IEXPR = 'IEXPR';
var IEXPREVAL = 'IEXPREVAL';
var IMEMBER = 'IMEMBER';
var IENDSTATEMENT = 'IENDSTATEMENT';
var IARRAY = 'IARRAY';

@@ -30,2 +35,4 @@ function Instruction(type, value) {

case IVAR:
case IVARNAME:
case IENDSTATEMENT:
case IFUNCOP:

@@ -35,2 +42,6 @@ return this.value;

return 'CALL ' + this.value;
case IFUNDEF:
return 'DEF ' + this.value;
case IARRAY:
return 'ARRAY ' + this.value;
case IMEMBER:

@@ -63,4 +74,10 @@ return '.' + this.value;

var type = item.type;
if (type === INUMBER) {
nstack.push(item);
if (type === INUMBER || type === IVARNAME) {
if (Array.isArray(item.value)) {
nstack.push.apply(nstack, simplify(item.value.map(function (x) {
return new Instruction(INUMBER, x);
}).concat(new Instruction(IARRAY, item.value.length)), unaryOps, binaryOps, ternaryOps, values));
} else {
nstack.push(item);
}
} else if (type === IVAR && values.hasOwnProperty(item.value)) {

@@ -99,3 +116,9 @@ item = new Instruction(INUMBER, values[item.value]);

nstack.push(new Instruction(INUMBER, n1.value[item.value]));
} else {
} /* else if (type === IARRAY && nstack.length >= item.value) {
var length = item.value;
while (length-- > 0) {
newexpression.push(nstack.pop());
}
newexpression.push(new Instruction(IARRAY, item.value));
} */ else {
while (nstack.length > 0) {

@@ -145,7 +168,14 @@ newexpression.push(nstack.shift());

var n1, n2, n3;
var f;
for (var i = 0; i < tokens.length; i++) {
var f, args, argCount;
if (isExpressionEvaluator(tokens)) {
return resolveExpression(tokens, values);
}
var numTokens = tokens.length;
for (var i = 0; i < numTokens; i++) {
var item = tokens[i];
var type = item.type;
if (type === INUMBER) {
if (type === INUMBER || type === IVARNAME) {
nstack.push(item.value);

@@ -159,5 +189,8 @@ } else if (type === IOP2) {

nstack.push(n1 ? true : !!evaluate(n2, expr, values));
} else if (item.value === '=') {
f = expr.binaryOps[item.value];
nstack.push(f(n1, evaluate(n2, expr, values), values));
} else {
f = expr.binaryOps[item.value];
nstack.push(f(n1, n2));
nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values)));
}

@@ -172,7 +205,12 @@ } else if (type === IOP3) {

f = expr.ternaryOps[item.value];
nstack.push(f(n1, n2, n3));
nstack.push(f(resolveExpression(n1, values), resolveExpression(n2, values), resolveExpression(n3, values)));
}
} else if (type === IVAR) {
if (/^__proto__|prototype|constructor$/.test(item.value)) {
throw new Error('prototype access detected');
}
if (item.value in expr.functions) {
nstack.push(expr.functions[item.value]);
} else if (item.value in expr.unaryOps && expr.parser.isOperatorEnabled(item.value)) {
nstack.push(expr.unaryOps[item.value]);
} else {

@@ -189,3 +227,3 @@ var v = values[item.value];

f = expr.unaryOps[item.value];
nstack.push(f(n1));
nstack.push(f(resolveExpression(n1, values)));
} else if (type === IFUNCOP) {

@@ -201,6 +239,6 @@ n2 = nstack.pop();

} else if (type === IFUNCALL) {
var argCount = item.value;
var args = [];
argCount = item.value;
args = [];
while (argCount-- > 0) {
args.unshift(nstack.pop());
args.unshift(resolveExpression(nstack.pop(), values));
}

@@ -213,7 +251,43 @@ f = nstack.pop();

}
} else if (type === IFUNDEF) {
// Create closure to keep references to arguments and expression
nstack.push((function () {
var n2 = nstack.pop();
var args = [];
var argCount = item.value;
while (argCount-- > 0) {
args.unshift(nstack.pop());
}
var n1 = nstack.pop();
var f = function () {
var scope = Object.assign({}, values);
for (var i = 0, len = args.length; i < len; i++) {
scope[args[i]] = arguments[i];
}
return evaluate(n2, expr, scope);
};
// f.name = n1
Object.defineProperty(f, 'name', {
value: n1,
writable: false
});
values[n1] = f;
return f;
})());
} else if (type === IEXPR) {
nstack.push(item.value);
nstack.push(createExpressionEvaluator(item, expr));
} else if (type === IEXPREVAL) {
nstack.push(item);
} else if (type === IMEMBER) {
n1 = nstack.pop();
nstack.push(n1[item.value]);
} else if (type === IENDSTATEMENT) {
nstack.pop();
} else if (type === IARRAY) {
argCount = item.value;
args = [];
while (argCount-- > 0) {
args.unshift(nstack.pop());
}
nstack.push(args);
} else {

@@ -226,9 +300,28 @@ throw new Error('invalid Expression');

}
return nstack[0] === -0 ? 0: nstack[0];
// Explicitly return zero to avoid test issues caused by -0
return nstack[0] === 0 ? 0 : resolveExpression(nstack[0], values);
}
function createExpressionEvaluator(token, expr, values) {
if (isExpressionEvaluator(token)) return token;
return {
type: IEXPREVAL,
value: function (scope) {
return evaluate(token.value, expr, scope);
}
};
}
function isExpressionEvaluator(n) {
return n && n.type === IEXPREVAL;
}
function resolveExpression(n, values) {
return isExpressionEvaluator(n) ? n.value(values) : n;
}
function expressionToString(tokens, toJS) {
var nstack = [];
var n1, n2, n3;
var f;
var f, args, argCount;
for (var i = 0; i < tokens.length; i++) {

@@ -240,2 +333,4 @@ var item = tokens[i];

nstack.push('(' + item.value + ')');
} else if (Array.isArray(item.value)) {
nstack.push('[' + item.value.map(escapeValue).join(', ') + ']');
} else {

@@ -256,3 +351,3 @@ nstack.push(escapeValue(item.value));

} else if (f === '||') {
nstack.push('(String(' + n1 + ') + String(' + n2 + '))');
nstack.push('(function(a,b){ return Array.isArray(a) && Array.isArray(b) ? a.concat(b) : String(a) + String(b); }((' + n1 + '),(' + n2 + ')))');
} else if (f === '==') {

@@ -262,2 +357,4 @@ nstack.push('(' + n1 + ' === ' + n2 + ')');

nstack.push('(' + n1 + ' !== ' + n2 + ')');
} else if (f === '[') {
nstack.push(n1 + '[(' + n2 + ') | 0]');
} else {

@@ -267,3 +364,7 @@ nstack.push('(' + n1 + ' ' + f + ' ' + n2 + ')');

} else {
nstack.push('(' + n1 + ' ' + f + ' ' + n2 + ')');
if (f === '[') {
nstack.push(n1 + '[' + n2 + ']');
} else {
nstack.push('(' + n1 + ' ' + f + ' ' + n2 + ')');
}
}

@@ -280,3 +381,3 @@ } else if (type === IOP3) {

}
} else if (type === IVAR) {
} else if (type === IVAR || type === IVARNAME) {
nstack.push(item.value);

@@ -302,4 +403,4 @@ } else if (type === IOP1) {

} else if (type === IFUNCALL) {
var argCount = item.value;
var args = [];
argCount = item.value;
args = [];
while (argCount-- > 0) {

@@ -310,8 +411,28 @@ args.unshift(nstack.pop());

nstack.push(f + '(' + args.join(', ') + ')');
} else if (type === IFUNDEF) {
n2 = nstack.pop();
argCount = item.value;
args = [];
while (argCount-- > 0) {
args.unshift(nstack.pop());
}
n1 = nstack.pop();
if (toJS) {
nstack.push('(' + n1 + ' = function(' + args.join(', ') + ') { return ' + n2 + ' })');
} else {
nstack.push('(' + n1 + '(' + args.join(', ') + ') = ' + n2 + ')');
}
} else if (type === IMEMBER) {
n1 = nstack.pop();
nstack.push(n1 + '.' + item.value);
} else if (type === IARRAY) {
argCount = item.value;
args = [];
while (argCount-- > 0) {
args.unshift(nstack.pop());
}
nstack.push('[' + args.join(', ') + ']');
} else if (type === IEXPR) {
nstack.push('(' + expressionToString(item.value, toJS) + ')');
} else {
} else if (type === IENDSTATEMENT) ; else {
throw new Error('invalid Expression');

@@ -321,3 +442,7 @@ }

if (nstack.length > 1) {
throw new Error('invalid Expression (parity)');
if (toJS) {
nstack = [ nstack.join(',') ];
} else {
nstack = [ nstack.join(';') ];
}
}

@@ -350,3 +475,3 @@ return String(nstack[0]);

var item = tokens[i];
if (item.type === IVAR) {
if (item.type === IVAR || item.type === IVARNAME) {
if (!withMembers && !contains(symbols, item.value)) {

@@ -441,4 +566,6 @@ symbols.push(item.value);

var TPAREN = 'TPAREN';
var TBRACKET = 'TBRACKET';
var TCOMMA = 'TCOMMA';
var TNAME = 'TNAME';
var TSEMICOLON = 'TSEMICOLON';

@@ -467,2 +594,3 @@ function Token(type, value, index) {

this.options = parser.options;
this.parser = parser;
}

@@ -496,3 +624,5 @@

this.isParen() ||
this.isBracket() ||
this.isComma() ||
this.isSemicolon() ||
this.isNamedOp() ||

@@ -539,2 +669,12 @@ this.isFuncOp() ||

TokenStream.prototype.isBracket = function () {
var c = this.expression.charAt(this.pos);
if ((c === '[' || c === ']') && this.isOperatorEnabled('[')) {
this.current = this.newToken(TBRACKET, c);
this.pos++;
return true;
}
return false;
};
TokenStream.prototype.isComma = function () {

@@ -550,2 +690,12 @@ var c = this.expression.charAt(this.pos);

TokenStream.prototype.isSemicolon = function () {
var c = this.expression.charAt(this.pos);
if (c === ';') {
this.current = this.newToken(TSEMICOLON, ';');
this.pos++;
return true;
}
return false;
};
TokenStream.prototype.isConst = function () {

@@ -870,3 +1020,3 @@ var startPos = this.pos;

} else {
return false;
this.current = this.newToken(TOP, c);
}

@@ -893,38 +1043,4 @@ } else if (c === '!') {

var optionNameMap = {
'+': 'add',
'-': 'subtract',
'*': 'multiply',
'/': 'divide',
'%': 'remainder',
'^': 'power',
'!': 'factorial',
'<': 'comparison',
'>': 'comparison',
'<=': 'comparison',
'>=': 'comparison',
'==': 'comparison',
'!=': 'comparison',
'||': 'concatenate',
'and': 'logical',
'or': 'logical',
'not': 'logical',
'?': 'conditional',
':': 'conditional'
};
function getOptionName(op) {
return optionNameMap.hasOwnProperty(op) ? optionNameMap[op] : op;
}
TokenStream.prototype.isOperatorEnabled = function (op) {
var optionName = getOptionName(op);
var operators = this.options.operators || {};
// in is a special case for now because it's disabled by default
if (optionName === 'in') {
return !!operators['in'];
}
return !(optionName in operators) || !!operators[optionName];
return this.parser.isOperatorEnabled(op);
};

@@ -1009,3 +1125,8 @@

ParserState.prototype.parseAtom = function (instr) {
if (this.accept(TNAME)) {
var unaryOps = this.tokens.unaryOps;
function isPrefixOperator(token) {
return token.value in unaryOps;
}
if (this.accept(TNAME) || this.accept(TOP, isPrefixOperator)) {
instr.push(new Instruction(IVAR, this.current.value));

@@ -1019,2 +1140,9 @@ } else if (this.accept(TNUMBER)) {

this.expect(TPAREN, ')');
} else if (this.accept(TBRACKET, '[')) {
if (this.accept(TBRACKET, ']')) {
instr.push(new Instruction(IARRAY, 0));
} else {
var argCount = this.parseArrayList(instr);
instr.push(new Instruction(IARRAY, argCount));
}
} else {

@@ -1026,3 +1154,75 @@ throw new Error('unexpected ' + this.nextToken);

ParserState.prototype.parseExpression = function (instr) {
var exprInstr = [];
if (this.parseUntilEndStatement(instr, exprInstr)) {
return;
}
this.parseVariableAssignmentExpression(exprInstr);
if (this.parseUntilEndStatement(instr, exprInstr)) {
return;
}
this.pushExpression(instr, exprInstr);
};
ParserState.prototype.pushExpression = function (instr, exprInstr) {
for (var i = 0, len = exprInstr.length; i < len; i++) {
instr.push(exprInstr[i]);
}
};
ParserState.prototype.parseUntilEndStatement = function (instr, exprInstr) {
if (!this.accept(TSEMICOLON)) return false;
if (this.nextToken && this.nextToken.type !== TEOF && !(this.nextToken.type === TPAREN && this.nextToken.value === ')')) {
exprInstr.push(new Instruction(IENDSTATEMENT));
}
if (this.nextToken.type !== TEOF) {
this.parseExpression(exprInstr);
}
instr.push(new Instruction(IEXPR, exprInstr));
return true;
};
ParserState.prototype.parseArrayList = function (instr) {
var argCount = 0;
while (!this.accept(TBRACKET, ']')) {
this.parseExpression(instr);
++argCount;
while (this.accept(TCOMMA)) {
this.parseExpression(instr);
++argCount;
}
}
return argCount;
};
ParserState.prototype.parseVariableAssignmentExpression = function (instr) {
this.parseConditionalExpression(instr);
while (this.accept(TOP, '=')) {
var varName = instr.pop();
var varValue = [];
var lastInstrIndex = instr.length - 1;
if (varName.type === IFUNCALL) {
if (!this.tokens.isOperatorEnabled('()=')) {
throw new Error('function definition is not permitted');
}
for (var i = 0, len = varName.value + 1; i < len; i++) {
var index = lastInstrIndex - i;
if (instr[index].type === IVAR) {
instr[index] = new Instruction(IVARNAME, instr[index].value);
}
}
this.parseVariableAssignmentExpression(varValue);
instr.push(new Instruction(IEXPR, varValue));
instr.push(new Instruction(IFUNDEF, varName.value));
continue;
}
if (varName.type !== IVAR && varName.type !== IMEMBER) {
throw new Error('expected variable for assignment');
}
this.parseVariableAssignmentExpression(varValue);
instr.push(new Instruction(IVARNAME, varName.value));
instr.push(new Instruction(IEXPR, varValue));
instr.push(binaryInstruction('='));
}
};

@@ -1105,10 +1305,17 @@

if (this.accept(TOP, isPrefixOperator)) {
if ((this.current.value !== '-' && this.current.value !== '+' && this.nextToken.type === TPAREN && this.nextToken.value === '(')) {
this.restore();
this.parseExponential(instr);
} else {
var op = this.current;
this.parseFactor(instr);
instr.push(unaryInstruction(op.value));
if (this.current.value !== '-' && this.current.value !== '+') {
if (this.nextToken.type === TPAREN && this.nextToken.value === '(') {
this.restore();
this.parseExponential(instr);
return;
} else if (this.nextToken.type === TSEMICOLON || this.nextToken.type === TCOMMA || this.nextToken.type === TEOF || (this.nextToken.type === TPAREN && this.nextToken.value === ')')) {
this.restore();
this.parseAtom(instr);
return;
}
}
var op = this.current;
this.parseFactor(instr);
instr.push(unaryInstruction(op.value));
} else {

@@ -1188,9 +1395,23 @@ this.parseExponential(instr);

this.parseAtom(instr);
while (this.accept(TOP, '.')) {
if (!this.allowMemberAccess) {
throw new Error('unexpected ".", member access is not permitted');
while (this.accept(TOP, '.') || this.accept(TBRACKET, '[')) {
var op = this.current;
if (op.value === '.') {
if (!this.allowMemberAccess) {
throw new Error('unexpected ".", member access is not permitted');
}
this.expect(TNAME);
instr.push(new Instruction(IMEMBER, this.current.value));
} else if (op.value === '[') {
if (!this.tokens.isOperatorEnabled('[')) {
throw new Error('unexpected "[]", arrays are disabled');
}
this.parseExpression(instr);
this.expect(TBRACKET, ']');
instr.push(binaryInstruction('['));
} else {
throw new Error('unexpected symbol: ' + op.value);
}
this.expect(TNAME);
instr.push(new Instruction(IMEMBER, this.current.value));
}

@@ -1220,2 +1441,5 @@ };

function concat(a, b) {
if (Array.isArray(a) && Array.isArray(b)) {
return a.concat(b);
}
return '' + a + b;

@@ -1384,3 +1608,6 @@ }

function stringLength(s) {
function stringOrArrayLength(s) {
if (Array.isArray(s)) {
return s.length;
}
return String(s).length;

@@ -1440,2 +1667,110 @@ }

function setVar(name, value, variables) {
if (variables) variables[name] = value;
return value;
}
function arrayIndex(array, index) {
return array[index | 0];
}
function max(array) {
if (arguments.length === 1 && Array.isArray(array)) {
return Math.max.apply(Math, array);
} else {
return Math.max.apply(Math, arguments);
}
}
function min(array) {
if (arguments.length === 1 && Array.isArray(array)) {
return Math.min.apply(Math, array);
} else {
return Math.min.apply(Math, arguments);
}
}
function arrayMap(f, a) {
if (typeof f !== 'function') {
throw new Error('First argument to map is not a function');
}
if (!Array.isArray(a)) {
throw new Error('Second argument to map is not an array');
}
return a.map(function (x, i) {
return f(x, i);
});
}
function arrayFold(f, init, a) {
if (typeof f !== 'function') {
throw new Error('First argument to fold is not a function');
}
if (!Array.isArray(a)) {
throw new Error('Second argument to fold is not an array');
}
return a.reduce(function (acc, x, i) {
return f(acc, x, i);
}, init);
}
function arrayFilter(f, a) {
if (typeof f !== 'function') {
throw new Error('First argument to filter is not a function');
}
if (!Array.isArray(a)) {
throw new Error('Second argument to filter is not an array');
}
return a.filter(function (x, i) {
return f(x, i);
});
}
function stringOrArrayIndexOf(target, s) {
if (!(Array.isArray(s) || typeof s === 'string')) {
throw new Error('Second argument to indexOf is not a string or array');
}
return s.indexOf(target);
}
function arrayJoin(sep, a) {
if (!Array.isArray(a)) {
throw new Error('Second argument to join is not an array');
}
return a.join(sep);
}
function sign(x) {
return ((x > 0) - (x < 0)) || +x;
}
var ONE_THIRD = 1/3;
function cbrt(x) {
return x < 0 ? -Math.pow(-x, ONE_THIRD) : Math.pow(x, ONE_THIRD);
}
function expm1(x) {
return Math.exp(x) - 1;
}
function log1p(x) {
return Math.log(1 + x);
}
function log2(x) {
return Math.log(x) / Math.LN2;
}
function sum(array) {
if (!Array.isArray(array)) {
throw new Error('Sum argument is not an array');
}
return array.reduce(function (total, value) {
return total + Number(value);
}, 0);
}
function Parser(options) {

@@ -1457,6 +1792,10 @@ this.options = options || {};

sqrt: Math.sqrt,
cbrt: Math.cbrt || cbrt,
log: Math.log,
log2: Math.log2 || log2,
ln: Math.log,
lg: Math.log10 || log10,
log10: Math.log10 || log10,
expm1: Math.expm1 || expm1,
log1p: Math.log1p || log1p,
abs: Math.abs,

@@ -1471,4 +1810,5 @@ ceil: Math.ceil,

not: not,
length: stringLength,
'!': factorial
length: stringOrArrayLength,
'!': factorial,
sign: Math.sign || sign
};

@@ -1492,3 +1832,5 @@

or: orOperator,
'in': inOperator
'in': inOperator,
'=': setVar,
'[': arrayIndex
};

@@ -1503,4 +1845,4 @@

fac: factorial,
min: Math.min,
max: Math.max,
min: min,
max: max,
hypot: Math.hypot || hypot,

@@ -1512,3 +1854,9 @@ pyt: Math.hypot || hypot, // backward compat

gamma: gamma,
roundTo: roundTo
roundTo: roundTo,
map: arrayMap,
fold: arrayFold,
filter: arrayFilter,
indexOf: stringOrArrayIndexOf,
join: arrayJoin,
sum: sum
};

@@ -1552,2 +1900,38 @@

var optionNameMap = {
'+': 'add',
'-': 'subtract',
'*': 'multiply',
'/': 'divide',
'%': 'remainder',
'^': 'power',
'!': 'factorial',
'<': 'comparison',
'>': 'comparison',
'<=': 'comparison',
'>=': 'comparison',
'==': 'comparison',
'!=': 'comparison',
'||': 'concatenate',
'and': 'logical',
'or': 'logical',
'not': 'logical',
'?': 'conditional',
':': 'conditional',
'=': 'assignment',
'[': 'array',
'()=': 'fndef'
};
function getOptionName(op) {
return optionNameMap.hasOwnProperty(op) ? optionNameMap[op] : op;
}
Parser.prototype.isOperatorEnabled = function (op) {
var optionName = getOptionName(op);
var operators = this.options.operators || {};
return !(optionName in operators) || !!operators[optionName];
};
/*!

@@ -1564,2 +1948,3 @@ Based on ndef.parser, by Raphael Graf(r@undefined.ch)

// Backwards compatibility
var index = {

@@ -1570,4 +1955,8 @@ Parser: Parser,

return index;
exports.Expression = Expression;
exports.Parser = Parser;
exports.default = index;
Object.defineProperty(exports, '__esModule', { value: true });
})));

@@ -1,1 +0,12 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.exprEval=e()}(this,function(){"use strict";var t="INUMBER",e="IOP1",s="IOP2",r="IOP3",n="IVAR",i="IFUNCOP",o="IFUNCALL",p="IEXPR",a="IMEMBER";function h(t,e){this.type=t,this.value=void 0!==e&&null!==e?e:0}function u(t){return new h(e,t)}function c(t){return new h(s,t)}function l(t){return new h(r,t)}function f(i,h){for(var u,c,l,x,y=[],w=0;w<i.length;w++){var d=i[w],M=d.type;if(M===t)"number"==typeof d.value&&d.value<0?y.push("("+d.value+")"):y.push(v(d.value));else if(M===s)c=y.pop(),u=y.pop(),x=d.value,h?"^"===x?y.push("Math.pow("+u+", "+c+")"):"and"===x?y.push("(!!"+u+" && !!"+c+")"):"or"===x?y.push("(!!"+u+" || !!"+c+")"):"||"===x?y.push("(String("+u+") + String("+c+"))"):"=="===x?y.push("("+u+" === "+c+")"):"!="===x?y.push("("+u+" !== "+c+")"):y.push("("+u+" "+x+" "+c+")"):y.push("("+u+" "+x+" "+c+")");else if(M===r){if(l=y.pop(),c=y.pop(),u=y.pop(),"?"!==(x=d.value))throw new Error("invalid Expression");y.push("("+u+" ? "+c+" : "+l+")")}else if(M===n)y.push(d.value);else if(M===e)u=y.pop(),"-"===(x=d.value)||"+"===x?y.push("("+x+u+")"):h?"not"===x?y.push("(!"+u+")"):"!"===x?y.push("fac("+u+")"):y.push(x+"("+u+")"):"!"===x?y.push("("+u+"!)"):y.push("("+x+" "+u+")");else if(M===o){for(var g=d.value,E=[];g-- >0;)E.unshift(y.pop());x=y.pop(),y.push(x+"("+E.join(", ")+")")}else if(M===a)u=y.pop(),y.push(u+"."+d.value);else{if(M!==p)throw new Error("invalid Expression");y.push("("+f(d.value,h)+")")}}if(y.length>1)throw new Error("invalid Expression (parity)");return String(y[0])}function v(t){return"string"==typeof t?JSON.stringify(t).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"):t}function x(t,e){for(var s=0;s<t.length;s++)if(t[s]===e)return!0;return!1}function y(t,e,s){for(var r=!!(s=s||{}).withMembers,i=null,o=0;o<t.length;o++){var h=t[o];h.type===n?r||x(e,h.value)?null!==i?(x(e,i)||e.push(i),i=h.value):i=h.value:e.push(h.value):h.type===a&&r&&null!==i?i+="."+h.value:h.type===p?y(h.value,e,s):null!==i&&(x(e,i)||e.push(i),i=null)}null===i||x(e,i)||e.push(i)}function w(t,e){this.tokens=t,this.parser=e,this.unaryOps=e.unaryOps,this.binaryOps=e.binaryOps,this.ternaryOps=e.ternaryOps,this.functions=e.functions}h.prototype.toString=function(){switch(this.type){case t:case e:case s:case r:case n:case i:return this.value;case o:return"CALL "+this.value;case a:return"."+this.value;default:return"Invalid Instruction"}},w.prototype.simplify=function(i){return i=i||{},new w(function i(o,u,c,l,f){for(var v,x,y,w,d=[],M=[],g=0;g<o.length;g++){var E=o[g],k=E.type;if(k===t)d.push(E);else if(k===n&&f.hasOwnProperty(E.value))E=new h(t,f[E.value]),d.push(E);else if(k===s&&d.length>1)x=d.pop(),v=d.pop(),w=c[E.value],E=new h(t,w(v.value,x.value)),d.push(E);else if(k===r&&d.length>2)y=d.pop(),x=d.pop(),v=d.pop(),"?"===E.value?d.push(v.value?x.value:y.value):(w=l[E.value],E=new h(t,w(v.value,x.value,y.value)),d.push(E));else if(k===e&&d.length>0)v=d.pop(),w=u[E.value],E=new h(t,w(v.value)),d.push(E);else if(k===p){for(;d.length>0;)M.push(d.shift());M.push(new h(p,i(E.value,u,c,l,f)))}else if(k===a&&d.length>0)v=d.pop(),d.push(new h(t,v.value[E.value]));else{for(;d.length>0;)M.push(d.shift());M.push(E)}}for(;d.length>0;)M.push(d.shift());return M}(this.tokens,this.unaryOps,this.binaryOps,this.ternaryOps,i),this.parser)},w.prototype.substitute=function(t,i){return i instanceof w||(i=this.parser.parse(String(i))),new w(function t(i,o,a){for(var f=[],v=0;v<i.length;v++){var x=i[v],y=x.type;if(y===n&&x.value===o)for(var w=0;w<a.tokens.length;w++){var d,M=a.tokens[w];d=M.type===e?u(M.value):M.type===s?c(M.value):M.type===r?l(M.value):new h(M.type,M.value),f.push(d)}else y===p?f.push(new h(p,t(x.value,o,a))):f.push(x)}return f}(this.tokens,t,i),this.parser)},w.prototype.evaluate=function(h){return h=h||{},function h(u,c,l){for(var f,v,x,y,w=[],d=0;d<u.length;d++){var M=u[d],g=M.type;if(g===t)w.push(M.value);else if(g===s)v=w.pop(),f=w.pop(),"and"===M.value?w.push(!!f&&!!h(v,c,l)):"or"===M.value?w.push(!!f||!!h(v,c,l)):(y=c.binaryOps[M.value],w.push(y(f,v)));else if(g===r)x=w.pop(),v=w.pop(),f=w.pop(),"?"===M.value?w.push(h(f?v:x,c,l)):(y=c.ternaryOps[M.value],w.push(y(f,v,x)));else if(g===n)if(M.value in c.functions)w.push(c.functions[M.value]);else{var E=l[M.value];if(void 0===E)throw new Error("undefined variable: "+M.value);w.push(E)}else if(g===e)f=w.pop(),y=c.unaryOps[M.value],w.push(y(f));else if(g===i){if(v=w.pop(),f=w.pop(),!(y=c.functions[M.value]).apply||!y.call)throw new Error(y+" is not a function");w.push(y.apply(void 0,[f,v]))}else if(g===o){for(var k=M.value,b=[];k-- >0;)b.unshift(w.pop());if(!(y=w.pop()).apply||!y.call)throw new Error(y+" is not a function");w.push(y.apply(void 0,b))}else if(g===p)w.push(M.value);else{if(g!==a)throw new Error("invalid Expression");f=w.pop(),w.push(f[M.value])}}if(w.length>1)throw new Error("invalid Expression (parity)");return-0===w[0]?0:w[0]}(this.tokens,this,h)},w.prototype.toString=function(){return f(this.tokens,!1)},w.prototype.symbols=function(t){t=t||{};var e=[];return y(this.tokens,e,t),e},w.prototype.variables=function(t){t=t||{};var e=[];y(this.tokens,e,t);var s=this.functions;return e.filter(function(t){return!(t in s)})},w.prototype.toJSFunction=function(t,e){var s=this,r=new Function(t,"with(this.functions) with (this.ternaryOps) with (this.binaryOps) with (this.unaryOps) { return "+f(this.simplify(e).tokens,!0)+"; }");return function(){return r.apply(s,arguments)}};var d="TOP";function M(t,e,s){this.type=t,this.value=e,this.index=s}function g(t,e){this.pos=0,this.current=null,this.unaryOps=t.unaryOps,this.binaryOps=t.binaryOps,this.ternaryOps=t.ternaryOps,this.functions=t.functions,this.consts=t.consts,this.expression=e,this.savedPosition=0,this.savedCurrent=null,this.options=t.options}M.prototype.toString=function(){return this.type+": "+this.value},g.prototype.newToken=function(t,e,s){return new M(t,e,null!=s?s:this.pos)},g.prototype.save=function(){this.savedPosition=this.pos,this.savedCurrent=this.current},g.prototype.restore=function(){this.pos=this.savedPosition,this.current=this.savedCurrent},g.prototype.next=function(){return this.pos>=this.expression.length?this.newToken("TEOF","EOF"):this.isWhitespace()||this.isComment()?this.next():this.isRadixInteger()||this.isNumber()||this.isOperator()||this.isString()||this.isParen()||this.isComma()||this.isNamedOp()||this.isFuncOp()||this.isConst()||this.isName()?this.current:void this.parseError('Unknown character "'+this.expression.charAt(this.pos)+'"')},g.prototype.isString=function(){var t=!1,e=this.pos,s=this.expression.charAt(e);if("'"===s||'"'===s)for(var r=this.expression.indexOf(s,e+1);r>=0&&this.pos<this.expression.length;){if(this.pos=r+1,"\\"!==this.expression.charAt(r-1)){var n=this.expression.substring(e+1,r);this.current=this.newToken("TSTRING",this.unescape(n),e),t=!0;break}r=this.expression.indexOf(s,r+1)}return t},g.prototype.isParen=function(){var t=this.expression.charAt(this.pos);return("("===t||")"===t)&&(this.current=this.newToken("TPAREN",t),this.pos++,!0)},g.prototype.isComma=function(){return","===this.expression.charAt(this.pos)&&(this.current=this.newToken("TCOMMA",","),this.pos++,!0)},g.prototype.isConst=function(){for(var t=this.pos,e=t;e<this.expression.length;e++){var s=this.expression.charAt(e);if(s.toUpperCase()===s.toLowerCase()&&(e===this.pos||"_"!==s&&"."!==s&&(s<"0"||s>"9")))break}if(e>t){var r=this.expression.substring(t,e);if(r in this.consts)return this.current=this.newToken("TNUMBER",this.consts[r]),this.pos+=r.length,!0}return!1},g.prototype.isNamedOp=function(){for(var t=this.pos,e=t;e<this.expression.length;e++){var s=this.expression.charAt(e);if(s.toUpperCase()===s.toLowerCase()&&(e===this.pos||"_"!==s&&(s<"0"||s>"9")))break}if(e>t){var r=this.expression.substring(t,e);if(this.isOperatorEnabled(r)&&(r in this.binaryOps||r in this.unaryOps||r in this.ternaryOps))return this.current=this.newToken(d,r),this.pos+=r.length,!0}return!1},g.prototype.isFuncOp=function(){var t,e=this.expression.charAt(this.pos),s=this.pos+1,r=s;if("@"===e){for(;r<this.expression.length&&((e=this.expression.charAt(r)).toUpperCase()!==e.toLowerCase()||!(r===s||"_"!==e&&(e<"0"||e>"9")));r++);if(r>s&&(t=this.expression.substring(s,r))in this.functions)return this.current=this.newToken("TFUNCOP",t),this.pos=s+t.length,!0}return!1},g.prototype.isName=function(){for(var t=this.pos,e=t,s=!1;e<this.expression.length;e++){var r=this.expression.charAt(e);if(r.toUpperCase()===r.toLowerCase()){if(e===this.pos&&("$"===r||"_"===r)){"_"===r&&(s=!0);continue}if(e===this.pos||!s||"_"!==r&&(r<"0"||r>"9"))break}else s=!0}if(s){var n=this.expression.substring(t,e);return this.current=this.newToken("TNAME",n),this.pos+=n.length,!0}return!1},g.prototype.isWhitespace=function(){for(var t=!1,e=this.expression.charAt(this.pos);!(" "!==e&&"\t"!==e&&"\n"!==e&&"\r"!==e||(t=!0,this.pos++,this.pos>=this.expression.length));)e=this.expression.charAt(this.pos);return t};var E=/^[0-9a-f]{4}$/i;g.prototype.unescape=function(t){var e=t.indexOf("\\");if(e<0)return t;for(var s=t.substring(0,e);e>=0;){var r=t.charAt(++e);switch(r){case"'":s+="'";break;case'"':s+='"';break;case"\\":s+="\\";break;case"/":s+="/";break;case"b":s+="\b";break;case"f":s+="\f";break;case"n":s+="\n";break;case"r":s+="\r";break;case"t":s+="\t";break;case"u":var n=t.substring(e+1,e+5);E.test(n)||this.parseError("Illegal escape sequence: \\u"+n),s+=String.fromCharCode(parseInt(n,16)),e+=4;break;default:throw this.parseError('Illegal escape sequence: "\\'+r+'"')}++e;var i=t.indexOf("\\",e);s+=t.substring(e,i<0?t.length:i),e=i}return s},g.prototype.isComment=function(){return"/"===this.expression.charAt(this.pos)&&"*"===this.expression.charAt(this.pos+1)&&(this.pos=this.expression.indexOf("*/",this.pos)+2,1===this.pos&&(this.pos=this.expression.length),!0)},g.prototype.isRadixInteger=function(){var t,e,s=this.pos;if(s>=this.expression.length-2||"0"!==this.expression.charAt(s))return!1;if(++s,"x"===this.expression.charAt(s))t=16,e=/^[0-9a-f]$/i,++s;else{if("b"!==this.expression.charAt(s))return!1;t=2,e=/^[01]$/i,++s}for(var r=!1,n=s;s<this.expression.length;){var i=this.expression.charAt(s);if(!e.test(i))break;s++,r=!0}return r&&(this.current=this.newToken("TNUMBER",parseInt(this.expression.substring(n,s),t)),this.pos=s),r},g.prototype.isNumber=function(){for(var t,e=!1,s=this.pos,r=s,n=s,i=!1,o=!1;s<this.expression.length&&((t=this.expression.charAt(s))>="0"&&t<="9"||!i&&"."===t);)"."===t?i=!0:o=!0,s++,e=o;if(e&&(n=s),"e"===t||"E"===t){s++;for(var p=!0,a=!1;s<this.expression.length;){if(t=this.expression.charAt(s),!p||"+"!==t&&"-"!==t){if(!(t>="0"&&t<="9"))break;a=!0,p=!1}else p=!1;s++}a||(s=n)}return e?(this.current=this.newToken("TNUMBER",parseFloat(this.expression.substring(r,s))),this.pos=s):this.pos=n,e},g.prototype.isOperator=function(){var t=this.pos,e=this.expression.charAt(this.pos);if("+"===e||"-"===e||"*"===e||"/"===e||"%"===e||"^"===e||"?"===e||":"===e||"."===e)this.current=this.newToken(d,e);else if("∙"===e||"•"===e)this.current=this.newToken(d,"*");else if(">"===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(d,">="),this.pos++):this.current=this.newToken(d,">");else if("<"===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(d,"<="),this.pos++):this.current=this.newToken(d,"<");else if("|"===e){if("|"!==this.expression.charAt(this.pos+1))return!1;this.current=this.newToken(d,"||"),this.pos++}else if("="===e){if("="!==this.expression.charAt(this.pos+1))return!1;this.current=this.newToken(d,"=="),this.pos++}else{if("!"!==e)return!1;"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(d,"!="),this.pos++):this.current=this.newToken(d,e)}return this.pos++,!!this.isOperatorEnabled(this.current.value)||(this.pos=t,!1)};var k={"+":"add","-":"subtract","*":"multiply","/":"divide","%":"remainder","^":"power","!":"factorial","<":"comparison",">":"comparison","<=":"comparison",">=":"comparison","==":"comparison","!=":"comparison","||":"concatenate",and:"logical",or:"logical",not:"logical","?":"conditional",":":"conditional"};function b(t,e,s){this.parser=t,this.tokens=e,this.current=null,this.nextToken=null,this.next(),this.savedCurrent=null,this.savedNextToken=null,this.allowMemberAccess=!1!==s.allowMemberAccess}g.prototype.isOperatorEnabled=function(t){var e=function(t){return k.hasOwnProperty(t)?k[t]:t}(t),s=this.options.operators||{};return"in"===e?!!s.in:!(e in s&&!s[e])},g.prototype.getCoordinates=function(){var t,e=0,s=-1;do{e++,t=this.pos-s,s=this.expression.indexOf("\n",s+1)}while(s>=0&&s<this.pos);return{line:e,column:t}},g.prototype.parseError=function(t){var e=this.getCoordinates();throw new Error("parse error ["+e.line+":"+e.column+"]: "+t)},b.prototype.next=function(){return this.current=this.nextToken,this.nextToken=this.tokens.next()},b.prototype.tokenMatches=function(t,e){return void 0===e||(Array.isArray(e)?x(e,t.value):"function"==typeof e?e(t):t.value===e)},b.prototype.save=function(){this.savedCurrent=this.current,this.savedNextToken=this.nextToken,this.tokens.save()},b.prototype.restore=function(){this.tokens.restore(),this.current=this.savedCurrent,this.nextToken=this.savedNextToken},b.prototype.accept=function(t,e){return!(this.nextToken.type!==t||!this.tokenMatches(this.nextToken,e))&&(this.next(),!0)},b.prototype.expect=function(t,e){if(!this.accept(t,e)){var s=this.tokens.getCoordinates();throw new Error("parse error ["+s.line+":"+s.column+"]: Expected "+(e||t))}},b.prototype.parseAtom=function(e){if(this.accept("TNAME"))e.push(new h(n,this.current.value));else if(this.accept("TNUMBER"))e.push(new h(t,this.current.value));else if(this.accept("TSTRING"))e.push(new h(t,this.current.value));else{if(!this.accept("TPAREN","("))throw new Error("unexpected "+this.nextToken);this.parseExpression(e),this.expect("TPAREN",")")}},b.prototype.parseExpression=function(t){this.parseConditionalExpression(t)},b.prototype.parseConditionalExpression=function(t){for(this.parseOrExpression(t);this.accept(d,"?");){var e=[],s=[];this.parseConditionalExpression(e),this.expect(d,":"),this.parseConditionalExpression(s),t.push(new h(p,e)),t.push(new h(p,s)),t.push(l("?"))}},b.prototype.parseOrExpression=function(t){for(this.parseAndExpression(t);this.accept(d,"or");){var e=[];this.parseAndExpression(e),t.push(new h(p,e)),t.push(c("or"))}},b.prototype.parseAndExpression=function(t){for(this.parseComparison(t);this.accept(d,"and");){var e=[];this.parseComparison(e),t.push(new h(p,e)),t.push(c("and"))}};var m=["==","!=","<","<=",">=",">","in"];b.prototype.parseComparison=function(t){for(this.parseAddSub(t);this.accept(d,m);){var e=this.current;this.parseAddSub(t),t.push(c(e.value))}};var O=["+","-","||"];b.prototype.parseAddSub=function(t){for(this.parseTerm(t);this.accept(d,O);){var e=this.current;this.parseTerm(t),t.push(c(e.value))}};var T=["*","/","%"];function A(t,e){return Number(t)+Number(e)}function C(t,e){return t-e}function N(t,e){return t*e}function P(t,e){return t/e}function F(t,e){return t%e}function I(t,e){return""+t+e}function S(t,e){return t===e}function R(t,e){return t!==e}function U(t,e){return t>e}function L(t,e){return t<e}function q(t,e){return t>=e}function B(t,e){return t<=e}function _(t,e){return Boolean(t&&e)}function $(t,e){return Boolean(t||e)}function G(t,e){return x(e,t)}function j(t){return(Math.exp(t)-Math.exp(-t))/2}function J(t){return(Math.exp(t)+Math.exp(-t))/2}function W(t){return t===1/0?1:t===-1/0?-1:(Math.exp(t)-Math.exp(-t))/(Math.exp(t)+Math.exp(-t))}function V(t){return t===-1/0?t:Math.log(t+Math.sqrt(t*t+1))}function X(t){return Math.log(t+Math.sqrt(t*t-1))}function z(t){return Math.log((1+t)/(1-t))/2}function D(t){return Math.log(t)*Math.LOG10E}function H(t){return-t}function K(t){return!t}function Q(t){return t<0?Math.ceil(t):Math.floor(t)}function Y(t){return Math.random()*(t||1)}function Z(t){return st(t+1)}b.prototype.parseTerm=function(t){for(this.parseFactor(t);this.accept(d,T);){var e=this.current;this.parseFactor(t),t.push(c(e.value))}},b.prototype.parseFactor=function(t){var e=this.tokens.unaryOps;if(this.save(),this.accept(d,function(t){return t.value in e}))if("-"!==this.current.value&&"+"!==this.current.value&&"TPAREN"===this.nextToken.type&&"("===this.nextToken.value)this.restore(),this.parseExponential(t);else{var s=this.current;this.parseFactor(t),t.push(u(s.value))}else this.parseExponential(t)},b.prototype.parseExponential=function(t){for(this.parsePostfixExpression(t);this.accept(d,"^");)this.parseFactor(t),t.push(c("^"))},b.prototype.parsePostfixExpression=function(t){for(this.parseFunctionOperator(t);this.accept(d,"!");)t.push(u("!"))},b.prototype.parseFunctionOperator=function(t){var e,s=this.tokens.functions;function r(t){return t.value in s}for(this.parseFunctionCall(t);this.accept("TFUNCOP",r);)e=this.current,this.parseFactor(t),t.push(new h(i,e.value))},b.prototype.parseFunctionCall=function(t){var e=this.tokens.unaryOps;if(this.accept(d,function(t){return t.value in e})){var s=this.current;this.parseAtom(t),t.push(u(s.value))}else for(this.parseMemberExpression(t);this.accept("TPAREN","(");)if(this.accept("TPAREN",")"))t.push(new h(o,0));else{var r=this.parseArgumentList(t);t.push(new h(o,r))}},b.prototype.parseArgumentList=function(t){for(var e=0;!this.accept("TPAREN",")");)for(this.parseExpression(t),++e;this.accept("TCOMMA");)this.parseExpression(t),++e;return e},b.prototype.parseMemberExpression=function(t){for(this.parseAtom(t);this.accept(d,".");){if(!this.allowMemberAccess)throw new Error('unexpected ".", member access is not permitted');this.expect("TNAME"),t.push(new h(a,this.current.value))}};var tt=4.7421875,et=[.9999999999999971,57.15623566586292,-59.59796035547549,14.136097974741746,-.4919138160976202,3399464998481189e-20,4652362892704858e-20,-9837447530487956e-20,.0001580887032249125,-.00021026444172410488,.00021743961811521265,-.0001643181065367639,8441822398385275e-20,-26190838401581408e-21,36899182659531625e-22];function st(t){var e,s;if(function(t){return isFinite(t)&&t===Math.round(t)}(t)){if(t<=0)return isFinite(t)?1/0:NaN;if(t>171)return 1/0;for(var r=t-2,n=t-1;r>1;)n*=r,r--;return 0===n&&(n=1),n}if(t<.5)return Math.PI/(Math.sin(Math.PI*t)*st(1-t));if(t>=171.35)return 1/0;if(t>85){var i=t*t,o=i*t,p=o*t,a=p*t;return Math.sqrt(2*Math.PI/t)*Math.pow(t/Math.E,t)*(1+1/(12*t)+1/(288*i)-139/(51840*o)-571/(2488320*p)+163879/(209018880*a)+5246819/(75246796800*a*t))}--t,s=et[0];for(var h=1;h<et.length;++h)s+=et[h]/(t+h);return e=t+tt+.5,Math.sqrt(2*Math.PI)*Math.pow(e,t+.5)*Math.exp(-e)*s}function rt(t){return String(t).length}function nt(){for(var t=0,e=0,s=0;s<arguments.length;s++){var r,n=Math.abs(arguments[s]);e<n?(t=t*(r=e/n)*r+1,e=n):t+=n>0?(r=n/e)*r:n}return e===1/0?1/0:e*Math.sqrt(t)}function it(t,e,s){return t?e:s}function ot(t,e){return void 0===e||0==+e?Math.round(t):(t=+t,e=-+e,isNaN(t)||"number"!=typeof e||e%1!=0?NaN:(t=t.toString().split("e"),+((t=(t=Math.round(+(t[0]+"e"+(t[1]?+t[1]-e:-e)))).toString().split("e"))[0]+"e"+(t[1]?+t[1]+e:e))))}function pt(t){this.options=t||{},this.unaryOps={sin:Math.sin,cos:Math.cos,tan:Math.tan,asin:Math.asin,acos:Math.acos,atan:Math.atan,sinh:Math.sinh||j,cosh:Math.cosh||J,tanh:Math.tanh||W,asinh:Math.asinh||V,acosh:Math.acosh||X,atanh:Math.atanh||z,sqrt:Math.sqrt,log:Math.log,ln:Math.log,lg:Math.log10||D,log10:Math.log10||D,abs:Math.abs,ceil:Math.ceil,floor:Math.floor,round:Math.round,trunc:Math.trunc||Q,"-":H,"+":Number,exp:Math.exp,not:K,length:rt,"!":Z},this.binaryOps={"+":A,"-":C,"*":N,"/":P,"%":F,"^":Math.pow,"||":I,"==":S,"!=":R,">":U,"<":L,">=":q,"<=":B,and:_,or:$,in:G},this.ternaryOps={"?":it},this.functions={random:Y,fac:Z,min:Math.min,max:Math.max,hypot:Math.hypot||nt,pyt:Math.hypot||nt,pow:Math.pow,atan2:Math.atan2,if:it,gamma:st,roundTo:ot},this.consts={E:Math.E,PI:Math.PI,true:!0,false:!1}}pt.prototype.parse=function(t){var e=[],s=new b(this,new g(this,t),{allowMemberAccess:this.options.allowMemberAccess});return s.parseExpression(e),s.expect("TEOF","EOF"),new w(e,this)},pt.prototype.evaluate=function(t,e){return this.parse(t).evaluate(e)};var at=new pt;return pt.parse=function(t){return at.parse(t)},pt.evaluate=function(t,e){return at.parse(t).evaluate(e)},{Parser:pt,Expression:w}});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).exprEval={})}(this,(function(t){"use strict";var e="INUMBER",r="IOP1",s="IOP2",n="IOP3",i="IVAR",o="IVARNAME",a="IFUNCOP",p="IFUNCALL",h="IFUNDEF",u="IEXPR",c="IEXPREVAL",f="IMEMBER",l="IENDSTATEMENT",v="IARRAY";function y(t,e){this.type=t,this.value=null!=e?e:0}function x(t){return new y(r,t)}function w(t){return new y(s,t)}function d(t){return new y(n,t)}function g(t,a,p,h,c){for(var l,x,w,d,E=[],M=[],m=0;m<t.length;m++){var A=t[m],b=A.type;if(b===e||b===o)Array.isArray(A.value)?E.push.apply(E,g(A.value.map((function(t){return new y(e,t)})).concat(new y(v,A.value.length)),a,p,h,c)):E.push(A);else if(b===i&&c.hasOwnProperty(A.value))A=new y(e,c[A.value]),E.push(A);else if(b===s&&E.length>1)x=E.pop(),l=E.pop(),d=p[A.value],A=new y(e,d(l.value,x.value)),E.push(A);else if(b===n&&E.length>2)w=E.pop(),x=E.pop(),l=E.pop(),"?"===A.value?E.push(l.value?x.value:w.value):(d=h[A.value],A=new y(e,d(l.value,x.value,w.value)),E.push(A));else if(b===r&&E.length>0)l=E.pop(),d=a[A.value],A=new y(e,d(l.value)),E.push(A);else if(b===u){for(;E.length>0;)M.push(E.shift());M.push(new y(u,g(A.value,a,p,h,c)))}else if(b===f&&E.length>0)l=E.pop(),E.push(new y(e,l.value[A.value]));else{for(;E.length>0;)M.push(E.shift());M.push(A)}}for(;E.length>0;)M.push(E.shift());return M}function E(t,e,o){for(var a=[],p=0;p<t.length;p++){var h=t[p],c=h.type;if(c===i&&h.value===e)for(var f=0;f<o.tokens.length;f++){var l,v=o.tokens[f];l=v.type===r?x(v.value):v.type===s?w(v.value):v.type===n?d(v.value):new y(v.type,v.value),a.push(l)}else c===u?a.push(new y(u,E(h.value,e,o))):a.push(h)}return a}function M(t,y,x){var w,d,g,E,k,O,T=[];if(A(t))return b(t,x);for(var C=t.length,N=0;N<C;N++){var S=t[N],I=S.type;if(I===e||I===o)T.push(S.value);else if(I===s)d=T.pop(),w=T.pop(),"and"===S.value?T.push(!!w&&!!M(d,y,x)):"or"===S.value?T.push(!!w||!!M(d,y,x)):"="===S.value?(E=y.binaryOps[S.value],T.push(E(w,M(d,y,x),x))):(E=y.binaryOps[S.value],T.push(E(b(w,x),b(d,x))));else if(I===n)g=T.pop(),d=T.pop(),w=T.pop(),"?"===S.value?T.push(M(w?d:g,y,x)):(E=y.ternaryOps[S.value],T.push(E(b(w,x),b(d,x),b(g,x))));else if(I===i){if(/^__proto__|prototype|constructor$/.test(S.value))throw new Error("prototype access detected");if(S.value in y.functions)T.push(y.functions[S.value]);else if(S.value in y.unaryOps&&y.parser.isOperatorEnabled(S.value))T.push(y.unaryOps[S.value]);else{var F=x[S.value];if(void 0===F)throw new Error("undefined variable: "+S.value);T.push(F)}}else if(I===r)w=T.pop(),E=y.unaryOps[S.value],T.push(E(b(w,x)));else if(I===a){if(d=T.pop(),w=T.pop(),!(E=y.functions[S.value]).apply||!E.call)throw new Error(E+" is not a function");T.push(E.apply(void 0,[w,d]))}else if(I===p){for(O=S.value,k=[];O-- >0;)k.unshift(b(T.pop(),x));if(!(E=T.pop()).apply||!E.call)throw new Error(E+" is not a function");T.push(E.apply(void 0,k))}else if(I===h)T.push(function(){for(var t=T.pop(),e=[],r=S.value;r-- >0;)e.unshift(T.pop());var s=T.pop(),n=function(){for(var r=Object.assign({},x),s=0,n=e.length;s<n;s++)r[e[s]]=arguments[s];return M(t,y,r)};return Object.defineProperty(n,"name",{value:s,writable:!1}),x[s]=n,n}());else if(I===u)T.push(m(S,y));else if(I===c)T.push(S);else if(I===f)w=T.pop(),T.push(w[S.value]);else if(I===l)T.pop();else{if(I!==v)throw new Error("invalid Expression");for(O=S.value,k=[];O-- >0;)k.unshift(T.pop());T.push(k)}}if(T.length>1)throw new Error("invalid Expression (parity)");return 0===T[0]?0:b(T[0],x)}function m(t,e,r){return A(t)?t:{type:c,value:function(r){return M(t.value,e,r)}}}function A(t){return t&&t.type===c}function b(t,e){return A(t)?t.value(e):t}function k(t,a){for(var c,y,x,w,d,g,E=[],M=0;M<t.length;M++){var m=t[M],A=m.type;if(A===e)"number"==typeof m.value&&m.value<0?E.push("("+m.value+")"):Array.isArray(m.value)?E.push("["+m.value.map(O).join(", ")+"]"):E.push(O(m.value));else if(A===s)y=E.pop(),c=E.pop(),w=m.value,a?"^"===w?E.push("Math.pow("+c+", "+y+")"):"and"===w?E.push("(!!"+c+" && !!"+y+")"):"or"===w?E.push("(!!"+c+" || !!"+y+")"):"||"===w?E.push("(function(a,b){ return Array.isArray(a) && Array.isArray(b) ? a.concat(b) : String(a) + String(b); }(("+c+"),("+y+")))"):"=="===w?E.push("("+c+" === "+y+")"):"!="===w?E.push("("+c+" !== "+y+")"):"["===w?E.push(c+"[("+y+") | 0]"):E.push("("+c+" "+w+" "+y+")"):"["===w?E.push(c+"["+y+"]"):E.push("("+c+" "+w+" "+y+")");else if(A===n){if(x=E.pop(),y=E.pop(),c=E.pop(),"?"!==(w=m.value))throw new Error("invalid Expression");E.push("("+c+" ? "+y+" : "+x+")")}else if(A===i||A===o)E.push(m.value);else if(A===r)c=E.pop(),"-"===(w=m.value)||"+"===w?E.push("("+w+c+")"):a?"not"===w?E.push("(!"+c+")"):"!"===w?E.push("fac("+c+")"):E.push(w+"("+c+")"):"!"===w?E.push("("+c+"!)"):E.push("("+w+" "+c+")");else if(A===p){for(g=m.value,d=[];g-- >0;)d.unshift(E.pop());w=E.pop(),E.push(w+"("+d.join(", ")+")")}else if(A===h){for(y=E.pop(),g=m.value,d=[];g-- >0;)d.unshift(E.pop());c=E.pop(),a?E.push("("+c+" = function("+d.join(", ")+") { return "+y+" })"):E.push("("+c+"("+d.join(", ")+") = "+y+")")}else if(A===f)c=E.pop(),E.push(c+"."+m.value);else if(A===v){for(g=m.value,d=[];g-- >0;)d.unshift(E.pop());E.push("["+d.join(", ")+"]")}else if(A===u)E.push("("+k(m.value,a)+")");else if(A!==l)throw new Error("invalid Expression")}return E.length>1&&(E=a?[E.join(",")]:[E.join(";")]),String(E[0])}function O(t){return"string"==typeof t?JSON.stringify(t).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"):t}function T(t,e){for(var r=0;r<t.length;r++)if(t[r]===e)return!0;return!1}function C(t,e,r){for(var s=!!(r=r||{}).withMembers,n=null,a=0;a<t.length;a++){var p=t[a];p.type===i||p.type===o?s||T(e,p.value)?null!==n?(T(e,n)||e.push(n),n=p.value):n=p.value:e.push(p.value):p.type===f&&s&&null!==n?n+="."+p.value:p.type===u?C(p.value,e,r):null!==n&&(T(e,n)||e.push(n),n=null)}null===n||T(e,n)||e.push(n)}function N(t,e){this.tokens=t,this.parser=e,this.unaryOps=e.unaryOps,this.binaryOps=e.binaryOps,this.ternaryOps=e.ternaryOps,this.functions=e.functions}y.prototype.toString=function(){switch(this.type){case e:case r:case s:case n:case i:case o:case l:case a:return this.value;case p:return"CALL "+this.value;case h:return"DEF "+this.value;case v:return"ARRAY "+this.value;case f:return"."+this.value;default:return"Invalid Instruction"}},N.prototype.simplify=function(t){return t=t||{},new N(g(this.tokens,this.unaryOps,this.binaryOps,this.ternaryOps,t),this.parser)},N.prototype.substitute=function(t,e){return e instanceof N||(e=this.parser.parse(String(e))),new N(E(this.tokens,t,e),this.parser)},N.prototype.evaluate=function(t){return t=t||{},M(this.tokens,this,t)},N.prototype.toString=function(){return k(this.tokens,!1)},N.prototype.symbols=function(t){t=t||{};var e=[];return C(this.tokens,e,t),e},N.prototype.variables=function(t){t=t||{};var e=[];C(this.tokens,e,t);var r=this.functions;return e.filter((function(t){return!(t in r)}))},N.prototype.toJSFunction=function(t,e){var r=this,s=new Function(t,"with(this.functions) with (this.ternaryOps) with (this.binaryOps) with (this.unaryOps) { return "+k(this.simplify(e).tokens,!0)+"; }");return function(){return s.apply(r,arguments)}};var S="TEOF",I="TOP",F="TFUNCOP",P="TNUMBER",L="TSTRING",R="TPAREN",j="TBRACKET",U="TCOMMA",_="TNAME",q="TSEMICOLON";function B(t,e,r){this.type=t,this.value=e,this.index=r}function V(t,e){this.pos=0,this.current=null,this.unaryOps=t.unaryOps,this.binaryOps=t.binaryOps,this.ternaryOps=t.ternaryOps,this.functions=t.functions,this.consts=t.consts,this.expression=e,this.savedPosition=0,this.savedCurrent=null,this.options=t.options,this.parser=t}B.prototype.toString=function(){return this.type+": "+this.value},V.prototype.newToken=function(t,e,r){return new B(t,e,null!=r?r:this.pos)},V.prototype.save=function(){this.savedPosition=this.pos,this.savedCurrent=this.current},V.prototype.restore=function(){this.pos=this.savedPosition,this.current=this.savedCurrent},V.prototype.next=function(){return this.pos>=this.expression.length?this.newToken(S,"EOF"):this.isWhitespace()||this.isComment()?this.next():this.isRadixInteger()||this.isNumber()||this.isOperator()||this.isString()||this.isParen()||this.isBracket()||this.isComma()||this.isSemicolon()||this.isNamedOp()||this.isFuncOp()||this.isConst()||this.isName()?this.current:void this.parseError('Unknown character "'+this.expression.charAt(this.pos)+'"')},V.prototype.isString=function(){var t=!1,e=this.pos,r=this.expression.charAt(e);if("'"===r||'"'===r)for(var s=this.expression.indexOf(r,e+1);s>=0&&this.pos<this.expression.length;){if(this.pos=s+1,"\\"!==this.expression.charAt(s-1)){var n=this.expression.substring(e+1,s);this.current=this.newToken(L,this.unescape(n),e),t=!0;break}s=this.expression.indexOf(r,s+1)}return t},V.prototype.isParen=function(){var t=this.expression.charAt(this.pos);return("("===t||")"===t)&&(this.current=this.newToken(R,t),this.pos++,!0)},V.prototype.isBracket=function(){var t=this.expression.charAt(this.pos);return!("["!==t&&"]"!==t||!this.isOperatorEnabled("["))&&(this.current=this.newToken(j,t),this.pos++,!0)},V.prototype.isComma=function(){return","===this.expression.charAt(this.pos)&&(this.current=this.newToken(U,","),this.pos++,!0)},V.prototype.isSemicolon=function(){return";"===this.expression.charAt(this.pos)&&(this.current=this.newToken(q,";"),this.pos++,!0)},V.prototype.isConst=function(){for(var t=this.pos,e=t;e<this.expression.length;e++){var r=this.expression.charAt(e);if(r.toUpperCase()===r.toLowerCase()&&(e===this.pos||"_"!==r&&"."!==r&&(r<"0"||r>"9")))break}if(e>t){var s=this.expression.substring(t,e);if(s in this.consts)return this.current=this.newToken(P,this.consts[s]),this.pos+=s.length,!0}return!1},V.prototype.isNamedOp=function(){for(var t=this.pos,e=t;e<this.expression.length;e++){var r=this.expression.charAt(e);if(r.toUpperCase()===r.toLowerCase()&&(e===this.pos||"_"!==r&&(r<"0"||r>"9")))break}if(e>t){var s=this.expression.substring(t,e);if(this.isOperatorEnabled(s)&&(s in this.binaryOps||s in this.unaryOps||s in this.ternaryOps))return this.current=this.newToken(I,s),this.pos+=s.length,!0}return!1},V.prototype.isFuncOp=function(){var t,e=this.expression.charAt(this.pos),r=this.pos+1,s=r;if("@"===e){for(;s<this.expression.length&&((e=this.expression.charAt(s)).toUpperCase()!==e.toLowerCase()||!(s===r||"_"!==e&&(e<"0"||e>"9")));s++);if(s>r&&(t=this.expression.substring(r,s))in this.functions)return this.current=this.newToken(F,t),this.pos=r+t.length,!0}return!1},V.prototype.isName=function(){for(var t=this.pos,e=t,r=!1;e<this.expression.length;e++){var s=this.expression.charAt(e);if(s.toUpperCase()===s.toLowerCase()){if(e===this.pos&&("$"===s||"_"===s)){"_"===s&&(r=!0);continue}if(e===this.pos||!r||"_"!==s&&(s<"0"||s>"9"))break}else r=!0}if(r){var n=this.expression.substring(t,e);return this.current=this.newToken(_,n),this.pos+=n.length,!0}return!1},V.prototype.isWhitespace=function(){for(var t=!1,e=this.expression.charAt(this.pos);!(" "!==e&&"\t"!==e&&"\n"!==e&&"\r"!==e||(t=!0,this.pos++,this.pos>=this.expression.length));)e=this.expression.charAt(this.pos);return t};var $=/^[0-9a-f]{4}$/i;function D(t,e,r){this.parser=t,this.tokens=e,this.current=null,this.nextToken=null,this.next(),this.savedCurrent=null,this.savedNextToken=null,this.allowMemberAccess=!1!==r.allowMemberAccess}V.prototype.unescape=function(t){var e=t.indexOf("\\");if(e<0)return t;for(var r=t.substring(0,e);e>=0;){var s=t.charAt(++e);switch(s){case"'":r+="'";break;case'"':r+='"';break;case"\\":r+="\\";break;case"/":r+="/";break;case"b":r+="\b";break;case"f":r+="\f";break;case"n":r+="\n";break;case"r":r+="\r";break;case"t":r+="\t";break;case"u":var n=t.substring(e+1,e+5);$.test(n)||this.parseError("Illegal escape sequence: \\u"+n),r+=String.fromCharCode(parseInt(n,16)),e+=4;break;default:throw this.parseError('Illegal escape sequence: "\\'+s+'"')}++e;var i=t.indexOf("\\",e);r+=t.substring(e,i<0?t.length:i),e=i}return r},V.prototype.isComment=function(){return"/"===this.expression.charAt(this.pos)&&"*"===this.expression.charAt(this.pos+1)&&(this.pos=this.expression.indexOf("*/",this.pos)+2,1===this.pos&&(this.pos=this.expression.length),!0)},V.prototype.isRadixInteger=function(){var t,e,r=this.pos;if(r>=this.expression.length-2||"0"!==this.expression.charAt(r))return!1;if(++r,"x"===this.expression.charAt(r))t=16,e=/^[0-9a-f]$/i,++r;else{if("b"!==this.expression.charAt(r))return!1;t=2,e=/^[01]$/i,++r}for(var s=!1,n=r;r<this.expression.length;){var i=this.expression.charAt(r);if(!e.test(i))break;r++,s=!0}return s&&(this.current=this.newToken(P,parseInt(this.expression.substring(n,r),t)),this.pos=r),s},V.prototype.isNumber=function(){for(var t,e=!1,r=this.pos,s=r,n=r,i=!1,o=!1;r<this.expression.length&&((t=this.expression.charAt(r))>="0"&&t<="9"||!i&&"."===t);)"."===t?i=!0:o=!0,r++,e=o;if(e&&(n=r),"e"===t||"E"===t){r++;for(var a=!0,p=!1;r<this.expression.length;){if(t=this.expression.charAt(r),!a||"+"!==t&&"-"!==t){if(!(t>="0"&&t<="9"))break;p=!0,a=!1}else a=!1;r++}p||(r=n)}return e?(this.current=this.newToken(P,parseFloat(this.expression.substring(s,r))),this.pos=r):this.pos=n,e},V.prototype.isOperator=function(){var t=this.pos,e=this.expression.charAt(this.pos);if("+"===e||"-"===e||"*"===e||"/"===e||"%"===e||"^"===e||"?"===e||":"===e||"."===e)this.current=this.newToken(I,e);else if("∙"===e||"•"===e)this.current=this.newToken(I,"*");else if(">"===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(I,">="),this.pos++):this.current=this.newToken(I,">");else if("<"===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(I,"<="),this.pos++):this.current=this.newToken(I,"<");else if("|"===e){if("|"!==this.expression.charAt(this.pos+1))return!1;this.current=this.newToken(I,"||"),this.pos++}else if("="===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(I,"=="),this.pos++):this.current=this.newToken(I,e);else{if("!"!==e)return!1;"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(I,"!="),this.pos++):this.current=this.newToken(I,e)}return this.pos++,!!this.isOperatorEnabled(this.current.value)||(this.pos=t,!1)},V.prototype.isOperatorEnabled=function(t){return this.parser.isOperatorEnabled(t)},V.prototype.getCoordinates=function(){var t,e=0,r=-1;do{e++,t=this.pos-r,r=this.expression.indexOf("\n",r+1)}while(r>=0&&r<this.pos);return{line:e,column:t}},V.prototype.parseError=function(t){var e=this.getCoordinates();throw new Error("parse error ["+e.line+":"+e.column+"]: "+t)},D.prototype.next=function(){return this.current=this.nextToken,this.nextToken=this.tokens.next()},D.prototype.tokenMatches=function(t,e){return void 0===e||(Array.isArray(e)?T(e,t.value):"function"==typeof e?e(t):t.value===e)},D.prototype.save=function(){this.savedCurrent=this.current,this.savedNextToken=this.nextToken,this.tokens.save()},D.prototype.restore=function(){this.tokens.restore(),this.current=this.savedCurrent,this.nextToken=this.savedNextToken},D.prototype.accept=function(t,e){return!(this.nextToken.type!==t||!this.tokenMatches(this.nextToken,e))&&(this.next(),!0)},D.prototype.expect=function(t,e){if(!this.accept(t,e)){var r=this.tokens.getCoordinates();throw new Error("parse error ["+r.line+":"+r.column+"]: Expected "+(e||t))}},D.prototype.parseAtom=function(t){var r=this.tokens.unaryOps;if(this.accept(_)||this.accept(I,(function(t){return t.value in r})))t.push(new y(i,this.current.value));else if(this.accept(P))t.push(new y(e,this.current.value));else if(this.accept(L))t.push(new y(e,this.current.value));else if(this.accept(R,"("))this.parseExpression(t),this.expect(R,")");else{if(!this.accept(j,"["))throw new Error("unexpected "+this.nextToken);if(this.accept(j,"]"))t.push(new y(v,0));else{var s=this.parseArrayList(t);t.push(new y(v,s))}}},D.prototype.parseExpression=function(t){var e=[];this.parseUntilEndStatement(t,e)||(this.parseVariableAssignmentExpression(e),this.parseUntilEndStatement(t,e)||this.pushExpression(t,e))},D.prototype.pushExpression=function(t,e){for(var r=0,s=e.length;r<s;r++)t.push(e[r])},D.prototype.parseUntilEndStatement=function(t,e){return!!this.accept(q)&&(!this.nextToken||this.nextToken.type===S||this.nextToken.type===R&&")"===this.nextToken.value||e.push(new y(l)),this.nextToken.type!==S&&this.parseExpression(e),t.push(new y(u,e)),!0)},D.prototype.parseArrayList=function(t){for(var e=0;!this.accept(j,"]");)for(this.parseExpression(t),++e;this.accept(U);)this.parseExpression(t),++e;return e},D.prototype.parseVariableAssignmentExpression=function(t){for(this.parseConditionalExpression(t);this.accept(I,"=");){var e=t.pop(),r=[],s=t.length-1;if(e.type!==p){if(e.type!==i&&e.type!==f)throw new Error("expected variable for assignment");this.parseVariableAssignmentExpression(r),t.push(new y(o,e.value)),t.push(new y(u,r)),t.push(w("="))}else{if(!this.tokens.isOperatorEnabled("()="))throw new Error("function definition is not permitted");for(var n=0,a=e.value+1;n<a;n++){var c=s-n;t[c].type===i&&(t[c]=new y(o,t[c].value))}this.parseVariableAssignmentExpression(r),t.push(new y(u,r)),t.push(new y(h,e.value))}}},D.prototype.parseConditionalExpression=function(t){for(this.parseOrExpression(t);this.accept(I,"?");){var e=[],r=[];this.parseConditionalExpression(e),this.expect(I,":"),this.parseConditionalExpression(r),t.push(new y(u,e)),t.push(new y(u,r)),t.push(d("?"))}},D.prototype.parseOrExpression=function(t){for(this.parseAndExpression(t);this.accept(I,"or");){var e=[];this.parseAndExpression(e),t.push(new y(u,e)),t.push(w("or"))}},D.prototype.parseAndExpression=function(t){for(this.parseComparison(t);this.accept(I,"and");){var e=[];this.parseComparison(e),t.push(new y(u,e)),t.push(w("and"))}};var G=["==","!=","<","<=",">=",">","in"];D.prototype.parseComparison=function(t){for(this.parseAddSub(t);this.accept(I,G);){var e=this.current;this.parseAddSub(t),t.push(w(e.value))}};var J=["+","-","||"];D.prototype.parseAddSub=function(t){for(this.parseTerm(t);this.accept(I,J);){var e=this.current;this.parseTerm(t),t.push(w(e.value))}};var W=["*","/","%"];function X(t,e){return Number(t)+Number(e)}function Y(t,e){return t-e}function K(t,e){return t*e}function z(t,e){return t/e}function H(t,e){return t%e}function Q(t,e){return Array.isArray(t)&&Array.isArray(e)?t.concat(e):""+t+e}function Z(t,e){return t===e}function tt(t,e){return t!==e}function et(t,e){return t>e}function rt(t,e){return t<e}function st(t,e){return t>=e}function nt(t,e){return t<=e}function it(t,e){return Boolean(t&&e)}function ot(t,e){return Boolean(t||e)}function at(t,e){return T(e,t)}function pt(t){return(Math.exp(t)-Math.exp(-t))/2}function ht(t){return(Math.exp(t)+Math.exp(-t))/2}function ut(t){return t===1/0?1:t===-1/0?-1:(Math.exp(t)-Math.exp(-t))/(Math.exp(t)+Math.exp(-t))}function ct(t){return t===-1/0?t:Math.log(t+Math.sqrt(t*t+1))}function ft(t){return Math.log(t+Math.sqrt(t*t-1))}function lt(t){return Math.log((1+t)/(1-t))/2}function vt(t){return Math.log(t)*Math.LOG10E}function yt(t){return-t}function xt(t){return!t}function wt(t){return t<0?Math.ceil(t):Math.floor(t)}function dt(t){return Math.random()*(t||1)}function gt(t){return mt(t+1)}D.prototype.parseTerm=function(t){for(this.parseFactor(t);this.accept(I,W);){var e=this.current;this.parseFactor(t),t.push(w(e.value))}},D.prototype.parseFactor=function(t){var e=this.tokens.unaryOps;if(this.save(),this.accept(I,(function(t){return t.value in e}))){if("-"!==this.current.value&&"+"!==this.current.value){if(this.nextToken.type===R&&"("===this.nextToken.value)return this.restore(),void this.parseExponential(t);if(this.nextToken.type===q||this.nextToken.type===U||this.nextToken.type===S||this.nextToken.type===R&&")"===this.nextToken.value)return this.restore(),void this.parseAtom(t)}var r=this.current;this.parseFactor(t),t.push(x(r.value))}else this.parseExponential(t)},D.prototype.parseExponential=function(t){for(this.parsePostfixExpression(t);this.accept(I,"^");)this.parseFactor(t),t.push(w("^"))},D.prototype.parsePostfixExpression=function(t){for(this.parseFunctionOperator(t);this.accept(I,"!");)t.push(x("!"))},D.prototype.parseFunctionOperator=function(t){var e,r=this.tokens.functions;function s(t){return t.value in r}for(this.parseFunctionCall(t);this.accept(F,s);)e=this.current,this.parseFactor(t),t.push(new y(a,e.value))},D.prototype.parseFunctionCall=function(t){var e=this.tokens.unaryOps;if(this.accept(I,(function(t){return t.value in e}))){var r=this.current;this.parseAtom(t),t.push(x(r.value))}else for(this.parseMemberExpression(t);this.accept(R,"(");)if(this.accept(R,")"))t.push(new y(p,0));else{var s=this.parseArgumentList(t);t.push(new y(p,s))}},D.prototype.parseArgumentList=function(t){for(var e=0;!this.accept(R,")");)for(this.parseExpression(t),++e;this.accept(U);)this.parseExpression(t),++e;return e},D.prototype.parseMemberExpression=function(t){for(this.parseAtom(t);this.accept(I,".")||this.accept(j,"[");){var e=this.current;if("."===e.value){if(!this.allowMemberAccess)throw new Error('unexpected ".", member access is not permitted');this.expect(_),t.push(new y(f,this.current.value))}else{if("["!==e.value)throw new Error("unexpected symbol: "+e.value);if(!this.tokens.isOperatorEnabled("["))throw new Error('unexpected "[]", arrays are disabled');this.parseExpression(t),this.expect(j,"]"),t.push(w("["))}}};var Et=4.7421875,Mt=[.9999999999999971,57.15623566586292,-59.59796035547549,14.136097974741746,-.4919138160976202,3399464998481189e-20,4652362892704858e-20,-9837447530487956e-20,.0001580887032249125,-.00021026444172410488,.00021743961811521265,-.0001643181065367639,8441822398385275e-20,-26190838401581408e-21,36899182659531625e-22];function mt(t){var e,r;if(function(t){return isFinite(t)&&t===Math.round(t)}(t)){if(t<=0)return isFinite(t)?1/0:NaN;if(t>171)return 1/0;for(var s=t-2,n=t-1;s>1;)n*=s,s--;return 0===n&&(n=1),n}if(t<.5)return Math.PI/(Math.sin(Math.PI*t)*mt(1-t));if(t>=171.35)return 1/0;if(t>85){var i=t*t,o=i*t,a=o*t,p=a*t;return Math.sqrt(2*Math.PI/t)*Math.pow(t/Math.E,t)*(1+1/(12*t)+1/(288*i)-139/(51840*o)-571/(2488320*a)+163879/(209018880*p)+5246819/(75246796800*p*t))}--t,r=Mt[0];for(var h=1;h<Mt.length;++h)r+=Mt[h]/(t+h);return e=t+Et+.5,Math.sqrt(2*Math.PI)*Math.pow(e,t+.5)*Math.exp(-e)*r}function At(t){return Array.isArray(t)?t.length:String(t).length}function bt(){for(var t=0,e=0,r=0;r<arguments.length;r++){var s,n=Math.abs(arguments[r]);e<n?(t=t*(s=e/n)*s+1,e=n):t+=n>0?(s=n/e)*s:n}return e===1/0?1/0:e*Math.sqrt(t)}function kt(t,e,r){return t?e:r}function Ot(t,e){return void 0===e||0==+e?Math.round(t):(t=+t,e=-+e,isNaN(t)||"number"!=typeof e||e%1!=0?NaN:(t=t.toString().split("e"),+((t=(t=Math.round(+(t[0]+"e"+(t[1]?+t[1]-e:-e)))).toString().split("e"))[0]+"e"+(t[1]?+t[1]+e:e))))}function Tt(t,e,r){return r&&(r[t]=e),e}function Ct(t,e){return t[0|e]}function Nt(t){return 1===arguments.length&&Array.isArray(t)?Math.max.apply(Math,t):Math.max.apply(Math,arguments)}function St(t){return 1===arguments.length&&Array.isArray(t)?Math.min.apply(Math,t):Math.min.apply(Math,arguments)}function It(t,e){if("function"!=typeof t)throw new Error("First argument to map is not a function");if(!Array.isArray(e))throw new Error("Second argument to map is not an array");return e.map((function(e,r){return t(e,r)}))}function Ft(t,e,r){if("function"!=typeof t)throw new Error("First argument to fold is not a function");if(!Array.isArray(r))throw new Error("Second argument to fold is not an array");return r.reduce((function(e,r,s){return t(e,r,s)}),e)}function Pt(t,e){if("function"!=typeof t)throw new Error("First argument to filter is not a function");if(!Array.isArray(e))throw new Error("Second argument to filter is not an array");return e.filter((function(e,r){return t(e,r)}))}function Lt(t,e){if(!Array.isArray(e)&&"string"!=typeof e)throw new Error("Second argument to indexOf is not a string or array");return e.indexOf(t)}function Rt(t,e){if(!Array.isArray(e))throw new Error("Second argument to join is not an array");return e.join(t)}function jt(t){return(t>0)-(t<0)||+t}var Ut=1/3;function _t(t){return t<0?-Math.pow(-t,Ut):Math.pow(t,Ut)}function qt(t){return Math.exp(t)-1}function Bt(t){return Math.log(1+t)}function Vt(t){return Math.log(t)/Math.LN2}function $t(t){if(!Array.isArray(t))throw new Error("Sum argument is not an array");return t.reduce((function(t,e){return t+Number(e)}),0)}function Dt(t){this.options=t||{},this.unaryOps={sin:Math.sin,cos:Math.cos,tan:Math.tan,asin:Math.asin,acos:Math.acos,atan:Math.atan,sinh:Math.sinh||pt,cosh:Math.cosh||ht,tanh:Math.tanh||ut,asinh:Math.asinh||ct,acosh:Math.acosh||ft,atanh:Math.atanh||lt,sqrt:Math.sqrt,cbrt:Math.cbrt||_t,log:Math.log,log2:Math.log2||Vt,ln:Math.log,lg:Math.log10||vt,log10:Math.log10||vt,expm1:Math.expm1||qt,log1p:Math.log1p||Bt,abs:Math.abs,ceil:Math.ceil,floor:Math.floor,round:Math.round,trunc:Math.trunc||wt,"-":yt,"+":Number,exp:Math.exp,not:xt,length:At,"!":gt,sign:Math.sign||jt},this.binaryOps={"+":X,"-":Y,"*":K,"/":z,"%":H,"^":Math.pow,"||":Q,"==":Z,"!=":tt,">":et,"<":rt,">=":st,"<=":nt,and:it,or:ot,in:at,"=":Tt,"[":Ct},this.ternaryOps={"?":kt},this.functions={random:dt,fac:gt,min:St,max:Nt,hypot:Math.hypot||bt,pyt:Math.hypot||bt,pow:Math.pow,atan2:Math.atan2,if:kt,gamma:mt,roundTo:Ot,map:It,fold:Ft,filter:Pt,indexOf:Lt,join:Rt,sum:$t},this.consts={E:Math.E,PI:Math.PI,true:!0,false:!1}}Dt.prototype.parse=function(t){var e=[],r=new D(this,new V(this,t),{allowMemberAccess:this.options.allowMemberAccess});return r.parseExpression(e),r.expect(S,"EOF"),new N(e,this)},Dt.prototype.evaluate=function(t,e){return this.parse(t).evaluate(e)};var Gt=new Dt;Dt.parse=function(t){return Gt.parse(t)},Dt.evaluate=function(t,e){return Gt.parse(t).evaluate(e)};var Jt={"+":"add","-":"subtract","*":"multiply","/":"divide","%":"remainder","^":"power","!":"factorial","<":"comparison",">":"comparison","<=":"comparison",">=":"comparison","==":"comparison","!=":"comparison","||":"concatenate",and:"logical",or:"logical",not:"logical","?":"conditional",":":"conditional","=":"assignment","[":"array","()=":"fndef"};Dt.prototype.isOperatorEnabled=function(t){var e=function(t){return Jt.hasOwnProperty(t)?Jt[t]:t}(t),r=this.options.operators||{};return!(e in r)||!!r[e]};
/*!
Based on ndef.parser, by Raphael Graf(r@undefined.ch)
http://www.undefined.ch/mparser/index.html
Ported to JavaScript and modified by Matthew Crumley (email@matthewcrumley.com, http://silentmatt.com/)
You are free to use and modify this code in anyway you find useful. Please leave this comment in the code
to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code,
but don't feel like you have to let me know or ask permission.
*/
var Wt={Parser:Dt,Expression:N};t.Expression=N,t.Parser=Dt,t.default=Wt,Object.defineProperty(t,"__esModule",{value:!0})}));

22

package.json
{
"name": "@oat-sa/expr-eval",
"version": "1.3.2",
"version": "2.0.0",
"description": "Mathematical expression evaluator",
"main": "dist/bundle.js",
"module": "dist/index.mjs",
"typings": "parser.d.ts",

@@ -12,19 +13,20 @@ "directories": {

"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-semistandard": "^13.0.0",
"eslint-config-standard": "^12.0.0",
"eslint": "^6.3.0",
"eslint-config-semistandard": "^15.0.0",
"eslint-config-standard": "^13.0.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-node": "^9.2.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^4.1.0",
"istanbul": "^0.4.5",
"mocha": "^10.0.0",
"rollup": "^0.63.5",
"rollup-plugin-uglify": "^3.0.0"
"nyc": "^14.1.1",
"rollup": "^1.20.3",
"rollup-plugin-terser": "^7.0.2"
},
"scripts": {
"test": "npm run build && mocha",
"coverage": "npm run build && istanbul cover _mocha",
"coverage": "npm run build && nyc --reporter=lcov --reporter=text-summary mocha",
"lint": "eslint index.js src test rollup.config.js rollup-min.config.js",
"build": "rollup -c rollup.config.js && rollup -c rollup-min.config.js",
"watch": "rollup -c rollup.config.js -w",
"build": "rollup -c rollup.config.js && rollup -c rollup-min.config.js && rollup -c rollup-esm.config.js",
"prepublish": "npm run build"

@@ -31,0 +33,0 @@ },

@@ -48,3 +48,13 @@ export type Value = number

length?: boolean,
in?: boolean
in?: boolean,
random?: boolean,
min?: boolean,
max?: boolean,
assignment?: boolean,
fndef?: boolean,
cbrt?: boolean,
expm1?: boolean,
log1p?: boolean,
sign?: boolean,
log2?: boolean
};

@@ -55,3 +65,5 @@ }

constructor(options?: ParserOptions);
unaryOps: any;
functions: any;
consts: any;
parse(expression: string): Expression;

@@ -69,3 +81,3 @@ evaluate(expression: string, values?: Value): number;

variables(options?: { withMembers?: boolean }): string[];
toJSFunction(params: string, values?: Value): (...args: any[]) => number;
toJSFunction(params: string | string[], values?: Value): (...args: any[]) => number;
}

@@ -26,7 +26,7 @@ JavaScript Expression Evaluator

-------------------------------------
```js
const Parser = require('expr-eval').Parser;
var Parser = require('expr-eval').Parser;
var parser = new Parser();
var expr = parser.parse('2 * x + 1');
const parser = new Parser();
let expr = parser.parse('2 * x + 1');
console.log(expr.evaluate({ x: 3 })); // 7

@@ -36,3 +36,3 @@

Parser.evaluate('6 * x', { x: 7 }) // 42
```
Documentation

@@ -57,4 +57,5 @@ -------------------------------------

- [Unary operators](#unary-operators)
- [Array literals](#array-literals)
- [Pre-defined functions](#pre-defined-functions)
- [Custom functions](#custom-functions)
- [Custom JavaScript functions](#custom-javascript-functions)
- [Constants](#constants)

@@ -74,4 +75,4 @@

For example, the following will create a `Parser` that does not allow comparison or logical operators, but does allow `in`:
var parser = new Parser({
```js
const parser = new Parser({
operators: {

@@ -93,7 +94,8 @@ // These default to true, but are included to be explicit

// The in operator is disabled by default in the current version
'in': true
// Disable 'in' and = operators
'in': false,
assignment: false
}
});
```
#### parse(expression: string)

@@ -128,3 +130,3 @@

exception.
```js
js> expr = Parser.parse("2 ^ x");

@@ -134,3 +136,3 @@ (2^x)

8
```
#### substitute(variable: string, expression: Expression | string | number)

@@ -141,3 +143,3 @@

or number, it will be parsed into an `Expression`.
```js
js> expr = Parser.parse("2 * x + 1");

@@ -149,3 +151,3 @@ ((2*x)+1)

25
```
#### simplify(variables: object)

@@ -164,3 +166,3 @@

replaced with "8", resulting in `((8*x)+1)`.
```js
js> expr = Parser.parse("x * (y * atan(1))").simplify({ y: 4 });

@@ -170,7 +172,7 @@ (x*3.141592653589793)

6.283185307179586
```
#### variables(options?: object)
Get an array of the unbound variables in the expression.
```js
js> expr = Parser.parse("x * (y * atan(1))");

@@ -182,3 +184,3 @@ (x*(y*atan(1)))

x
```
By default, `variables` will return "top-level" objects, so for example, `Parser.parse(x.y.z).variables()` returns `['x']`. If you want to get the whole chain of object members, you can call it with `{ withMembers: true }`. So `Parser.parse(x.y.z).variables({ withMembers: true })` would return `['x.y.z']`.

@@ -190,3 +192,3 @@

expression.
```js
js> expr = Parser.parse("min(x, y, z)");

@@ -198,3 +200,3 @@ (min(x, y, z))

min,x
```
Like `variables`, `symbols` accepts an option argument `{ withMembers: true }` to include object members.

@@ -215,3 +217,3 @@

simplified with variables bound to the supplied values.
```js
js> expr = Parser.parse("x + y + z");

@@ -227,3 +229,3 @@ ((x + y) + z)

105
```
### Expression Syntax ###

@@ -240,3 +242,3 @@

(...) | None | Grouping
f(), x.y | Left | Function call, property access
f(), x.y, a[i] | Left | Function call, property access, array indexing
! | Left | Factorial

@@ -246,18 +248,18 @@ ^ | Right | Exponentiation

\*, /, % | Left | Multiplication, division, remainder
+, -, \|\| | Left | Addition, subtraction, concatenation
==, !=, >=, <=, >, <, in | Left | Equals, not equals, etc. "in" means "is the left operand included in the right array operand?" (disabled by default)
+, -, \|\| | Left | Addition, subtraction, array/list concatenation
==, !=, >=, <=, >, <, in | Left | Equals, not equals, etc. "in" means "is the left operand included in the right array operand?"
and | Left | Logical AND
or | Left | Logical OR
x ? y : z | Right | Ternary conditional (if x then y else z)
The `in` operator is disabled by default in the current version. To use it,
construct a `Parser` instance with `operators.in` set to `true`. For example:
var parser = new Parser({
= | Right | Variable assignment
; | Left | Expression separator
```js
const parser = new Parser({
operators: {
'in': true
'in': true,
'assignment': true
}
});
// Now parser supports 'x in array' expressions
// Now parser supports 'x in array' and 'y = 2*x' expressions
```
#### Unary operators

@@ -280,3 +282,3 @@

x! | Factorial (x * (x-1) * (x-2) * … * 2 * 1). gamma(x + 1) for non-integers.
abs x | Absolute value (magnatude) of x
abs x | Absolute value (magnitude) of x
acos x | Arc cosine of x (in radians)

@@ -288,2 +290,3 @@ acosh x | Hyperbolic arc cosine of x (in radians)

atanh x | Hyperbolic arc tangent of x (in radians)
cbrt x | Cube root of x
ceil x | Ceiling of x — the smallest integer that’s >= x

@@ -293,9 +296,13 @@ cos x | Cosine of x (x is in radians)

exp x | e^x (exponential/antilogarithm function with base e)
expm1 x | e^x - 1
floor x | Floor of x — the largest integer that’s <= x
length x | String length of x
length x | String or array length of x
ln x | Natural logarithm of x
log x | Natural logarithm of x (synonym for ln, not base-10)
log10 x | Base-10 logarithm of x
log2 x | Base-2 logarithm of x
log1p x | Natural logarithm of (1 + x)
not x | Logical NOT operator
round x | X, rounded to the nearest integer, using "gradeschool rounding"
round x | X, rounded to the nearest integer, using "grade-school rounding"
sign x | Sign of x (-1, 0, or 1 for negative, zero, or positive respectively)
sin x | Sine of x (x is in radians)

@@ -314,21 +321,42 @@ sinh x | Hyperbolic sine of x (x is in radians)

Function | Description
:----------- | :----------
random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.
fac(n) | n! (factorial of n: "n * (n-1) * (n-2) * … * 2 * 1") Deprecated. Use the ! operator instead.
min(a,b,…) | Get the smallest (minimum) number in the list
max(a,b,…) | Get the largest (maximum) number in the list
hypot(a,b) | Hypotenuse, i.e. the square root of the sum of squares of its arguments.
pyt(a, b) | Alias for hypot
pow(x, y) | Equivalent to x^y. For consistency with JavaScript's Math object.
atan2(y, x) | Arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians.
if(c, a, b) | Function form of c ? a : b
roundTo(x, n) | Rounds x to n places after the decimal point.
Function | Description
:------------ | :----------
random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.
fac(n) | n! (factorial of n: "n * (n-1) * (n-2) * … * 2 * 1") Deprecated. Use the ! operator instead.
min(a,b,…) | Get the smallest (minimum) number in the list.
max(a,b,…) | Get the largest (maximum) number in the list.
hypot(a,b) | Hypotenuse, i.e. the square root of the sum of squares of its arguments.
pyt(a, b) | Alias for hypot.
pow(x, y) | Equivalent to x^y. For consistency with JavaScript's Math object.
atan2(y, x) | Arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians.
roundTo(x, n) | Rounds x to n places after the decimal point.
map(f, a) | Array map: Pass each element of `a` the function `f`, and return an array of the results.
fold(f, y, a) | Array fold: Fold/reduce array `a` into a single value, `y` by setting `y = f(y, x, index)` for each element `x` of the array.
filter(f, a) | Array filter: Return an array containing only the values from `a` where `f(x, index)` is `true`.
indexOf(x, a) | Return the first index of string or array `a` matching the value `x`, or `-1` if not found.
join(sep, a) | Concatenate the elements of `a`, separated by `sep`.
if(c, a, b) | Function form of c ? a : b. Note: This always evaluates both `a` and `b`, regardless of whether `c` is `true` or not. Use `c ? a : b` instead if there are side effects, or if evaluating the branches could be expensive.
#### Custom functions
#### Array literals
Arrays can be created by including the elements inside square `[]` brackets, separated by commas. For example:
[ 1, 2, 3, 2+2, 10/2, 3! ]
#### Function definitions
You can define functions using the syntax `name(params) = expression`. When it's evaluated, the name will be added to the passed in scope as a function. You can call it later in the expression, or make it available to other expressions by re-using the same scope object. Functions can support multiple parameters, separated by commas.
Examples:
```js
square(x) = x*x
add(a, b) = a + b
factorial(x) = x < 2 ? 1 : x * factorial(x - 1)
```
#### Custom JavaScript functions
If you need additional functions that aren't supported out of the box, you can easily add them in your own code. Instances of the `Parser` class have a property called `functions` that's simply an object with all the functions that are in scope. You can add, replace, or delete any of the properties to customize what's available in the expressions. For example:
```js
const parser = new Parser();
var parser = new Parser();
// Add a new function

@@ -338,9 +366,9 @@ parser.functions.customAddFunction = function (arg1, arg2) {

};
// Remove the factorial function
delete parser.functions.fac;
parser.evaluate('customAddFunction(2, 4) == 6'); // true
//parser.evaluate('fac(3)'); // This will fail
```
#### Constants

@@ -360,14 +388,14 @@

constants available to your expressions. For example:
var parser = new Parser();
```js
const parser = new Parser();
parser.consts.R = 1.234;
console.log(parser.parse('A+B/R').toString()); // ((A + B) / 1.234)
```
To disable the pre-defined constants, you can replace or delete `parser.consts`:
var parser = new Parser();
```js
const parser = new Parser();
parser.consts = {};
```
### Tests ###

@@ -374,0 +402,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc