Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fparser

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fparser - npm Package Compare versions

Comparing version 2.0.2 to 2.1.0

315

dist/fparser-dev.js

@@ -10,3 +10,3 @@ (function webpackUniversalModuleDefinition(root, factory) {

root["Formula"] = factory();
})(this, function() {
})(this, () => {
return /******/ (() => { // webpackBootstrap

@@ -21,5 +21,3 @@ /******/ var __webpack_modules__ = ({

var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
(function (global, factory) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) {
if (true) {

@@ -38,47 +36,29 @@ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),

_exports.default = void 0;
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
* JS Formula Parser
* -------------------
* (c) 2012-2021 Alexander Schenkel, alex@alexi.ch
* (c) 2012-2023 Alexander Schenkel, alex@alexi.ch
*

@@ -112,4 +92,3 @@ * JS Formula Parser takes a string, parses its mathmatical formula

};
var Formula = /*#__PURE__*/function () {
var Formula = _exports.default = /*#__PURE__*/function () {
/**

@@ -129,14 +108,12 @@ * Creates a new Formula instance

var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Formula);
this.formulaExpression = null;
this.options = Object.assign({
this.options = _objectSpread(_objectSpread({}, {
memoization: false
}, options);
}), options);
this._variables = [];
this._memory = {};
this.setFormula(fStr);
return this;
}
/**

@@ -149,4 +126,2 @@ * Re-sets the given String and parses it to a formula expression. Can be used after initialization,

*/
_createClass(Formula, [{

@@ -162,5 +137,5 @@ key: "setFormula",

}
return this;
}
/**

@@ -170,3 +145,2 @@ * Enable memoization: An expression is only evaluated once for the same input.

*/
}, {

@@ -177,6 +151,6 @@ key: "enableMemoization",

}
/**
* Disable in-memory memoization: each call to evaluate() is executed from scratch.
*/
}, {

@@ -188,2 +162,3 @@ key: "disableMemoization",

}
/**

@@ -194,3 +169,2 @@ * Splits the given string by ',', makes sure the ',' is not within

*/
}, {

@@ -201,12 +175,9 @@ key: "splitFunctionParams",

var pCount = 0,
paramStr = '';
paramStr = '';
var params = [];
var _iterator = _createForOfIteratorHelper(toSplit.split('')),
_step;
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var chr = _step.value;
if (chr === ',' && pCount === 0) {

@@ -222,3 +193,2 @@ // Found function param, save 'em

paramStr += chr;
if (pCount < 0) {

@@ -236,13 +206,11 @@ throw new Error('ERROR: Too many closing parentheses!');

}
if (pCount !== 0) {
throw new Error('ERROR: Too many opening parentheses!');
}
if (paramStr.length > 0) {
params.push(paramStr);
}
return params;
}
/**

@@ -252,8 +220,7 @@ * Cleans the input string from unnecessary whitespace,

*/
}, {
key: "cleanupInputString",
value: function cleanupInputString(s) {
s = s.replace(/[\s]+/g, ''); // surround known math constants with [], to parse them as named variables [xxx]:
s = s.replace(/\s+/g, '');
// surround known math constants with [], to parse them as named variables [xxx]:
Object.keys(MATH_CONSTANTS).forEach(function (c) {

@@ -264,2 +231,3 @@ s = s.replace(new RegExp("\\b".concat(c, "\\b"), 'g'), "[".concat(c, "]"));

}
/**

@@ -305,3 +273,2 @@ * Parses the given formula string by using a state machine into a single Expression object,

*/
}, {

@@ -311,6 +278,7 @@ key: "parse",

// clean the input string first. spaces, math constant replacements etc.:
str = this.cleanupInputString(str); // start recursive call to parse:
str = this.cleanupInputString(str);
// start recursive call to parse:
return this._do_parse(str);
}
/**

@@ -321,3 +289,2 @@ * @see parse(): this is the recursive parse function, without the clean string part.

*/
}, {

@@ -327,12 +294,10 @@ key: "_do_parse",

var _this = this;
var lastChar = str.length - 1,
act = 0,
state = 0,
expressions = [],
char = '',
tmp = '',
funcName = null,
pCount = 0;
act = 0,
state = 0,
expressions = [],
char = '',
tmp = '',
funcName = null,
pCount = 0;
while (act <= lastChar) {

@@ -343,3 +308,2 @@ switch (state) {

char = str.charAt(act);
if (char.match(/[0-9.]/)) {

@@ -361,8 +325,7 @@ // found the beginning of a number, change state to "within-number"

}
} // Found a simple operator, store as expression:
}
// Found a simple operator, store as expression:
if (act === lastChar || this.isOperatorExpr(expressions[expressions.length - 1])) {
state = -1; // invalid to end with an operator, or have 2 operators in conjunction
break;

@@ -394,3 +357,2 @@ } else {

}
expressions.push(new VariableExpression(char));

@@ -402,12 +364,8 @@ this.registerVariable(char);

}
break;
case 'within-nr':
char = str.charAt(act);
if (char.match(/[0-9.]/)) {
//Still within number, store and continue
tmp += char;
if (act === lastChar) {

@@ -423,3 +381,2 @@ expressions.push(new ValueExpression(tmp));

}
expressions.push(new ValueExpression(tmp));

@@ -430,8 +387,5 @@ tmp = '';

}
break;
case 'within-func':
char = str.charAt(act);
if (char.match(/[a-zA-Z0-9_]/)) {

@@ -447,8 +401,5 @@ tmp += char;

}
break;
case 'within-named-var':
char = str.charAt(act);
if (char === ']') {

@@ -460,3 +411,3 @@ // end of named var, create expression:

state = 0;
} else if (char.match(/[a-zA-Z0-9_]/)) {
} else if (char.match(/[a-zA-Z0-9_.]/)) {
tmp += char;

@@ -466,9 +417,6 @@ } else {

}
break;
case 'within-parentheses':
case 'within-func-parentheses':
char = str.charAt(act);
if (char === ')') {

@@ -489,3 +437,2 @@ //Check if this is the matching closing parenthesis.If not, just read ahead.

}
state = 0;

@@ -504,15 +451,12 @@ } else {

}
break;
}
act++;
}
if (state !== 0) {
throw new Error('Could not parse formula: Syntax error.');
}
return this.buildExpressionTree(expressions);
}
/**

@@ -527,3 +471,2 @@ * @see parse(): Builds an expression tree from the given expression array.

*/
}, {

@@ -535,11 +478,8 @@ key: "buildExpressionTree",

}
var exprCopy = _toConsumableArray(expressions);
var idx = 0;
var expr = null; // Replace all Power expressions with a partial tree:
var expr = null;
// Replace all Power expressions with a partial tree:
while (idx < exprCopy.length) {
expr = exprCopy[idx];
if (expr instanceof PowerExpression) {

@@ -549,3 +489,2 @@ if (idx === 0 || idx === exprCopy.length - 1) {

}
expr.base = exprCopy[idx - 1];

@@ -558,11 +497,9 @@ expr.exponent = exprCopy[idx + 1];

}
} // Replace all Mult/Div expressions with a partial tree:
}
// Replace all Mult/Div expressions with a partial tree:
idx = 0;
expr = null;
while (idx < exprCopy.length) {
expr = exprCopy[idx];
if (expr instanceof MultDivExpression) {

@@ -572,3 +509,2 @@ if (idx === 0 || idx === exprCopy.length - 1) {

}
expr.left = exprCopy[idx - 1];

@@ -581,11 +517,9 @@ expr.right = exprCopy[idx + 1];

}
} // Replace all Plus/Minus expressions with a partial tree:
}
// Replace all Plus/Minus expressions with a partial tree:
idx = 0;
expr = null;
while (idx < exprCopy.length) {
expr = exprCopy[idx];
if (expr instanceof PlusMinusExpression) {

@@ -595,3 +529,2 @@ if (idx === 0 || idx === exprCopy.length - 1) {

}
expr.left = exprCopy[idx - 1];

@@ -605,7 +538,5 @@ expr.right = exprCopy[idx + 1];

}
if (exprCopy.length !== 1) {
throw new Error('Could not parse formula: incorrect syntax?');
}
return exprCopy[0];

@@ -616,3 +547,3 @@ }

value: function isOperator(char) {
return typeof char === 'string' && char.match(/[\+\-\*\/\^]/);
return typeof char === 'string' && char.match(/[+\-*/^]/);
}

@@ -636,2 +567,3 @@ }, {

}
/**

@@ -648,3 +580,2 @@ * Evaluates a Formula by delivering values for the Formula's variables.

*/
}, {

@@ -654,3 +585,2 @@ key: "evaluate",

var _this2 = this;
// resolve multiple value objects recursively:

@@ -662,12 +592,8 @@ if (valueObj instanceof Array) {

}
var expr = this.getExpression();
if (!(expr instanceof Expression)) {
throw new Error('No expression set: Did you init the object with a Formula?');
}
if (this.options.memoization) {
var res = this.resultFromMemory(valueObj);
if (res !== null) {

@@ -681,3 +607,2 @@ return res;

}
return expr.evaluate(_objectSpread(_objectSpread({}, MATH_CONSTANTS), valueObj));

@@ -695,3 +620,2 @@ }

var res = this._memory[key];
if (res !== undefined) {

@@ -726,8 +650,4 @@ return res;

}]);
return Formula;
}();
_exports.default = Formula;
var Expression = /*#__PURE__*/function () {

@@ -737,3 +657,2 @@ function Expression() {

}
_createClass(Expression, [{

@@ -755,42 +674,29 @@ key: "evaluate",

var right = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (operator === '^') {
return new PowerExpression(operator, left, right);
}
if (operator === '*' || operator === '/') {
return new MultDivExpression(operator, left, right);
}
if (operator === '+' || operator === '-') {
return new PlusMinusExpression(operator, left, right);
}
throw new Error("Unknown operator: ".concat(operator));
}
}]);
return Expression;
}();
var BracketExpression = /*#__PURE__*/function (_Expression) {
_inherits(BracketExpression, _Expression);
var _super = _createSuper(BracketExpression);
function BracketExpression(expr) {
var _this3;
_classCallCheck(this, BracketExpression);
_this3 = _super.call(this);
_this3.innerExpression = expr;
if (!(_this3.innerExpression instanceof Expression)) {
throw new Error('No inner expression given for bracket expression');
}
return _this3;
}
_createClass(BracketExpression, [{

@@ -808,26 +714,17 @@ key: "evaluate",

}]);
return BracketExpression;
}(Expression);
var ValueExpression = /*#__PURE__*/function (_Expression2) {
_inherits(ValueExpression, _Expression2);
var _super2 = _createSuper(ValueExpression);
function ValueExpression(value) {
var _this4;
_classCallCheck(this, ValueExpression);
_this4 = _super2.call(this);
_this4.value = Number(value);
if (isNaN(_this4.value)) {
throw new Error('Cannot parse number: ' + value);
}
return _this4;
}
_createClass(ValueExpression, [{

@@ -845,25 +742,16 @@ key: "evaluate",

}]);
return ValueExpression;
}(Expression);
var PlusMinusExpression = /*#__PURE__*/function (_Expression3) {
_inherits(PlusMinusExpression, _Expression3);
var _super3 = _createSuper(PlusMinusExpression);
function PlusMinusExpression(operator) {
var _this5;
var left = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var right = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
_classCallCheck(this, PlusMinusExpression);
_this5 = _super3.call(this);
if (!['+', '-'].includes(operator)) {
throw new Error("Operator not allowed in Plus/Minus expression: ".concat(operator));
}
_this5.operator = operator;

@@ -874,3 +762,2 @@ _this5.left = left;

}
_createClass(PlusMinusExpression, [{

@@ -880,11 +767,8 @@ key: "evaluate",

var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this.operator === '+') {
return this.left.evaluate(params) + this.right.evaluate(params);
}
if (this.operator === '-') {
return this.left.evaluate(params) - this.right.evaluate(params);
}
throw new Error('Unknown operator for PlusMinus expression');

@@ -898,25 +782,16 @@ }

}]);
return PlusMinusExpression;
}(Expression);
var MultDivExpression = /*#__PURE__*/function (_Expression4) {
_inherits(MultDivExpression, _Expression4);
var _super4 = _createSuper(MultDivExpression);
function MultDivExpression(operator) {
var _this6;
var left = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var right = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
_classCallCheck(this, MultDivExpression);
_this6 = _super4.call(this);
if (!['*', '/'].includes(operator)) {
throw new Error("Operator not allowed in Multiply/Division expression: ".concat(operator));
}
_this6.operator = operator;

@@ -927,3 +802,2 @@ _this6.left = left;

}
_createClass(MultDivExpression, [{

@@ -933,11 +807,8 @@ key: "evaluate",

var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this.operator === '*') {
return this.left.evaluate(params) * this.right.evaluate(params);
}
if (this.operator === '/') {
return this.left.evaluate(params) / this.right.evaluate(params);
}
throw new Error('Unknown operator for MultDiv expression');

@@ -951,19 +822,12 @@ }

}]);
return MultDivExpression;
}(Expression);
var PowerExpression = /*#__PURE__*/function (_Expression5) {
_inherits(PowerExpression, _Expression5);
var _super5 = _createSuper(PowerExpression);
function PowerExpression() {
var _this7;
var base = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var exponent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
_classCallCheck(this, PowerExpression);
_this7 = _super5.call(this);

@@ -974,3 +838,2 @@ _this7.base = base;

}
_createClass(PowerExpression, [{

@@ -988,18 +851,11 @@ key: "evaluate",

}]);
return PowerExpression;
}(Expression);
var FunctionExpression = /*#__PURE__*/function (_Expression6) {
_inherits(FunctionExpression, _Expression6);
var _super6 = _createSuper(FunctionExpression);
function FunctionExpression(fn, argumentExpressions) {
var _this8;
var formulaObject = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
_classCallCheck(this, FunctionExpression);
_this8 = _super6.call(this);

@@ -1009,5 +865,5 @@ _this8.fn = fn;

_this8.formulaObject = formulaObject;
_this8.blacklisted = undefined;
return _this8;
}
_createClass(FunctionExpression, [{

@@ -1020,14 +876,22 @@ key: "evaluate",

return a.evaluate(params);
}); // If the params object itself has a function definition with
});
// If the params object itself has a function definition with
// the function name, call this one:
if (params[this.fn] instanceof Function) {
return params[this.fn].apply(this, paramValues);
} // perhaps the Formula object has the function? so call it:
}
// perhaps the Formula object has the function? so call it:
else if (this.formulaObject && this.formulaObject[this.fn] instanceof Function) {
// Don't, if it is blacklisted:
if (this.isBlacklisted()) {
throw new Error('Blacklisted function called: ' + this.fn);
}
return this.formulaObject[this.fn].apply(this.formulaObject, paramValues);
} // Has the JS Math object a function as requested? Call it:
}
// Has the JS Math object a function as requested? Call it:
else if (Math[this.fn] instanceof Function) {
return Math[this.fn].apply(this, paramValues);
} // No more options left: sorry!
}
// No more options left: sorry!
else {

@@ -1044,22 +908,38 @@ throw new Error('Function not found: ' + this.fn);

}
}, {
key: "isBlacklisted",
value: function isBlacklisted() {
// cache evaluation of blacklisted function, to save call time:
if (this.blacklisted === undefined) {
this.blacklisted = Formula.functionBlacklist.includes(this.formulaObject ? this.formulaObject[this.fn] : null);
}
return this.blacklisted;
}
}]);
return FunctionExpression;
}(Expression);
function getProperty(object, path, fullPath) {
var curr = object;
for (var i = 0; i < path.length; i++) {
if (curr[path[i]] === undefined) {
throw new Error("Cannot evaluate ".concat(path[i], ", property not found (from path ").concat(fullPath, ")"));
}
curr = curr[path[i]];
}
if (_typeof(curr) === 'object') {
throw new Error('Invalid value');
}
return curr;
}
var VariableExpression = /*#__PURE__*/function (_Expression7) {
_inherits(VariableExpression, _Expression7);
var _super7 = _createSuper(VariableExpression);
function VariableExpression(varName) {
function VariableExpression(fullPath) {
var _this9;
_classCallCheck(this, VariableExpression);
_this9 = _super7.call(this);
_this9.varName = varName || '';
_this9.fullPath = fullPath;
_this9.varPath = fullPath.split('.');
return _this9;
}
_createClass(VariableExpression, [{

@@ -1069,11 +949,9 @@ key: "evaluate",

var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// params contain variable / value pairs: If this object's variable matches
// a varname found in the params, return the value.
// eg: params = {x: 5,y:3}, varname = x, return 5
if (params[this.varName] !== undefined) {
return Number(params[this.varName]);
} else {
throw new Error('Cannot evaluate ' + this.varName + ': No value given');
}
// Objects and arrays are also supported:
// e.g. params = {x: {y: 5}}, varname = x.y, return 5
// or params = {x: [2,4,6]}, varname = x.2, return 6
return Number(getProperty(params, this.varPath, this.fullPath));
}

@@ -1083,9 +961,7 @@ }, {

value: function toString() {
return "".concat(this.varName);
return "".concat(this.varPath.join('.'));
}
}]);
return VariableExpression;
}(Expression);
Formula.Expression = Expression;

@@ -1100,2 +976,9 @@ Formula.BracketExpression = BracketExpression;

Formula.MATH_CONSTANTS = MATH_CONSTANTS;
// Create a function blacklist:
Formula.functionBlacklist = Object.getOwnPropertyNames(Formula.prototype).filter(function (prop) {
return Formula.prototype[prop] instanceof Function;
}).map(function (prop) {
return Formula.prototype[prop];
});
module.exports = exports.default;

@@ -1102,0 +985,0 @@ });

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Formula=e():t.Formula=e()}(this,(function(){return t={91:function(t,e){var n,r;function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self&&self,void 0===(r="function"==typeof(n=function(n){"use strict";function r(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&i(t,e)}function i(t,e){return(i=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function a(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=s(t);if(e){var o=s(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return u(this,n)}}function u(t,e){return!e||"object"!==o(e)&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function s(t){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function c(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?l(Object(n),!0).forEach((function(e){f(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function f(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function h(t){return function(t){if(Array.isArray(t))return v(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||p(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(t,e){if(t){if("string"==typeof t)return v(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?v(t,e):void 0}}function v(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function y(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function m(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}function g(t,e,n){return e&&m(t.prototype,e),n&&m(t,n),t}Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var b={PI:Math.PI,E:Math.E,LN2:Math.LN2,LN10:Math.LN10,LOG2E:Math.LOG2E,LOG10E:Math.LOG10E,SQRT1_2:Math.SQRT1_2,SQRT2:Math.SQRT2},w=function(){function t(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return y(this,t),this.formulaExpression=null,this.options=Object.assign({memoization:!1},n),this._variables=[],this._memory={},this.setFormula(e),this}return g(t,[{key:"setFormula",value:function(t){return t&&(this.formulaExpression=null,this._variables=[],this._memory={},this.formulaStr=t,this.formulaExpression=this.parse(t)),this}},{key:"enableMemoization",value:function(){this.options.memoization=!0}},{key:"disableMemoization",value:function(){this.options.memoization=!1,this._memory={}}},{key:"splitFunctionParams",value:function(t){var e,n=0,r="",o=[],i=function(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=p(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var r=0,o=function(){};return{s:o,n:function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,u=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return a=t.done,t},e:function(t){u=!0,i=t},f:function(){try{a||null==n.return||n.return()}finally{if(u)throw i}}}}(t.split(""));try{for(i.s();!(e=i.n()).done;){var a=e.value;if(","===a&&0===n)o.push(r),r="";else if("("===a)n++,r+=a;else if(")"===a){if(r+=a,--n<0)throw new Error("ERROR: Too many closing parentheses!")}else r+=a}}catch(t){i.e(t)}finally{i.f()}if(0!==n)throw new Error("ERROR: Too many opening parentheses!");return r.length>0&&o.push(r),o}},{key:"cleanupInputString",value:function(t){return t=t.replace(/[\s]+/g,""),Object.keys(b).forEach((function(e){t=t.replace(new RegExp("\\b".concat(e,"\\b"),"g"),"[".concat(e,"]"))})),t}},{key:"parse",value:function(t){return t=this.cleanupInputString(t),this._do_parse(t)}},{key:"_do_parse",value:function(t){for(var e=this,n=t.length-1,r=0,o=0,i=[],a="",u="",s=null,l=0;r<=n;){switch(o){case 0:if((a=t.charAt(r)).match(/[0-9.]/))o="within-nr",u="",r--;else if(this.isOperator(a)){if("-"===a&&(0===i.length||this.isOperatorExpr(i[i.length-1]))){o="within-nr",u="-";break}if(r===n||this.isOperatorExpr(i[r-1])){o=-1;break}i.push(d.createOperatorExpression(a)),o=0}else"("===a?(o="within-parentheses",u="",l=0):"["===a?(o="within-named-var",u=""):a.match(/[a-zA-Z]/)&&(r<n&&t.charAt(r+1).match(/[a-zA-Z0-9_]/)?(u=a,o="within-func"):(i.length>0&&i[i.length-1]instanceof x&&i.push(d.createOperatorExpression("*")),i.push(new _(a)),this.registerVariable(a),o=0,u=""));break;case"within-nr":(a=t.charAt(r)).match(/[0-9.]/)?(u+=a,r===n&&(i.push(new x(u)),o=0)):("-"===u&&(u=-1),i.push(new x(u)),u="",o=0,r--);break;case"within-func":if((a=t.charAt(r)).match(/[a-zA-Z0-9_]/))u+=a;else{if("("!==a)throw new Error("Wrong character for function at position "+r);s=u,u="",l=0,o="within-func-parentheses"}break;case"within-named-var":if("]"===(a=t.charAt(r)))i.push(new _(u)),this.registerVariable(u),u="",o=0;else{if(!a.match(/[a-zA-Z0-9_]/))throw new Error("Character not allowed within named variable: "+a);u+=a}break;case"within-parentheses":case"within-func-parentheses":if(")"===(a=t.charAt(r)))if(l<=0){if("within-parentheses"===o)i.push(new E(this._do_parse(u)));else if("within-func-parentheses"===o){var c=this.splitFunctionParams(u).map((function(t){return e._do_parse(t)}));i.push(new j(s,c,this)),s=null}o=0}else l--,u+=a;else"("===a?(l++,u+=a):u+=a}r++}if(0!==o)throw new Error("Could not parse formula: Syntax error.");return this.buildExpressionTree(i)}},{key:"buildExpressionTree",value:function(t){if(t.length<1)return null;for(var e=h(t),n=0,r=null;n<e.length;)if((r=e[n])instanceof S){if(0===n||n===e.length-1)throw new Error("Wrong operator position!");r.base=e[n-1],r.exponent=e[n+1],e[n-1]=r,e.splice(n,2)}else n++;for(n=0,r=null;n<e.length;)if((r=e[n])instanceof k){if(0===n||n===e.length-1)throw new Error("Wrong operator position!");r.left=e[n-1],r.right=e[n+1],e[n-1]=r,e.splice(n,2)}else n++;for(n=0,r=null;n<e.length;)if((r=e[n])instanceof O){if(0===n||n===e.length-1)throw new Error("Wrong operator position!");r.left=e[n-1],r.right=e[n+1],e[n-1]=r,e.splice(n,2)}else n++;if(1!==e.length)throw new Error("Could not parse formula: incorrect syntax?");return e[0]}},{key:"isOperator",value:function(t){return"string"==typeof t&&t.match(/[\+\-\*\/\^]/)}},{key:"isOperatorExpr",value:function(t){return t instanceof O||t instanceof k||t instanceof S}},{key:"registerVariable",value:function(t){this._variables.indexOf(t)<0&&this._variables.push(t)}},{key:"getVariables",value:function(){return this._variables}},{key:"evaluate",value:function(t){var e=this;if(t instanceof Array)return t.map((function(t){return e.evaluate(t)}));var n=this.getExpression();if(!(n instanceof d))throw new Error("No expression set: Did you init the object with a Formula?");if(this.options.memoization){var r=this.resultFromMemory(t);return null!==r||(r=n.evaluate(c(c({},b),t)),this.storeInMemory(t,r)),r}return n.evaluate(c(c({},b),t))}},{key:"hashValues",value:function(t){return JSON.stringify(t)}},{key:"resultFromMemory",value:function(t){var e=this.hashValues(t),n=this._memory[e];return void 0!==n?n:null}},{key:"storeInMemory",value:function(t,e){this._memory[this.hashValues(t)]=e}},{key:"getExpression",value:function(){return this.formulaExpression}},{key:"getExpressionString",value:function(){return this.formulaExpression?this.formulaExpression.toString():""}}],[{key:"calc",value:function(e,n){return n=n||{},new t(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).evaluate(n)}}]),t}();n.default=w;var d=function(){function t(){y(this,t)}return g(t,[{key:"evaluate",value:function(){throw new Error("Must be defined in child classes")}},{key:"toString",value:function(){return""}}],[{key:"createOperatorExpression",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if("^"===t)return new S(t,e,n);if("*"===t||"/"===t)return new k(t,e,n);if("+"===t||"-"===t)return new O(t,e,n);throw new Error("Unknown operator: ".concat(t))}}]),t}(),E=function(t){r(n,t);var e=a(n);function n(t){var r;if(y(this,n),(r=e.call(this)).innerExpression=t,!(r.innerExpression instanceof d))throw new Error("No inner expression given for bracket expression");return r}return g(n,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.innerExpression.evaluate(t)}},{key:"toString",value:function(){return"(".concat(this.innerExpression.toString(),")")}}]),n}(d),x=function(t){r(n,t);var e=a(n);function n(t){var r;if(y(this,n),(r=e.call(this)).value=Number(t),isNaN(r.value))throw new Error("Cannot parse number: "+t);return r}return g(n,[{key:"evaluate",value:function(){return this.value}},{key:"toString",value:function(){return String(this.value)}}]),n}(d),O=function(t){r(n,t);var e=a(n);function n(t){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(y(this,n),r=e.call(this),!["+","-"].includes(t))throw new Error("Operator not allowed in Plus/Minus expression: ".concat(t));return r.operator=t,r.left=o,r.right=i,r}return g(n,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("+"===this.operator)return this.left.evaluate(t)+this.right.evaluate(t);if("-"===this.operator)return this.left.evaluate(t)-this.right.evaluate(t);throw new Error("Unknown operator for PlusMinus expression")}},{key:"toString",value:function(){return"".concat(this.left.toString()," ").concat(this.operator," ").concat(this.right.toString())}}]),n}(d),k=function(t){r(n,t);var e=a(n);function n(t){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(y(this,n),r=e.call(this),!["*","/"].includes(t))throw new Error("Operator not allowed in Multiply/Division expression: ".concat(t));return r.operator=t,r.left=o,r.right=i,r}return g(n,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("*"===this.operator)return this.left.evaluate(t)*this.right.evaluate(t);if("/"===this.operator)return this.left.evaluate(t)/this.right.evaluate(t);throw new Error("Unknown operator for MultDiv expression")}},{key:"toString",value:function(){return"".concat(this.left.toString()," ").concat(this.operator," ").concat(this.right.toString())}}]),n}(d),S=function(t){r(n,t);var e=a(n);function n(){var t,r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return y(this,n),(t=e.call(this)).base=r,t.exponent=o,t}return g(n,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return Math.pow(this.base.evaluate(t),this.exponent.evaluate(t))}},{key:"toString",value:function(){return"".concat(this.base.toString(),"^").concat(this.exponent.toString())}}]),n}(d),j=function(t){r(n,t);var e=a(n);function n(t,r){var o,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return y(this,n),(o=e.call(this)).fn=t,o.argumentExpressions=r||[],o.formulaObject=i,o}return g(n,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};t=t||{};var e=this.argumentExpressions.map((function(e){return e.evaluate(t)}));if(t[this.fn]instanceof Function)return t[this.fn].apply(this,e);if(this.formulaObject&&this.formulaObject[this.fn]instanceof Function)return this.formulaObject[this.fn].apply(this.formulaObject,e);if(Math[this.fn]instanceof Function)return Math[this.fn].apply(this,e);throw new Error("Function not found: "+this.fn)}},{key:"toString",value:function(){return"".concat(this.fn,"(").concat(this.argumentExpressions.map((function(t){return t.toString()})).join(", "),")")}}]),n}(d),_=function(t){r(n,t);var e=a(n);function n(t){var r;return y(this,n),(r=e.call(this)).varName=t||"",r}return g(n,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(void 0!==t[this.varName])return Number(t[this.varName]);throw new Error("Cannot evaluate "+this.varName+": No value given")}},{key:"toString",value:function(){return"".concat(this.varName)}}]),n}(d);w.Expression=d,w.BracketExpression=E,w.PowerExpression=S,w.MultDivExpression=k,w.PlusMinusExpression=O,w.ValueExpression=x,w.VariableExpression=_,w.FunctionExpression=j,w.MATH_CONSTANTS=b,t.exports=e.default})?n.apply(e,[e]):n)||(t.exports=r)}},e={},function n(r){var o=e[r];if(void 0!==o)return o.exports;var i=e[r]={exports:{}};return t[r].call(i.exports,i,i.exports,n),i.exports}(91);var t,e}));
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Formula=e():t.Formula=e()}(this,(()=>{return t={91:function(t,e){var r,n;"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self&&self,r=function(r){"use strict";function n(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&o(t,e)}function o(t,e){return o=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},o(t,e)}function i(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var r,n=a(t);if(e){var o=a(this).constructor;r=Reflect.construct(n,arguments,o)}else r=n.apply(this,arguments);return function(t,e){if(e&&("object"===u(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,r)}}function a(t){return a=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},a(t)}function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function s(t){return function(t){if(Array.isArray(t))return c(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||l(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){if(t){if("string"==typeof t)return c(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?c(t,e):void 0}}function c(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r<e;r++)n[r]=t[r];return n}function f(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function h(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?f(Object(r),!0).forEach((function(e){var n,o,i;n=t,o=e,i=r[e],(o=b(o))in n?Object.defineProperty(n,o,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[o]=i})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):f(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}function p(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function v(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,b(n.key),n)}}function y(t,e,r){return e&&v(t.prototype,e),r&&v(t,r),Object.defineProperty(t,"prototype",{writable:!1}),t}function b(t){var e=function(t,e){if("object"!==u(t)||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var n=r.call(t,e||"default");if("object"!==u(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"===u(e)?e:String(e)}Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var m={PI:Math.PI,E:Math.E,LN2:Math.LN2,LN10:Math.LN10,LOG2E:Math.LOG2E,LOG10E:Math.LOG10E,SQRT1_2:Math.SQRT1_2,SQRT2:Math.SQRT2},g=r.default=function(){function t(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};p(this,t),this.formulaExpression=null,this.options=h(h({},{memoization:!1}),r),this._variables=[],this._memory={},this.setFormula(e)}return y(t,[{key:"setFormula",value:function(t){return t&&(this.formulaExpression=null,this._variables=[],this._memory={},this.formulaStr=t,this.formulaExpression=this.parse(t)),this}},{key:"enableMemoization",value:function(){this.options.memoization=!0}},{key:"disableMemoization",value:function(){this.options.memoization=!1,this._memory={}}},{key:"splitFunctionParams",value:function(t){var e,r=0,n="",o=[],i=function(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=l(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,u=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return a=t.done,t},e:function(t){u=!0,i=t},f:function(){try{a||null==r.return||r.return()}finally{if(u)throw i}}}}(t.split(""));try{for(i.s();!(e=i.n()).done;){var a=e.value;if(","===a&&0===r)o.push(n),n="";else if("("===a)r++,n+=a;else if(")"===a){if(n+=a,--r<0)throw new Error("ERROR: Too many closing parentheses!")}else n+=a}}catch(t){i.e(t)}finally{i.f()}if(0!==r)throw new Error("ERROR: Too many opening parentheses!");return n.length>0&&o.push(n),o}},{key:"cleanupInputString",value:function(t){return t=t.replace(/\s+/g,""),Object.keys(m).forEach((function(e){t=t.replace(new RegExp("\\b".concat(e,"\\b"),"g"),"[".concat(e,"]"))})),t}},{key:"parse",value:function(t){return t=this.cleanupInputString(t),this._do_parse(t)}},{key:"_do_parse",value:function(t){for(var e=this,r=t.length-1,n=0,o=0,i=[],a="",u="",s=null,l=0;n<=r;){switch(o){case 0:if((a=t.charAt(n)).match(/[0-9.]/))o="within-nr",u="",n--;else if(this.isOperator(a)){if("-"===a&&(0===i.length||this.isOperatorExpr(i[i.length-1]))){o="within-nr",u="-";break}if(n===r||this.isOperatorExpr(i[i.length-1])){o=-1;break}i.push(d.createOperatorExpression(a)),o=0}else"("===a?(o="within-parentheses",u="",l=0):"["===a?(o="within-named-var",u=""):a.match(/[a-zA-Z]/)&&(n<r&&t.charAt(n+1).match(/[a-zA-Z0-9_]/)?(u=a,o="within-func"):(i.length>0&&i[i.length-1]instanceof E&&i.push(d.createOperatorExpression("*")),i.push(new j(a)),this.registerVariable(a),o=0,u=""));break;case"within-nr":(a=t.charAt(n)).match(/[0-9.]/)?(u+=a,n===r&&(i.push(new E(u)),o=0)):("-"===u&&(u=-1),i.push(new E(u)),u="",o=0,n--);break;case"within-func":if((a=t.charAt(n)).match(/[a-zA-Z0-9_]/))u+=a;else{if("("!==a)throw new Error("Wrong character for function at position "+n);s=u,u="",l=0,o="within-func-parentheses"}break;case"within-named-var":if("]"===(a=t.charAt(n)))i.push(new j(u)),this.registerVariable(u),u="",o=0;else{if(!a.match(/[a-zA-Z0-9_.]/))throw new Error("Character not allowed within named variable: "+a);u+=a}break;case"within-parentheses":case"within-func-parentheses":if(")"===(a=t.charAt(n)))if(l<=0){if("within-parentheses"===o)i.push(new w(this._do_parse(u)));else if("within-func-parentheses"===o){var c=this.splitFunctionParams(u).map((function(t){return e._do_parse(t)}));i.push(new S(s,c,this)),s=null}o=0}else l--,u+=a;else"("===a?(l++,u+=a):u+=a}n++}if(0!==o)throw new Error("Could not parse formula: Syntax error.");return this.buildExpressionTree(i)}},{key:"buildExpressionTree",value:function(t){if(t.length<1)return null;for(var e=s(t),r=0,n=null;r<e.length;)if((n=e[r])instanceof k){if(0===r||r===e.length-1)throw new Error("Wrong operator position!");n.base=e[r-1],n.exponent=e[r+1],e[r-1]=n,e.splice(r,2)}else r++;for(r=0,n=null;r<e.length;)if((n=e[r])instanceof x){if(0===r||r===e.length-1)throw new Error("Wrong operator position!");n.left=e[r-1],n.right=e[r+1],e[r-1]=n,e.splice(r,2)}else r++;for(r=0,n=null;r<e.length;)if((n=e[r])instanceof O){if(0===r||r===e.length-1)throw new Error("Wrong operator position!");n.left=e[r-1],n.right=e[r+1],e[r-1]=n,e.splice(r,2)}else r++;if(1!==e.length)throw new Error("Could not parse formula: incorrect syntax?");return e[0]}},{key:"isOperator",value:function(t){return"string"==typeof t&&t.match(/[+\-*/^]/)}},{key:"isOperatorExpr",value:function(t){return t instanceof O||t instanceof x||t instanceof k}},{key:"registerVariable",value:function(t){this._variables.indexOf(t)<0&&this._variables.push(t)}},{key:"getVariables",value:function(){return this._variables}},{key:"evaluate",value:function(t){var e=this;if(t instanceof Array)return t.map((function(t){return e.evaluate(t)}));var r=this.getExpression();if(!(r instanceof d))throw new Error("No expression set: Did you init the object with a Formula?");if(this.options.memoization){var n=this.resultFromMemory(t);return null!==n||(n=r.evaluate(h(h({},m),t)),this.storeInMemory(t,n)),n}return r.evaluate(h(h({},m),t))}},{key:"hashValues",value:function(t){return JSON.stringify(t)}},{key:"resultFromMemory",value:function(t){var e=this.hashValues(t),r=this._memory[e];return void 0!==r?r:null}},{key:"storeInMemory",value:function(t,e){this._memory[this.hashValues(t)]=e}},{key:"getExpression",value:function(){return this.formulaExpression}},{key:"getExpressionString",value:function(){return this.formulaExpression?this.formulaExpression.toString():""}}],[{key:"calc",value:function(e,r){return r=r||{},new t(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).evaluate(r)}}]),t}(),d=function(){function t(){p(this,t)}return y(t,[{key:"evaluate",value:function(){throw new Error("Must be defined in child classes")}},{key:"toString",value:function(){return""}}],[{key:"createOperatorExpression",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if("^"===t)return new k(t,e,r);if("*"===t||"/"===t)return new x(t,e,r);if("+"===t||"-"===t)return new O(t,e,r);throw new Error("Unknown operator: ".concat(t))}}]),t}(),w=function(t){n(r,t);var e=i(r);function r(t){var n;if(p(this,r),(n=e.call(this)).innerExpression=t,!(n.innerExpression instanceof d))throw new Error("No inner expression given for bracket expression");return n}return y(r,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return this.innerExpression.evaluate(t)}},{key:"toString",value:function(){return"(".concat(this.innerExpression.toString(),")")}}]),r}(d),E=function(t){n(r,t);var e=i(r);function r(t){var n;if(p(this,r),(n=e.call(this)).value=Number(t),isNaN(n.value))throw new Error("Cannot parse number: "+t);return n}return y(r,[{key:"evaluate",value:function(){return this.value}},{key:"toString",value:function(){return String(this.value)}}]),r}(d),O=function(t){n(r,t);var e=i(r);function r(t){var n,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(p(this,r),n=e.call(this),!["+","-"].includes(t))throw new Error("Operator not allowed in Plus/Minus expression: ".concat(t));return n.operator=t,n.left=o,n.right=i,n}return y(r,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("+"===this.operator)return this.left.evaluate(t)+this.right.evaluate(t);if("-"===this.operator)return this.left.evaluate(t)-this.right.evaluate(t);throw new Error("Unknown operator for PlusMinus expression")}},{key:"toString",value:function(){return"".concat(this.left.toString()," ").concat(this.operator," ").concat(this.right.toString())}}]),r}(d),x=function(t){n(r,t);var e=i(r);function r(t){var n,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(p(this,r),n=e.call(this),!["*","/"].includes(t))throw new Error("Operator not allowed in Multiply/Division expression: ".concat(t));return n.operator=t,n.left=o,n.right=i,n}return y(r,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if("*"===this.operator)return this.left.evaluate(t)*this.right.evaluate(t);if("/"===this.operator)return this.left.evaluate(t)/this.right.evaluate(t);throw new Error("Unknown operator for MultDiv expression")}},{key:"toString",value:function(){return"".concat(this.left.toString()," ").concat(this.operator," ").concat(this.right.toString())}}]),r}(d),k=function(t){n(r,t);var e=i(r);function r(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return p(this,r),(t=e.call(this)).base=n,t.exponent=o,t}return y(r,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return Math.pow(this.base.evaluate(t),this.exponent.evaluate(t))}},{key:"toString",value:function(){return"".concat(this.base.toString(),"^").concat(this.exponent.toString())}}]),r}(d),S=function(t){n(r,t);var e=i(r);function r(t,n){var o,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return p(this,r),(o=e.call(this)).fn=t,o.argumentExpressions=n||[],o.formulaObject=i,o.blacklisted=void 0,o}return y(r,[{key:"evaluate",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};t=t||{};var e=this.argumentExpressions.map((function(e){return e.evaluate(t)}));if(t[this.fn]instanceof Function)return t[this.fn].apply(this,e);if(this.formulaObject&&this.formulaObject[this.fn]instanceof Function){if(this.isBlacklisted())throw new Error("Blacklisted function called: "+this.fn);return this.formulaObject[this.fn].apply(this.formulaObject,e)}if(Math[this.fn]instanceof Function)return Math[this.fn].apply(this,e);throw new Error("Function not found: "+this.fn)}},{key:"toString",value:function(){return"".concat(this.fn,"(").concat(this.argumentExpressions.map((function(t){return t.toString()})).join(", "),")")}},{key:"isBlacklisted",value:function(){return void 0===this.blacklisted&&(this.blacklisted=g.functionBlacklist.includes(this.formulaObject?this.formulaObject[this.fn]:null)),this.blacklisted}}]),r}(d);var j=function(t){n(r,t);var e=i(r);function r(t){var n;return p(this,r),(n=e.call(this)).fullPath=t,n.varPath=t.split("."),n}return y(r,[{key:"evaluate",value:function(){return Number(function(t,e,r){for(var n=t,o=0;o<e.length;o++){if(void 0===n[e[o]])throw new Error("Cannot evaluate ".concat(e[o],", property not found (from path ").concat(r,")"));n=n[e[o]]}if("object"===u(n))throw new Error("Invalid value");return n}(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},this.varPath,this.fullPath))}},{key:"toString",value:function(){return"".concat(this.varPath.join("."))}}]),r}(d);g.Expression=d,g.BracketExpression=w,g.PowerExpression=k,g.MultDivExpression=x,g.PlusMinusExpression=O,g.ValueExpression=E,g.VariableExpression=j,g.FunctionExpression=S,g.MATH_CONSTANTS=m,g.functionBlacklist=Object.getOwnPropertyNames(g.prototype).filter((function(t){return g.prototype[t]instanceof Function})).map((function(t){return g.prototype[t]})),t.exports=e.default},void 0===(n=r.apply(e,[e]))||(t.exports=n)}},e={},function r(n){var o=e[n];if(void 0!==o)return o.exports;var i=e[n]={exports:{}};return t[n].call(i.exports,i,i.exports,r),i.exports}(91);var t,e}));
//# sourceMappingURL=fparser.js.map
{
"name": "fparser",
"version": "2.0.2",
"version": "2.1.0",
"description": "A Math Formula parser library for JavaScript",

@@ -10,3 +10,3 @@ "main": "dist/fparser.js",

"docker-shell": "docker run --rm -ti -v \"$PWD\":/usr/src/app -w /usr/src/app fparser bash",
"docker-demopage": "docker run --rm -ti -v \"$PWD\":/usr/src/app -w /usr/src/app/demopage -p 3000:8080 fparser npm run serve",
"docker-demopage": "docker run --rm -ti -v \"$PWD\":/usr/src/app -w /usr/src/app/demopage -p 3000:8080 fparser npm run dev",
"docker-test": "docker run --rm -ti -v \"$PWD\":/usr/src/app -w /usr/src/app fparse npm run test",

@@ -39,17 +39,16 @@ "build-dev": "NODE_ENV=development webpack",

"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/preset-env": "^7.16.11",
"@vue/cli": "^4.5.17",
"babel-loader": "^8.2.4",
"@babel/core": "^7.23.3",
"@babel/preset-env": "^7.23.3",
"babel-loader": "^9.1.3",
"babel-plugin-add-module-exports": "^1.0.4",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^3.4.1",
"jasmine": "^3.99.0",
"karma": "^6.3.17",
"karma-chrome-launcher": "^3.1.1",
"karma-jasmine": "^4.0.1",
"prettier": "^2.6.1",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2"
"eslint": "^8.54.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"jasmine": "^5.1.0",
"karma": "^6.4.2",
"karma-chrome-launcher": "^3.2.0",
"karma-jasmine": "^5.1.0",
"prettier": "^3.1.0",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4"
},

@@ -56,0 +55,0 @@ "eslintConfig": {

@@ -17,15 +17,15 @@ # fparser

* *Numbers* in the form [-]digits[.digits], e.g. "-133.2945"
* *simple operators*: '+','-','*','/', '^' expanded in correct order
* *parentheses* '(', ')' for grouping (e.g. "5*(3+2)")
* all *JavaScript Math object functions* (e.g. "sin(3.14)")
* all *JavaScript Math constants* like PI, E
* the use of *own functions*
* the use of single-char *variables* (like '2x')
* the use of named variables (like '2*[myVar]')
* *memoization*: store already evaluated results for faster re-calcs
* use it in Web pages, as ES6 module or as NodeJS module
* Example:<br /> <code>-1*(sin(2^x)/(PI*x))*cos(x))</code>
- _Numbers_ in the form [-]digits[.digits], e.g. "-133.2945"
- _simple operators_: '+','-','\*','/', '^' expanded in correct order
- _parentheses_ '(', ')' for grouping (e.g. "5\*(3+2)")
- all _JavaScript Math object functions_ (e.g. "sin(3.14)")
- all _JavaScript Math constants_ like PI, E
- the use of _own functions_
- the use of single-char _variables_ (like '2x')
- the use of named variables (like '2\*[myVar]')
- the use of path named variables (like '2\*[myVar.property.innerProperty]')
- _memoization_: store already evaluated results for faster re-calcs
- use it in Web pages, as ES6 module or as NodeJS module
- Example:<br /> <code>-1*(sin(2^x)/(PI*x))\*cos(x))</code>
## Usage

@@ -55,10 +55,10 @@

// 2. evaluate the formula, delivering a value object for each unknown entity:
let result = fObj.evaluate({x: 3}); // result = 8
let result = fObj.evaluate({ x: 3 }); // result = 8
// or deliver multiple value objects to return multiple results:
let results = fObj.evaluate([{x: 2},{x: 4},{x: 8}]); // results = [4,16,256]
let results = fObj.evaluate([{ x: 2 }, { x: 4 }, { x: 8 }]); // results = [4,16,256]
// You can also directly evaluate a value if you only need a one-shot result:
let result = Formula.calc('2^x',{x: 3}); // result = 8
let results = Formula.calc('2^x',[{x: 2},{x: 4},{x: 8}]); // results = [4,16,256]
let result = Formula.calc('2^x', { x: 3 }); // result = 8
let results = Formula.calc('2^x', [{ x: 2 }, { x: 4 }, { x: 8 }]); // results = [4,16,256]

@@ -74,2 +74,3 @@ // Usage in NodeJS:

### Using multiple variables
```javascript

@@ -79,3 +80,3 @@ const fObj = new Formula('a*x^2 + b*x + c');

// Just pass a value object containing a value for each unknown variable:
let result = fObj.evaluate({a:2,b:-1,c:3,x:3}); // result = 18
let result = fObj.evaluate({ a: 2, b: -1, c: 3, x: 3 }); // result = 18
```

@@ -86,2 +87,3 @@

Instead of single-char variables (like `2x+y`), you can also use named variables in brackets:
```javascript

@@ -91,6 +93,26 @@ const fObj = new Formula('2*[var1] + sin([var2]+PI)');

// Just pass a value object containing a value for each named variable:
let result = fObj.evaluate({var1: 5, var2: 0.7});
let result = fObj.evaluate({ var1: 5, var2: 0.7 });
```
### Using named path variables
Named variables in brackets can also describe an object property path:
```javascript
const fObj = new Formula('2*[var1.propertyA] + 3*[var2.propertyB.propertyC]');
// Just pass a value object containing a value for each named variable:
let result = fObj.evaluate({ var1: { propertyA: 3 }, var2: { propertyB: { propertyC: 9 } } });
```
This even works for array values: Instead of the property name, use an index in an array:
```javascript
// var2.propertyB is an array, so we can use an index for the 3rd entry of propertyB:
const fObj = new Formula('2*[var1.propertyA] + 3*[var2.propertyB.2]');
let result = fObj.evaluate({ var1: { propertyA: 3 }, var2: { propertyB: [2, 4, 6] } });
```
### Using user-defined functions
```javascript

@@ -120,6 +142,6 @@ const fObj = new Formula('sin(inverse(x))');

fObj.setFormula('2*x^2 + 5*x + 3');
let res = fObj.evaluate({x:3});
let res = fObj.evaluate({ x: 3 });
// ...
fObj.setFormula('x*y');
res = fObj.evaluate({x:2, y:4});
res = fObj.evaluate({ x: 2, y: 4 });
```

@@ -135,17 +157,61 @@

```javascript
const fObj = new Formula('x * y', {memoization: true});
let res1 = fObj.evaluate({x:2, y:3}); // 6, evaluated by calculating x*y
let res2 = fObj.evaluate({x:2, y:3}); // 6, from memory
const fObj = new Formula('x * y', { memoization: true });
let res1 = fObj.evaluate({ x: 2, y: 3 }); // 6, evaluated by calculating x*y
let res2 = fObj.evaluate({ x: 2, y: 3 }); // 6, from memory
```
You can enable / disable memoization on the object:
```javascript
const fObj = new Formula('x * y');
let res1 = fObj.evaluate({x:2, y:3}); // 6, evaluated by calculating x*y
let res1 = fObj.evaluate({ x: 2, y: 3 }); // 6, evaluated by calculating x*y
fObj.enableMemoization();
let res2 = fObj.evaluate({x:2, y:3}); // 6, evaluated by calculating x*y
let res3 = fObj.evaluate({x:2, y:3}); // 6, from memory
let res2 = fObj.evaluate({ x: 2, y: 3 }); // 6, evaluated by calculating x*y
let res3 = fObj.evaluate({ x: 2, y: 3 }); // 6, from memory
```
### Blacklisted functions
The `Formula` class blacklists its internal functions like `evaluate`, `parse` etc. You cannot create a formula that calls an internal `Formula`
function:
```javascript
// Internal functions cannot be used in formulas:
const fObj = new Formula('evaluate(x)');
fObj.evaluate({ x: 5 }); // throws an Error
// This also counts for function aliases / references to internal functions:
const fObj = new Formula('ex(x)');
fObj.ex = fObj.evaluate;
fObj.evaluate({ x: 5 }); // still throws an Error: ex is an alias of evaluate
```
The `Formula` object keeps a function reference of all blacklisted functions in the `Formula.functionBlacklist` array.
You can get a list of all blacklisted functions:
```javascript
let blacklistNames = Formula.functionBlacklist.map((f) => f.name));
```
Or you can check if a specific function is in the blacklist:
```javascript
fObj = new Formula('x * y');
// fObj.evaluate is a Function pointer to an internal, blacklisted function:
Formula.functionBlacklist.includes(fObj.evaluate);
```
If you want to provide your own function for a blacklisted internal function,
provide it with the `evaluate` function:
```javascript
fObj = new Formula('evaluate(x * y)');
fObj.evaluate({ x: 1, y: 2, evaluate: (x, y) => x + y });
```
Now, `evaluate` in your formula uses your own version of this function.
### Get all used variables
```javascript

@@ -169,5 +235,11 @@ // Get all used variables in the order of their appereance:

### 2.1.0
- [Breaking]: Blacklisting internal functions: You cannot use internal functions as formula function anymore.
- [Feature]: Supporting object paths as variable values (e.g. `3*[obj1.property1.innerProperty]`), thanks to [SamStonehouse](https://github.com/SamStonehouse)
- [Change]: Updated build infrastructure: upped versions of build tools
### 2.0.2
* Fixing Issue #22: If the formula started with a single negate variable (e.g. `-z*t`), the parser got confused.
- Fixing Issue #22: If the formula started with a single negate variable (e.g. `-z*t`), the parser got confused.

@@ -179,25 +251,22 @@ ### 2.0.0

* Switched to MIT license
* complete refactoring of the parsing and evaluating part: The parser now creates an Expression Tree (AST) that saves extra time while evaluating - Evaluation now only traverses the AST, which is much faster.
* added `getExpressionString()` function to get a formatted string from the formula
* adding support for memoization: store already evaluated results
* Switched bundler to webpack
* fixed some parser bugs
- Switched to MIT license
- complete refactoring of the parsing and evaluating part: The parser now creates an Expression Tree (AST) that saves extra time while evaluating - Evaluation now only traverses the AST, which is much faster.
- added `getExpressionString()` function to get a formatted string from the formula
- adding support for memoization: store already evaluated results
- Switched bundler to webpack
- fixed some parser bugs
### 1.4.0
* Adding support for named variables (`2x + [var1]`)
* switched testing to chromium runner instead of PhantomJS
- Adding support for named variables (`2x + [var1]`)
- switched testing to chromium runner instead of PhantomJS
### 1.3.0
* modernized library: The source is now ES6 code, and transpiled in a dist ES5+ library.
* Make sure you include dist/fparser.js if you are using it as a browser library.
* Drop support for Bower, as there are more modern approaches (npm) for package dependency nowadays
- modernized library: The source is now ES6 code, and transpiled in a dist ES5+ library.
- Make sure you include dist/fparser.js if you are using it as a browser library.
- Drop support for Bower, as there are more modern approaches (npm) for package dependency nowadays
License
----------
## License
Licensed under the MIT license, see LICENSE file.
/**
* JS Formula Parser
* -------------------
* (c) 2012-2021 Alexander Schenkel, alex@alexi.ch
* (c) 2012-2023 Alexander Schenkel, alex@alexi.ch
*

@@ -48,12 +48,6 @@ * JS Formula Parser takes a string, parses its mathmatical formula

this.formulaExpression = null;
this.options = Object.assign(
{
memoization: false
},
options
);
this.options = {...{memoization: false}, ...options};
this._variables = [];
this._memory = {};
this.setFormula(fStr);
return this;
}

@@ -137,3 +131,3 @@

cleanupInputString(s) {
s = s.replace(/[\s]+/g, '');
s = s.replace(/\s+/g, '');
// surround known math constants with [], to parse them as named variables [xxx]:

@@ -315,3 +309,3 @@ Object.keys(MATH_CONSTANTS).forEach((c) => {

state = 0;
} else if (char.match(/[a-zA-Z0-9_]/)) {
} else if (char.match(/[a-zA-Z0-9_.]/)) {
tmp += char;

@@ -438,3 +432,3 @@ } else {

isOperator(char) {
return typeof char === 'string' && char.match(/[\+\-\*\/\^]/);
return typeof char === 'string' && char.match(/[+\-*/^]/);
}

@@ -651,2 +645,3 @@

this.formulaObject = formulaObject;
this.blacklisted = undefined;
}

@@ -665,2 +660,6 @@

else if (this.formulaObject && this.formulaObject[this.fn] instanceof Function) {
// Don't, if it is blacklisted:
if (this.isBlacklisted()) {
throw new Error('Blacklisted function called: ' + this.fn);
}
return this.formulaObject[this.fn].apply(this.formulaObject, paramValues);

@@ -681,8 +680,36 @@ }

}
isBlacklisted() {
// cache evaluation of blacklisted function, to save call time:
if (this.blacklisted === undefined) {
this.blacklisted = Formula.functionBlacklist.includes(
this.formulaObject ? this.formulaObject[this.fn] : null
);
}
return this.blacklisted;
}
}
function getProperty(object, path, fullPath) {
let curr = object;
for (let i = 0; i < path.length; i++) {
if (curr[path[i]] === undefined) {
throw new Error(`Cannot evaluate ${path[i]}, property not found (from path ${fullPath})`);
}
curr = curr[path[i]];
}
if (typeof curr === 'object') {
throw new Error('Invalid value');
}
return curr;
}
class VariableExpression extends Expression {
constructor(varName) {
constructor(fullPath) {
super();
this.varName = varName || '';
this.fullPath = fullPath;
this.varPath = fullPath.split('.');
}

@@ -694,10 +721,9 @@

// eg: params = {x: 5,y:3}, varname = x, return 5
if (params[this.varName] !== undefined) {
return Number(params[this.varName]);
} else {
throw new Error('Cannot evaluate ' + this.varName + ': No value given');
}
// Objects and arrays are also supported:
// e.g. params = {x: {y: 5}}, varname = x.y, return 5
// or params = {x: [2,4,6]}, varname = x.2, return 6
return Number(getProperty(params, this.varPath, this.fullPath));
}
toString() {
return `${this.varName}`;
return `${this.varPath.join('.')}`;
}

@@ -715,1 +741,6 @@ }

Formula.MATH_CONSTANTS = MATH_CONSTANTS;
// Create a function blacklist:
Formula.functionBlacklist = Object.getOwnPropertyNames(Formula.prototype)
.filter((prop) => Formula.prototype[prop] instanceof Function)
.map((prop) => Formula.prototype[prop]);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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