/** * @license * The MIT License (MIT) * * Copyright (c) 2015 Matthew Crumley * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ !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";function t(t,e){this.type=t,this.value=void 0!==e&&null!==e?e:0}function e(e){return new t(Q,e)}function s(e){return new t(Y,e)}function r(e){return new t(Z,e)}function n(e,s,r,i,o){for(var a,h,p,u,c=[],l=[],f=0;f1)h=c.pop(),a=c.pop(),u=r[v.value],v=new t(K,u(a.value,h.value)),c.push(v);else if(x===Z&&c.length>2)p=c.pop(),h=c.pop(),a=c.pop(),"?"===v.value?c.push(a.value?h.value:p.value):(u=i[v.value],v=new t(K,u(a.value,h.value,p.value)),c.push(v));else if(x===Q&&c.length>0)a=c.pop(),u=s[v.value],v=new t(K,u(a.value)),c.push(v);else if(x===st){for(;c.length>0;)l.push(c.shift());l.push(new t(st,n(v.value,s,r,i,o)))}else if(x===rt&&c.length>0)a=c.pop(),c.push(new t(K,a.value[v.value]));else{for(;c.length>0;)l.push(c.shift());l.push(v)}}for(;c.length>0;)l.push(c.shift());return l}function i(n,o,a){for(var h=[],p=0;p0;)v.unshift(h.pop());if(!(a=h.pop()).apply||!a.call)throw new Error(a+" is not a function");h.push(a.apply(void 0,v))}else if(c===st)h.push(u.value);else{if(c!==rt)throw new Error("invalid Expression");r=h.pop(),h.push(r[u.value])}}if(h.length>1)throw new Error("invalid Expression (parity)");return h[0]}function a(t,e){for(var s,r,n,i,o=[],p=0;p0;)f.unshift(o.pop());i=o.pop(),o.push(i+"("+f.join(", ")+")")}else if(c===rt)s=o.pop(),o.push(s+"."+u.value);else{if(c!==st)throw new Error("invalid Expression");o.push("("+a(u.value,e)+")")}}if(o.length>1)throw new Error("invalid Expression (parity)");return String(o[0])}function h(t){return"string"==typeof t?JSON.stringify(t).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"):t}function p(t,e){for(var s=0;se}function T(t,e){return t=e}function O(t,e){return t<=e}function N(t,e){return Boolean(t&&e)}function C(t,e){return Boolean(t||e)}function P(t,e){return p(e,t)}function I(t){return(Math.exp(t)-Math.exp(-t))/2}function S(t){return(Math.exp(t)+Math.exp(-t))/2}function R(t){return t===1/0?1:t===-1/0?-1:(Math.exp(t)-Math.exp(-t))/(Math.exp(t)+Math.exp(-t))}function F(t){return t===-1/0?t:Math.log(t+Math.sqrt(t*t+1))}function L(t){return Math.log(t+Math.sqrt(t*t-1))}function U(t){return Math.log((1+t)/(1-t))/2}function q(t){return Math.log(t)*Math.LOG10E}function B(t){return-t}function $(t){return!t}function G(t){return t<0?Math.ceil(t):Math.floor(t)}function _(t){return Math.random()*(t||1)}function j(t){return W(t+1)}function J(t){return isFinite(t)&&t===Math.round(t)}function W(t){var e,s;if(J(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)*W(1-t));if(t>=171.35)return 1/0;if(t>85){var i=t*t,o=i*t,a=o*t,h=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*h)+5246819/(75246796800*h*t))}--t,s=ct[0];for(var p=1;p0?(r=n/e)*r:n}return e===1/0?1/0:e*Math.sqrt(t)}function z(t,e,s){return t?e:s}function D(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=Math.round(+(t[0]+"e"+(t[1]?+t[1]-e:-e))),+((t=t.toString().split("e"))[0]+"e"+(t[1]?+t[1]+e:e))))}function H(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||I,cosh:Math.cosh||S,tanh:Math.tanh||R,asinh:Math.asinh||F,acosh:Math.acosh||L,atanh:Math.atanh||U,sqrt:Math.sqrt,log:Math.log,ln:Math.log,lg:Math.log10||q,log10:Math.log10||q,abs:Math.abs,ceil:Math.ceil,floor:Math.floor,round:Math.round,trunc:Math.trunc||G,"-":B,"+":Number,exp:Math.exp,not:$,length:V,"!":j},this.binaryOps={"+":y,"-":w,"*":d,"/":M,"%":g,"^":Math.pow,"||":E,"==":k,"!=":b,">":m,"<":T,">=":A,"<=":O,and:N,or:C,in:P},this.ternaryOps={"?":z},this.functions={random:_,fac:j,min:Math.min,max:Math.max,hypot:Math.hypot||X,pyt:Math.hypot||X,pow:Math.pow,atan2:Math.atan2,if:z,gamma:W,roundTo:D},this.consts={E:Math.E,PI:Math.PI,true:!0,false:!1}}var K="INUMBER",Q="IOP1",Y="IOP2",Z="IOP3",tt="IVAR",et="IFUNCALL",st="IEXPR",rt="IMEMBER";t.prototype.toString=function(){switch(this.type){case K:case Q:case Y:case Z:case tt:return this.value;case et:return"CALL "+this.value;case rt:return"."+this.value;default:return"Invalid Instruction"}},c.prototype.simplify=function(t){return t=t||{},new c(n(this.tokens,this.unaryOps,this.binaryOps,this.ternaryOps,t),this.parser)},c.prototype.substitute=function(t,e){return e instanceof c||(e=this.parser.parse(String(e))),new c(i(this.tokens,t,e),this.parser)},c.prototype.evaluate=function(t){return t=t||{},o(this.tokens,this,t)},c.prototype.toString=function(){return a(this.tokens,!1)},c.prototype.symbols=function(t){t=t||{};var e=[];return u(this.tokens,e,t),e},c.prototype.variables=function(t){t=t||{};var e=[];u(this.tokens,e,t);var s=this.functions;return e.filter(function(t){return!(t in s)})},c.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 "+a(this.simplify(e).tokens,!0)+"; }");return function(){return r.apply(s,arguments)}};var nt="TOP";l.prototype.toString=function(){return this.type+": "+this.value},f.prototype.newToken=function(t,e,s){return new l(t,e,null!=s?s:this.pos)},f.prototype.save=function(){this.savedPosition=this.pos,this.savedCurrent=this.current},f.prototype.restore=function(){this.pos=this.savedPosition,this.current=this.savedCurrent},f.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.isConst()||this.isName()?this.current:void this.parseError('Unknown character "'+this.expression.charAt(this.pos)+'"')},f.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"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},f.prototype.isNamedOp=function(){for(var t=this.pos,e=t;e"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(nt,r),this.pos+=r.length,!0}return!1},f.prototype.isName=function(){for(var t=this.pos,e=t,s=!1;e"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},f.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.expression.length));)e=this.expression.charAt(this.pos);return t};var it=/^[0-9a-f]{4}$/i;f.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);it.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},f.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)},f.prototype.isRadixInteger=function(){var t=this.pos;if(t>=this.expression.length-2||"0"!==this.expression.charAt(t))return!1;++t;var e,s;if("x"===this.expression.charAt(t))e=16,s=/^[0-9a-f]$/i,++t;else{if("b"!==this.expression.charAt(t))return!1;e=2,s=/^[01]$/i,++t}for(var r=!1,n=t;t="0"&&t<="9"||!i&&"."===t);)"."===t?i=!0:o=!0,s++,e=o;if(e&&(n=s),"e"===t||"E"===t){s++;for(var a=!0,h=!1;s="0"&&t<="9"))break;h=!0,a=!1}else a=!1;s++}h||(s=n)}return e?(this.current=this.newToken("TNUMBER",parseFloat(this.expression.substring(r,s))),this.pos=s):this.pos=n,e},f.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(nt,e);else if("∙"===e||"•"===e)this.current=this.newToken(nt,"*");else if(">"===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(nt,">="),this.pos++):this.current=this.newToken(nt,">");else if("<"===e)"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(nt,"<="),this.pos++):this.current=this.newToken(nt,"<");else if("|"===e){if("|"!==this.expression.charAt(this.pos+1))return!1;this.current=this.newToken(nt,"||"),this.pos++}else if("="===e){if("="!==this.expression.charAt(this.pos+1))return!1;this.current=this.newToken(nt,"=="),this.pos++}else{if("!"!==e)return!1;"="===this.expression.charAt(this.pos+1)?(this.current=this.newToken(nt,"!="),this.pos++):this.current=this.newToken(nt,e)}return this.pos++,!!this.isOperatorEnabled(this.current.value)||(this.pos=t,!1)};var ot={"+":"add","-":"subtract","*":"multiply","/":"divide","%":"remainder","^":"power","!":"factorial","<":"comparison",">":"comparison","<=":"comparison",">=":"comparison","==":"comparison","!=":"comparison","||":"concatenate",and:"logical",or:"logical",not:"logical","?":"conditional",":":"conditional"};f.prototype.isOperatorEnabled=function(t){var e=v(t),s=this.options.operators||{};return"in"===e?!!s.in:!(e in s&&!s[e])},f.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=",">","in"];x.prototype.parseComparison=function(t){for(this.parseAddSub(t);this.accept(nt,at);){var e=this.current;this.parseAddSub(t),t.push(s(e.value))}};var ht=["+","-","||"];x.prototype.parseAddSub=function(t){for(this.parseTerm(t);this.accept(nt,ht);){var e=this.current;this.parseTerm(t),t.push(s(e.value))}};var pt=["*","/","%"];x.prototype.parseTerm=function(t){for(this.parseFactor(t);this.accept(nt,pt);){var e=this.current;this.parseFactor(t),t.push(s(e.value))}},x.prototype.parseFactor=function(t){var s=this.tokens.unaryOps;if(this.save(),this.accept(nt,function(t){return t.value in s}))if("-"!==this.current.value&&"+"!==this.current.value&&"TPAREN"===this.nextToken.type&&"("===this.nextToken.value)this.restore(),this.parseExponential(t);else{var r=this.current;this.parseFactor(t),t.push(e(r.value))}else this.parseExponential(t)},x.prototype.parseExponential=function(t){for(this.parsePostfixExpression(t);this.accept(nt,"^");)this.parseFactor(t),t.push(s("^"))},x.prototype.parsePostfixExpression=function(t){for(this.parseFunctionCall(t);this.accept(nt,"!");)t.push(e("!"))},x.prototype.parseFunctionCall=function(s){var r=this.tokens.unaryOps;if(this.accept(nt,function(t){return t.value in r})){var n=this.current;this.parseAtom(s),s.push(e(n.value))}else for(this.parseMemberExpression(s);this.accept("TPAREN","(");)if(this.accept("TPAREN",")"))s.push(new t(et,0));else{var i=this.parseArgumentList(s);s.push(new t(et,i))}},x.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},x.prototype.parseMemberExpression=function(e){for(this.parseAtom(e);this.accept(nt,".");){if(!this.allowMemberAccess)throw new Error('unexpected ".", member access is not permitted');this.expect("TNAME"),e.push(new t(rt,this.current.value))}};var ut=4.7421875,ct=[.9999999999999971,57.15623566586292,-59.59796035547549,14.136097974741746,-.4919138160976202,3399464998481189e-20,4652362892704858e-20,-9837447530487956e-20,.0001580887032249125,-.00021026444172410488,.00021743961811521265,-.0001643181065367639,8441822398385275e-20,-26190838401581408e-21,36899182659531625e-22];H.prototype.parse=function(t){var e=[],s=new x(this,new f(this,t),{allowMemberAccess:this.options.allowMemberAccess});return s.parseExpression(e),s.expect("TEOF","EOF"),new c(e,this)},H.prototype.evaluate=function(t,e){return this.parse(t).evaluate(e)};var lt=new H;return H.parse=function(t){return lt.parse(t)},H.evaluate=function(t,e){return lt.parse(t).evaluate(e)},{Parser:H,Expression:c}});