fable 3.1.33 → 3.1.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fable.js CHANGED
@@ -3062,7 +3062,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
3062
3062
  // presumably different callback function.
3063
3063
  // This makes sure that own properties are retained, so that
3064
3064
  // decorations and such are not lost along the way.
3065
- module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.33","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.45"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^7.0.1","cachetrax":"^1.0.4","cookie":"^1.0.2","data-arithmatic":"^1.0.7","dayjs":"^1.11.18","fable-log":"^3.0.16","fable-serviceproviderbase":"^3.0.15","fable-settings":"^3.0.12","fable-uuid":"^3.0.11","manyfest":"^1.0.42","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
3065
+ module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.35","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.45"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^7.0.1","cachetrax":"^1.0.4","cookie":"^1.0.2","data-arithmatic":"^1.0.7","dayjs":"^1.11.18","fable-log":"^3.0.16","fable-serviceproviderbase":"^3.0.15","fable-settings":"^3.0.12","fable-uuid":"^3.0.11","manyfest":"^1.0.42","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
3066
3066
  * Fable Application Services Support Library
3067
3067
  * @author <steven@velozo.com>
3068
3068
  */// Pre-init services
@@ -3683,6 +3683,14 @@ this.LogNoisiness='LogNoisiness'in this.fable?this.fable.LogNoisiness:0;}/**
3683
3683
  * @param {object} pManifest - The manifest object.
3684
3684
  * @returns {any} The result of the solved expression.
3685
3685
  */solvePostfixedExpression(pPostfixedExpression,pDataDestinationObject,pResultObject,pManifest){return this.Solver.solvePostfixedExpression(pPostfixedExpression,pDataDestinationObject,pResultObject,pManifest);}/**
3686
+ * Prepares the parameters for a SERIES directive by substituting values and applying defaults.
3687
+ *
3688
+ * @param {Array} pParameters
3689
+ * @param {Array} pDefaults
3690
+ * @param {Object} pResultObject
3691
+ * @param {Object} pDataSourceObject
3692
+ * @param {import('manyfest')} [pManifest]
3693
+ */_prepareDirectiveParameters(pParameters,pDefaults,pResultObject,pDataSourceObject,pManifest){const tmpResults=[];for(let i=0;i<pParameters.length;i++){const tmpParameter=pParameters[i];let tmpValue=this.fable.Math.parsePrecise(tmpParameter,NaN);if(isNaN(tmpValue)&&typeof tmpParameter==='string'&&tmpParameter.length>0){const tmpToken=this.fable.ExpressionParser.Postfix.getTokenContainerObject(tmpParameter,'Token.Symbol');this.substituteValuesInTokenizedObjects([tmpToken],pDataSourceObject,pResultObject,pManifest);if(tmpToken.Resolved){tmpValue=tmpToken.Value;}}if(isNaN(tmpValue)&&pDefaults.length>i){tmpValue=pDefaults[i];}tmpResults.push(tmpValue);}return tmpResults;}/**
3686
3694
  * Solves the given expression using the provided data and manifest.
3687
3695
  *
3688
3696
  * @param {string} pExpression - The expression to solve.
@@ -3693,8 +3701,7 @@ this.LogNoisiness='LogNoisiness'in this.fable?this.fable.LogNoisiness:0;}/**
3693
3701
  * @returns {any} - The result of solving the expression.
3694
3702
  */solve(pExpression,pDataSourceObject,pResultObject,pManifest,pDataDestinationObject){let tmpResultsObject=typeof pResultObject==='object'?pResultObject:{};let tmpDataSourceObject=typeof pDataSourceObject==='object'?pDataSourceObject:{};let tmpDataDestinationObject=typeof pDataDestinationObject==='object'?pDataDestinationObject:{};// This is technically a "pre-compile" and we can keep this Results Object around to reuse for better performance. Not required.
3695
3703
  this.tokenize(pExpression,tmpResultsObject);// Lint the tokenized expression to make sure it's valid
3696
- this.lintTokenizedExpression(tmpResultsObject.RawTokens,tmpResultsObject);this.buildPostfixedSolveList(tmpResultsObject.RawTokens,tmpResultsObject);if(tmpResultsObject.SolverDirectives.Code=='SERIES'){// Make sure tmpResultsObject.SolverDirective values for From: null, To: null, Step: null are all numeric and non-zero where applicable
3697
- let tmpFrom=this.fable.Math.parsePrecise(tmpResultsObject.SolverDirectives.From,NaN);let tmpTo=this.fable.Math.parsePrecise(tmpResultsObject.SolverDirectives.To,NaN);let tmpStep=this.fable.Math.parsePrecise(tmpResultsObject.SolverDirectives.Step,NaN);if(isNaN(tmpStep)){tmpStep='1';}if(isNaN(tmpFrom)||isNaN(tmpTo)){tmpResultsObject.ExpressionParserLog.push(`ExpressionParser.solve detected invalid SERIES directive parameters. FROM, TO must be numeric.`);this.log.warn(tmpResultsObject.ExpressionParserLog[tmpResultsObject.ExpressionParserLog.length-1]);return null;}// Make sure from/to are not equal
3704
+ this.lintTokenizedExpression(tmpResultsObject.RawTokens,tmpResultsObject);this.buildPostfixedSolveList(tmpResultsObject.RawTokens,tmpResultsObject);if(tmpResultsObject.SolverDirectives.Code=='SERIES'){const[tmpStep,tmpFrom,tmpTo]=this._prepareDirectiveParameters([tmpResultsObject.SolverDirectives.Step,tmpResultsObject.SolverDirectives.From,tmpResultsObject.SolverDirectives.To],['1'],tmpResultsObject,tmpDataSourceObject,pManifest);if(isNaN(tmpFrom)||isNaN(tmpTo)){tmpResultsObject.ExpressionParserLog.push(`ExpressionParser.solve detected invalid SERIES directive parameters. FROM, TO must be numeric.`);this.log.warn(tmpResultsObject.ExpressionParserLog[tmpResultsObject.ExpressionParserLog.length-1]);return null;}// Make sure from/to are not equal
3698
3705
  if(this.fable.Math.comparePrecise(tmpFrom,tmpTo)==0){tmpResultsObject.ExpressionParserLog.push(`ExpressionParser.solve detected invalid SERIES directive parameters. FROM and TO cannot be equal.`);this.log.warn(tmpResultsObject.ExpressionParserLog[tmpResultsObject.ExpressionParserLog.length-1]);return null;}// Make sure that Step is the correct positive/negative based on From and To
3699
3706
  if(this.fable.Math.comparePrecise(tmpStep,'0')==0){tmpResultsObject.ExpressionParserLog.push(`ExpressionParser.solve detected invalid SERIES directive parameters. STEP cannot be zero.`);this.log.warn(tmpResultsObject.ExpressionParserLog[tmpResultsObject.ExpressionParserLog.length-1]);return null;}if(this.fable.Math.comparePrecise(tmpFrom,tmpTo)<0){// From < To so Step must be positive
3700
3707
  if(this.fable.Math.comparePrecise(tmpStep,'0')<0){tmpResultsObject.ExpressionParserLog.push(`ExpressionParser.solve detected invalid SERIES directive parameters. STEP must be positive when FROM < TO.`);this.log.warn(tmpResultsObject.ExpressionParserLog[tmpResultsObject.ExpressionParserLog.length-1]);return null;}}else{// From >= To so Step must be negative
@@ -3702,26 +3709,62 @@ if(this.fable.Math.comparePrecise(tmpStep,'0')>0){tmpResultsObject.ExpressionPar
3702
3709
  let tmpIterations=parseInt(this.fable.Math.floorPrecise(this.fable.Math.dividePrecise(this.fable.Math.subtractPrecise(tmpTo,tmpFrom),tmpStep)));let tmpValueArray=[];for(let i=0;i<=tmpIterations;i++){let tmpCurrentValueOfN=this.fable.Math.addPrecise(tmpFrom,this.fable.Math.multiplyPrecise(tmpStep,i.toString()));// Jimmy up the data source with the current N value, stepIndex and all the other data from the source object
3703
3710
  // This generates a data source object every time on purpose so we can remarshal in values that changed in the destination
3704
3711
  let tmpSeriesStepDataSourceObject=Object.assign({},tmpDataSourceObject);tmpSeriesStepDataSourceObject.n=tmpCurrentValueOfN;tmpSeriesStepDataSourceObject.stepIndex=i;let tmpMutatedValues=this.substituteValuesInTokenizedObjects(tmpResultsObject.PostfixTokenObjects,tmpSeriesStepDataSourceObject,tmpResultsObject,pManifest);tmpValueArray.push(this.solvePostfixedExpression(tmpResultsObject.PostfixSolveList,tmpDataDestinationObject,tmpResultsObject,pManifest));for(let j=0;j<tmpMutatedValues.length;j++){tmpMutatedValues[j].Resolved=false;}}// Do the assignment
3705
- let tmpAssignmentManifestHash=tmpResultsObject.PostfixedAssignmentAddress;if(tmpResultsObject.OriginalRawTokens[1]==='='&&typeof tmpResultsObject.OriginalRawTokens[0]==='string'&&tmpResultsObject.OriginalRawTokens[0].length>0){tmpAssignmentManifestHash=tmpResultsObject.OriginalRawTokens[0];}let tmpManifest=typeof pManifest==='object'?pManifest:this.fable.newManyfest();tmpManifest.setValueByHash(tmpDataDestinationObject,tmpAssignmentManifestHash,tmpValueArray);return tmpValueArray;}else// For 'SOLVE' or anything else that didn't work
3712
+ let tmpAssignmentManifestHash=tmpResultsObject.PostfixedAssignmentAddress;if(tmpResultsObject.OriginalRawTokens[1]==='='&&typeof tmpResultsObject.OriginalRawTokens[0]==='string'&&tmpResultsObject.OriginalRawTokens[0].length>0){tmpAssignmentManifestHash=tmpResultsObject.OriginalRawTokens[0];}let tmpManifest=typeof pManifest==='object'?pManifest:this.fable.newManyfest();tmpManifest.setValueByHash(tmpDataDestinationObject,tmpAssignmentManifestHash,tmpValueArray);return tmpValueArray;}else if(tmpResultsObject.SolverDirectives.Code=='MONTECARLO'){const[tmpSampleCount]=this._prepareDirectiveParameters([tmpResultsObject.SolverDirectives.SampleCount],['1'],tmpResultsObject,tmpDataSourceObject,pManifest);if(isNaN(tmpSampleCount)){tmpResultsObject.ExpressionParserLog.push(`ExpressionParser.solve detected invalid MONTECARLO directive parameters. SAMPLECOUNT must be numeric.`);this.log.warn(tmpResultsObject.ExpressionParserLog[tmpResultsObject.ExpressionParserLog.length-1]);return null;}let tmpMonteCarloOutput=JSON.parse(JSON.stringify(tmpResultsObject.SolverDirectives));tmpMonteCarloOutput.Samples=[];// Now go through each variable and prepare its object of values
3713
+ let tmpVariableKeys=Object.keys(tmpMonteCarloOutput.Values);for(let i=0;i<tmpVariableKeys.length;i++){let tmpVariableKey=tmpVariableKeys[i];let tmpVariableDescription=tmpMonteCarloOutput.Values[tmpVariableKey];// For each variable, generate its array of sampled values
3714
+ tmpVariableDescription.Distribution={};tmpVariableDescription.ValueSequence=[];// Resolve the points if they are tokenized expressions
3715
+ const tmpResolvedPoints=[];for(let j=0;j<tmpVariableDescription.Points.length;j++){let tmpPointToken=tmpVariableDescription.Points[j];let tmpPointValue=this.fable.Math.parsePrecise(tmpPointToken,NaN);if(isNaN(tmpPointValue)&&typeof tmpPointToken==='string'&&tmpPointToken.length>0){tmpPointValue=pManifest.getValueByHash(tmpDataSourceObject,tmpPointToken);if(!tmpPointValue||tmpPointValue==null){//TODO: Warn?
3716
+ }else{tmpResolvedPoints.push(tmpPointValue);}}else{tmpResolvedPoints.push(tmpPointToken);}}// Now sort the resolved points
3717
+ tmpResolvedPoints.sort((a,b)=>this.fable.Math.comparePrecise(a,b));tmpVariableDescription.ResolvedPoints=tmpResolvedPoints;// Just simple linear until we add more easing types in a separate library (refactoring the below out)
3718
+ tmpVariableDescription.FirstPoint=tmpVariableDescription.ResolvedPoints[0];tmpVariableDescription.DomainRangeStart=tmpVariableDescription.FirstPoint;if(tmpVariableDescription.ResolvedPoints.length<2){tmpVariableDescription.LastPoint=tmpVariableDescription.FirstPoint;}else{tmpVariableDescription.LastPoint=this.fable.Math.parsePrecise(tmpVariableDescription.ResolvedPoints[tmpVariableDescription.ResolvedPoints.length-1],NaN);if(isNaN(tmpVariableDescription.LastPoint)){tmpVariableDescription.LastPoint=tmpVariableDescription.FirstPoint;}}tmpVariableDescription.DomainLength=this.fable.Math.subtractPrecise(tmpVariableDescription.LastPoint,tmpVariableDescription.FirstPoint);//this.fable.log.trace(`Monte Carlo variable ${tmpVariableKey} has first point ${tmpVariableDescription.FirstPoint}, last point ${tmpVariableDescription.LastPoint}, domain length ${tmpVariableDescription.DomainLength}`);
3719
+ // // This generation of data based on the resolved points (and easing type) should be abstracted. Most require the same rules.
3720
+ // tmpVariableDescription.ResolvedPointDomainStarts = [];
3721
+ // tmpVariableDescription.DomainTranslationAmount = [];
3722
+ // // Get the length of each domain segment and the multiplier for them
3723
+ // tmpVariableDescription.DomainLength = this.fable.Math.subtractPrecise(tmpVariableDescription.ResolvedPoints[tmpVariableDescription.ResolvedPoints.length - 1], tmpVariableDescription.ResolvedPoints[0]);
3724
+ // tmpVariableDescription.DomainChunkCount = tmpVariableDescription.ResolvedPoints.length;
3725
+ // tmpVariableDescription.DomainStart = tmpVariableDescription.ResolvedPoints[0];
3726
+ // let tmpCurrentDomainPosition = tmpVariableDescription.DomainStart;
3727
+ // let tmpPreviousDomainTranslationAmount = '0';
3728
+ // for (let j = 0; j < tmpVariableDescription.ResolvedPoints.length; j++)
3729
+ // {
3730
+ // let tmpResolvedPointValue = tmpVariableDescription.ResolvedPoints[j];
3731
+ // // Set the resolved point domain start
3732
+ // tmpVariableDescription.DomainTranslationAmount.push(this.fable.Math.dividePrecise(tmpResolvedPointValue, tmpVariableDescription.DomainLength));
3733
+ // // Push the previous translation amount as the start of this domain
3734
+ // tmpVariableDescription.ResolvedPointDomainStarts.push(tmpPreviousDomainTranslationAmount);
3735
+ // // Calculate the translation amount, for the start of the next domain
3736
+ // tmpPreviousDomainTranslationAmount = this.fable.Math.addPrecise(tmpPreviousDomainTranslationAmount, tmpVariableDescription.DomainLength);
3737
+ // }
3738
+ }for(let i=0;i<=tmpSampleCount-1;i++){// Jimmy up the data source with the current N value, stepIndex and all the other data from the source object
3739
+ // This generates a data source object every time on purpose so we can remarshal in values that changed in the destination
3740
+ let tmpSeriesStepDataSourceObject=Object.assign({},tmpDataSourceObject);tmpSeriesStepDataSourceObject.stepIndex=i;// Generate each value from the array of values
3741
+ for(let j=0;j<tmpVariableKeys.length;j++){let tmpPointManifestHash=tmpVariableKeys[j];let tmpPointManifest=tmpMonteCarloOutput.Values[tmpPointManifestHash];let tmpPointValue=this.fable.Math.generateValueFromEasingDescription(tmpPointManifest);tmpSeriesStepDataSourceObject[tmpVariableKeys[j]]=tmpPointValue;// Log the value out
3742
+ this.fable.log.info(`Monte Carlo variable ${tmpPointManifestHash} generated value ${tmpPointValue}`);if(!(tmpPointValue in tmpPointManifest.Distribution)){tmpPointManifest.Distribution[tmpPointValue]=0;}tmpPointManifest.Distribution[tmpPointValue]++;tmpPointManifest.ValueSequence.push(tmpPointValue);}let tmpMutatedValues=this.substituteValuesInTokenizedObjects(tmpResultsObject.PostfixTokenObjects,tmpSeriesStepDataSourceObject,tmpResultsObject,pManifest);tmpMonteCarloOutput.Samples.push(this.solvePostfixedExpression(tmpResultsObject.PostfixSolveList,tmpDataDestinationObject,tmpResultsObject,pManifest));for(let j=0;j<tmpMutatedValues.length;j++){tmpMutatedValues[j].Resolved=false;}}// Do the assignment
3743
+ let tmpAssignmentManifestHash=tmpResultsObject.PostfixedAssignmentAddress;if(tmpResultsObject.OriginalRawTokens[1]==='='&&typeof tmpResultsObject.OriginalRawTokens[0]==='string'&&tmpResultsObject.OriginalRawTokens[0].length>0){tmpAssignmentManifestHash=tmpResultsObject.OriginalRawTokens[0];}let tmpManifest=typeof pManifest==='object'?pManifest:this.fable.newManyfest();tmpManifest.setValueByHash(tmpDataDestinationObject,tmpAssignmentManifestHash,tmpMonteCarloOutput);return tmpMonteCarloOutput;}else// For 'SOLVE' or anything else that didn't work
3706
3744
  {// This is where the data from variables gets marshaled into their symbols (from AppData or the like)
3707
3745
  this.substituteValuesInTokenizedObjects(tmpResultsObject.PostfixTokenObjects,tmpDataSourceObject,tmpResultsObject,pManifest);// Finally this is the expr solving method, which returns a string and also marshals it into tmpDataDestinationObject
3708
3746
  return this.solvePostfixedExpression(tmpResultsObject.PostfixSolveList,tmpDataDestinationObject,tmpResultsObject,pManifest);}}}module.exports=FableServiceExpressionParser;},{"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-ExpressionTokenizer-DirectiveMutation.js":160,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-ExpressionTokenizer.js":161,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-FunctionMap.json":162,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-Linter.js":163,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-Messaging.js":164,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-Postfix.js":165,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-SolvePostfixedExpression.js":166,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-TokenMap.json":167,"./Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-ValueMarshal.js":168,"fable-serviceproviderbase":59}],159:[function(require,module,exports){const libFableServiceProviderBase=require('fable-serviceproviderbase');class ExpressionParserOperationBase extends libFableServiceProviderBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParserOperationBase';this.numberTest=/^-{0,1}\d*\.{0,1}\d+$/;this.ExpressionParser=false;}connectExpressionParser(pExpressionParser){this.ExpressionParser=pExpressionParser;}getTokenType(pToken){if(pToken in this.ExpressionParser.tokenMap){return`Token.${this.ExpressionParser.tokenMap[pToken].Type}`;}else if(pToken.length>2&&pToken[0]==='{'&&pToken[pToken.length-1]==='}'){return'Token.StateAddress';}else if(pToken.length>2&&pToken[0]==='"'&&pToken[pToken.length-1]==='"'){return'Token.String';}else if(this.numberTest.test(pToken)){return'Token.Constant';}else{return'Token.Symbol';}// Just for documentation sake:
3709
3747
  // There is a fifth token type, VirtualSymbol
3710
3748
  // This is a value that's added during solve and looked up by address in the VirtualSymbol object.
3711
- }getTokenContainerObject(pToken,pTokenType){return{Token:pToken,Type:typeof pTokenType==='undefined'?this.getTokenType(pToken):pTokenType,Descriptor:pToken in this.ExpressionParser.tokenMap?this.ExpressionParser.tokenMap[pToken]:false};}}module.exports=ExpressionParserOperationBase;},{"fable-serviceproviderbase":59}],160:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionTokenizerDirectiveMutation extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-TokenizerDirectiveMutation';this.directiveTypes={'SOLVE':{Name:'Solve Expression',Code:'SOLVE'},'SERIES':{Name:'Series',Code:'SERIES',From:null,To:null,Step:null},'MONTECARLO':{Name:'Monte Carlo Simulation',Code:'MONTECARLO',Iterations:null,Values:{}}};this.defaultDirective=this.directiveTypes.SOLVE;}parseSeriesDirective(pTokens){// This isn't a fancy real parse it's just taking words and stealing values after them.
3749
+ }getTokenContainerObject(pToken,pTokenType){return{Token:pToken,Type:typeof pTokenType==='undefined'?this.getTokenType(pToken):pTokenType,Descriptor:pToken in this.ExpressionParser.tokenMap?this.ExpressionParser.tokenMap[pToken]:false};}}module.exports=ExpressionParserOperationBase;},{"fable-serviceproviderbase":59}],160:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionTokenizerDirectiveMutation extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-TokenizerDirectiveMutation';this.directiveTypes={'SOLVE':{Name:'Solve Expression',Code:'SOLVE'},'SERIES':{Name:'Series',Code:'SERIES',From:null,To:null,Step:null},'MONTECARLO':{Name:'Monte Carlo Simulation',SampleCount:'1',Code:'MONTECARLO',Values:{}}};this.defaultDirective=this.directiveTypes.SOLVE;}parseSeriesDirective(pTokens){// This isn't a fancy real parse it's just taking words and stealing values after them.
3712
3750
  let tmpNewSeriesDirectiveDescription=Object.assign({},this.directiveTypes.SERIES);for(let i=0;i<pTokens.length;i++){let tmpToken=pTokens[i].toUpperCase();switch(tmpToken){case'FROM':if(i+1<pTokens.length){tmpNewSeriesDirectiveDescription.From=pTokens[i+1];}break;case'TO':if(i+1<pTokens.length){tmpNewSeriesDirectiveDescription.To=pTokens[i+1];}break;case'STEP':if(i+1<pTokens.length){tmpNewSeriesDirectiveDescription.Step=pTokens[i+1];}break;default:// Ignore other tokens
3751
+ break;}}return tmpNewSeriesDirectiveDescription;}parseMonteCarloDirective(pTokens){// This isn't a fancy real parse it's just taking words and stealing values after them.
3752
+ let tmpNewSeriesDirectiveDescription=Object.assign({},this.directiveTypes.MONTECARLO);for(let i=0;i<pTokens.length;i++){let tmpToken=pTokens[i].toUpperCase();switch(tmpToken){case'SAMPLECOUNT':if(i+1<pTokens.length){tmpNewSeriesDirectiveDescription.SampleCount=pTokens[i+1];}i=i+1;break;case'VARIABLE':case'VAR':case'V':if(i+1<pTokens.length){let tmpVariableToken=pTokens[i+1];if(typeof tmpVariableToken==='string'&&tmpVariableToken.length>0){tmpNewSeriesDirectiveDescription.Values[tmpVariableToken]={Token:tmpVariableToken,Easing:'Linear',// could be parametric, logarithmic, bezier, uniform, normal, etc.
3753
+ Points:[]// array of values for points to generate between.
3754
+ };}}i=i+1;break;case'POINT':case'PT':case'P':if(pTokens.length<i+2){continue;}let tmpVariableToken=pTokens[i+1];if(tmpVariableToken in tmpNewSeriesDirectiveDescription.Values){let tmpVariableValue=this.fable.Math.parsePrecise(pTokens[i+2],NaN);if(!isNaN(tmpVariableValue))tmpNewSeriesDirectiveDescription.Values[tmpVariableToken].Points.push(tmpVariableValue);}i=i+2;break;case'EASING':if(pTokens.length<i+2){continue;}tmpVariableToken=pTokens[i+1];let tmpEasingType=pTokens[i+2].toUpperCase();if(tmpVariableToken in tmpNewSeriesDirectiveDescription.Values){tmpNewSeriesDirectiveDescription.Values[tmpVariableToken].Easing=tmpEasingType;}i=i+2;break;default:// Ignore other tokens
3713
3755
  break;}}return tmpNewSeriesDirectiveDescription;}parseDirectives(pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.SolverDirectives=this.defaultDirective;tmpResults.SolverDirectiveTokens=[];if(tmpResults.RawTokens.length<2){tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenizeDirectiveMutation postprocessor received insufficient tokens to process directives.`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.SolverDirectives;}// Enumerate each of the tmpResults.RawTokens to see if one of the values in the directiveTypeMap exists and is either at the beginning or after the assignment (= or ?=) operator
3714
3756
  for(let i=0;i<tmpResults.RawTokens.length;i++){let tmpToken=tmpResults.RawTokens[i].toUpperCase();if(tmpToken in this.directiveTypes){// Check if it's at the beginning or after an assignment operator
3715
3757
  // FIXME: This is hard coded assignment operators which is bad juju
3716
3758
  if(i===0||tmpResults.RawTokens[i-1]==='='||tmpResults.RawTokens[i-1]==='?='){// We have a directive!
3717
- tmpResults.SolverDirectives.Type=this.directiveTypes[tmpToken];tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenizeDirectiveMutation identified solver directive: ${tmpToken}`);this.log.info(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);// Extract the Directive name and everything else from it up until the : token
3759
+ tmpResults.SolverDirectives.Type=this.directiveTypes[tmpToken];tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenizeDirectiveMutation identified solver directive: ${tmpToken}`);//this.log.info(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);
3760
+ // Extract the Directive name and everything else from it up until the : token
3718
3761
  let tmpDirectiveTokenStartIndex=i;let tmpDirectiveTokenEndIndex=-1;for(let j=tmpDirectiveTokenStartIndex+1;j<tmpResults.RawTokens.length;j++){if(tmpResults.RawTokens[j]===':'){tmpDirectiveTokenEndIndex=j;break;}}// If the directive token end is not in the expression we don't know what to do
3719
3762
  if(tmpDirectiveTokenEndIndex===-1){tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenizeDirectiveMutation could not find the end of the directive token set for directive: ${tmpToken}`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);continue;}// Set the tmpResults.SolverDirectiveTokens to the slice of tokens that represent the directive
3720
3763
  tmpResults.SolverDirectiveTokens=tmpResults.RawTokens.slice(tmpDirectiveTokenStartIndex,tmpDirectiveTokenEndIndex);// Remove the directive tokens and the assignment to the left of it from the array of raw tokens
3721
3764
  // the colonoscopy if you will
3722
3765
  tmpResults.RawTokens.splice(0,tmpDirectiveTokenEndIndex+1);// Further parsing based on directive type could go here
3723
3766
  // e.g. parseSeriesDirective for SERIES, etc.
3724
- switch(tmpToken){case'SERIES':tmpResults.SolverDirectives=this.parseSeriesDirective(tmpResults.SolverDirectiveTokens);break;default:// No further parsing needed
3767
+ switch(tmpToken){case'SERIES':tmpResults.SolverDirectives=this.parseSeriesDirective(tmpResults.SolverDirectiveTokens);break;case'MONTECARLO':tmpResults.SolverDirectives=this.parseMonteCarloDirective(tmpResults.SolverDirectiveTokens);break;default:// No further parsing needed
3725
3768
  break;}}}}return tmpResults.SolverDirectives;}}module.exports=ExpressionTokenizerDirectiveMutation;},{"./Fable-Service-ExpressionParser-Base.js":159}],161:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionTokenizer extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Tokenizer';}tokenize(pExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.RawExpression=pExpression;tmpResults.SolverDirectives={};tmpResults.RawTokens=[];tmpResults.ExpressionParserLog=[];if(typeof pExpression!=='string'){this.log.warn('ExpressionParser.tokenize was passed a non-string expression.');return tmpResults.RawTokens;}/* Tokenize the expression
3726
3769
  *
3727
3770
  * Current token types:
@@ -3776,14 +3819,15 @@ tmpCurrentTokenType='Value';tmpCurrentToken+=tmpCharacter;// continue;
3776
3819
  // tmpResults.ExpressionParserLog.push(`ExpressionParser.tokenize found an unknown character code ${tmpCharCode} character ${tmpCharacter} in the expression: ${pExpression} at index ${i}`);
3777
3820
  // this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);
3778
3821
  }if(tmpCurrentTokenType&&tmpCurrentToken.length>0){tmpResults.RawTokens.push(tmpCurrentToken);}tmpResults.OriginalRawTokens=Array.from(tmpResults.RawTokens);// Potentially mutate the tokens based on directives in the tokenized expression
3779
- this.TokenizerDirectiveMutation.parseDirectives(tmpResults);return tmpResults.RawTokens;}}module.exports=ExpressionTokenizer;},{"./Fable-Service-ExpressionParser-Base.js":159}],162:[function(require,module,exports){module.exports={"sqrt":{"Name":"Square Root","Address":"fable.Math.sqrtPrecise"},"percent":{"Name":"Compute Percent (in IS over OF format)","Address":"fable.Math.percentagePrecise"},"compare":{"Name":"Compare","Address":"fable.Math.comparePrecise"},"abs":{"Name":"Absolute Value","Address":"fable.Math.absPrecise"},"floor":{"Name":"Floor Value","Address":"fable.Math.floorPrecise"},"ceil":{"Name":"Ceiling Value","Address":"fable.Math.ceilPrecise"},"rad":{"Name":"Degrees to Radians","Address":"fable.Math.radPrecise"},"pi":{"Name":"Pi","Address":"fable.Math.piPrecise"},"euler":{"Name":"Euler","Address":"fable.Math.eulerPrecise"},"log":{"Name":"Logarithm","Address":"fable.Math.logPrecise"},"exp":{"Name":"Eulers Number to the Power Of N","Address":"fable.Math.expPrecise"},"sin":{"Name":"Sine","Address":"fable.Math.sin"},"cos":{"Name":"Cosine","Address":"fable.Math.cos"},"tan":{"Name":"Tangent","Address":"fable.Math.tan"},"count":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"countset":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"sortset":{"Name":"Sort Set","Address":"fable.Math.sortSetPrecise"},"bucketset":{"Name":"Bucket Set","Address":"fable.Math.bucketSetPrecise"},"sorthistogram":{"Name":"Sort Histogram","Address":"fable.Math.sortHistogramPrecise"},"sorthistogrambykeys":{"Name":"Sort Histogram by Keys","Address":"fable.Math.sortHistogramByKeys"},"max":{"Name":"Maximum","Address":"fable.Math.maxPrecise"},"min":{"Name":"Minimum","Address":"fable.Math.minPrecise"},"sum":{"Name":"Sum","Address":"fable.Math.sumPrecise"},"avg":{"Name":"Average","Address":"fable.Math.averagePrecise"},"mean":{"Name":"Mean","Address":"fable.Math.meanPrecise"},"median":{"Name":"Median","Address":"fable.Math.medianPrecise"},"mode":{"Name":"Mode","Address":"fable.Math.modePrecise"},"round":{"Name":"Round","Address":"fable.Math.roundPrecise"},"tofixed":{"Name":"To Fixed","Address":"fable.Math.toFixedPrecise"},"cumulativesummation":{"Name":"Sum each value in a Histogram or Value Map cumulatively, creating or setting a property with the result on each row","Address":"fable.Math.cumulativeSummation"},"subtractingsummation":{"Name":"Subtract each subsequent value in a Histogram or Value Map cumulatively (by default from the first row), creating or setting a property with the result on each row.","Address":"fable.Math.subtractingSummation"},"iterativeseries":{"Name":"Perform an Iterative Series of Mathematical Operations on Set Elements","Address":"fable.Math.iterativeSeries"},"countsetelements":{"Name":"Count Set Elements in a Histogram or Value Map","Address":"fable.Math.countSetElements"},"getvalue":{"Name":"Get Value from Application State or Services (AppData, etc.)","Address":"fable.Utility.getInternalValueByHash"},"objectkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"objectvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"generatearrayofobjectsfromsets":{"Name":"Generate Array of Objects from Sets","Address":"fable.Utility.generateArrayOfObjectsFromSets"},"objectvaluessortbyexternalobjectarray":{"Name":"Get Array of an Object's values sorted by an external array","Address":"fable.Utility.objectValuesSortByExternalArray"},"setkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"setvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"histogramkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"histogramvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"createarrayfromabsolutevalues":{"Name":"Create Array from Absolute Values","Address":"fable.Utility.createArrayFromAbsoluteValues"},"flatten":{"Name":"flatten an array of values","Address":"fable.Utility.flattenArrayOfSolverInputs"},"findfirstvaluebyexactmatch":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByExactMatchInternal"},"findfirstvaluebystringincludes":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByStringIncludesInternal"},"resolvehtmlentities":{"Name":"resolve HTML entities","Address":"fable.DataFormat.resolveHtmlEntities"},"concat":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsInternal"},"concatraw":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsRawInternal"},"join":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsInternal"},"joinraw":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsRawInternal"},"if":{"Name":"perform a conditional operator on two values, and choose one of two outcomes based on the result","Address":"fable.Logic.checkIf"},"when":{"Name":"perform a 'truthy' check on one value, and return one of two outcomes based on the result","Address":"fable.Logic.when"},"entryinset":{"Name":"Entry in Set","Address":"fable.Math.entryInSet"},"smallestinset":{"Name":"Smallest in Set","Address":"fable.Math.smallestInSet"},"largestinset":{"Name":"Largest in Set","Address":"fable.Math.largestInSet"},"aggregationhistogram":{"Name":"Generate a Histogram by Exact Value Aggregation","Address":"fable.Math.histogramAggregationByExactValueFromInternalState"},"aggregationhistogrambyobject":{"Name":"Generate a Histogram by Exact Value Aggregation from Object Property","Address":"fable.Math.histogramAggregationByExactValue"},"distributionhistogram":{"Name":"Generate a Histogram Based on Value Distribution","Address":"fable.Math.histogramDistributionByExactValueFromInternalState"},"distributionhistogrambyobject":{"Name":"Generate a Histogram Based on Value Distribution from Object Property","Address":"fable.Math.histogramDistributionByExactValue"},"setconcatenate":{"Name":"Set Concatenate","Address":"fable.Math.setConcatenate"},"getvaluearray":{"Name":"Get Value Array from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueArrayByHashParametersFromInternal"},"getvalueobject":{"Name":"Get Value Object from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueObjectByHashParametersFromInternal"},"cleanvaluearray":{"Name":"Clean Value Array","Address":"fable.Math.cleanValueArray"},"cleanvalueobject":{"Name":"Clean Value Object","Address":"fable.Math.cleanValueObject"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"randominteger":{"Name":"Random Integer","Address":"fable.DataGeneration.randomInteger"},"randomintegerbetween":{"Name":"Random Integer Between Two Numbers","Address":"fable.DataGeneration.randomIntegerBetween"},"randomintegerupto":{"Name":"Random Integer","Address":"fable.DataGeneration.randomIntegerUpTo"},"randomfloat":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloat"},"randomfloatbetween":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatBetween"},"randomfloatupto":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatUpTo"},"datemilliseconddifference":{"Name":"Date Difference in Milliseconds","Address":"fable.Dates.dateMillisecondDifference"},"dateseconddifference":{"Name":"Date Difference in Seconds","Address":"fable.Dates.dateSecondDifference"},"dateminutedifference":{"Name":"Date Difference in Minutes","Address":"fable.Dates.dateMinuteDifference"},"datehourdifference":{"Name":"Date Difference in Hours","Address":"fable.Dates.dateHourDifference"},"datedaydifference":{"Name":"Date Difference in Days","Address":"fable.Dates.dateDayDifference"},"dateweekdifference":{"Name":"Date Difference in Weeks","Address":"fable.Dates.dateWeekDifference"},"datemonthdifference":{"Name":"Date Difference in Months","Address":"fable.Dates.dateMonthDifference"},"dateyeardifference":{"Name":"Date Difference in Years","Address":"fable.Dates.dateYearDifference"},"datemathadd":{"Name":"Date Math Add","Address":"fable.Dates.dateMath"},"dateaddmilliseconds":{"Name":"Date Add Milliseconds","Address":"fable.Dates.dateAddMilliseconds"},"dateaddseconds":{"Name":"Date Add Seconds","Address":"fable.Dates.dateAddSeconds"},"dateaddminutes":{"Name":"Date Add Minutes","Address":"fable.Dates.dateAddMinutes"},"dateaddhours":{"Name":"Date Add Hours","Address":"fable.Dates.dateAddHours"},"dateadddays":{"Name":"Date Add Days","Address":"fable.Dates.dateAddDays"},"dateaddweeks":{"Name":"Date Add Weeks","Address":"fable.Dates.dateAddWeeks"},"dateaddmonths":{"Name":"Date Add Months","Address":"fable.Dates.dateAddMonths"},"dateaddyears":{"Name":"Date Add Years","Address":"fable.Dates.dateAddYears"},"datefromparts":{"Name":"Date From Parts","Address":"fable.Dates.dateFromParts"},"createvalueobjectbyhashes":{"Name":"Create Value Object by Hashes","Address":"fable.Utility.createValueObjectByHashes"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"leastsquares":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"linest":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"matrixtranspose":{"Name":"Transpose a Matrix","Address":"fable.Math.matrixTranspose"},"matrixmultiply":{"Name":"Multiply Two Matrices","Address":"fable.Math.matrixMultiply"},"matrixvectormultiply":{"Name":"Multiply a Matrix by a Vector","Address":"fable.Math.matrixVectorMultiply"},"matrixinverse":{"Name":"Inverse a Matrix","Address":"fable.Math.matrixInverse"},"gaussianelimination":{"Name":"Solve a System of Linear Equations using Gaussian Elimination","Address":"fable.Math.gaussianElimination"}};},{}],163:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionParserLinter extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Linter';}lintTokenizedExpression(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.LinterResults=[];// Guard against bad data being passed in
3822
+ this.TokenizerDirectiveMutation.parseDirectives(tmpResults);return tmpResults.RawTokens;}}module.exports=ExpressionTokenizer;},{"./Fable-Service-ExpressionParser-Base.js":159}],162:[function(require,module,exports){module.exports={"sqrt":{"Name":"Square Root","Address":"fable.Math.sqrtPrecise"},"percent":{"Name":"Compute Percent (in IS over OF format)","Address":"fable.Math.percentagePrecise"},"compare":{"Name":"Compare","Address":"fable.Math.comparePrecise"},"abs":{"Name":"Absolute Value","Address":"fable.Math.absPrecise"},"floor":{"Name":"Floor Value","Address":"fable.Math.floorPrecise"},"ceil":{"Name":"Ceiling Value","Address":"fable.Math.ceilPrecise"},"rad":{"Name":"Degrees to Radians","Address":"fable.Math.radPrecise"},"pi":{"Name":"Pi","Address":"fable.Math.piPrecise"},"euler":{"Name":"Euler","Address":"fable.Math.eulerPrecise"},"log":{"Name":"Logarithm","Address":"fable.Math.logPrecise"},"exp":{"Name":"Eulers Number to the Power Of N","Address":"fable.Math.expPrecise"},"sin":{"Name":"Sine","Address":"fable.Math.sin"},"cos":{"Name":"Cosine","Address":"fable.Math.cos"},"tan":{"Name":"Tangent","Address":"fable.Math.tan"},"count":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"countset":{"Name":"Count Set Elements","Address":"fable.Math.countSetElements"},"sortset":{"Name":"Sort Set","Address":"fable.Math.sortSetPrecise"},"bucketset":{"Name":"Bucket Set","Address":"fable.Math.bucketSetPrecise"},"sorthistogram":{"Name":"Sort Histogram","Address":"fable.Math.sortHistogramPrecise"},"sorthistogrambykeys":{"Name":"Sort Histogram by Keys","Address":"fable.Math.sortHistogramByKeys"},"max":{"Name":"Maximum","Address":"fable.Math.maxPrecise"},"min":{"Name":"Minimum","Address":"fable.Math.minPrecise"},"sum":{"Name":"Sum","Address":"fable.Math.sumPrecise"},"avg":{"Name":"Average","Address":"fable.Math.averagePrecise"},"mean":{"Name":"Mean","Address":"fable.Math.meanPrecise"},"median":{"Name":"Median","Address":"fable.Math.medianPrecise"},"mode":{"Name":"Mode","Address":"fable.Math.modePrecise"},"round":{"Name":"Round","Address":"fable.Math.roundPrecise"},"tofixed":{"Name":"To Fixed","Address":"fable.Math.toFixedPrecise"},"cumulativesummation":{"Name":"Sum each value in a Histogram or Value Map cumulatively, creating or setting a property with the result on each row","Address":"fable.Math.cumulativeSummation"},"subtractingsummation":{"Name":"Subtract each subsequent value in a Histogram or Value Map cumulatively (by default from the first row), creating or setting a property with the result on each row.","Address":"fable.Math.subtractingSummation"},"iterativeseries":{"Name":"Perform an Iterative Series of Mathematical Operations on Set Elements","Address":"fable.Math.iterativeSeries"},"countsetelements":{"Name":"Count Set Elements in a Histogram or Value Map","Address":"fable.Math.countSetElements"},"getvalue":{"Name":"Get Value from Application State or Services (AppData, etc.)","Address":"fable.Utility.getInternalValueByHash"},"objectkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"objectvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"generatearrayofobjectsfromsets":{"Name":"Generate Array of Objects from Sets","Address":"fable.Utility.generateArrayOfObjectsFromSets"},"objectvaluessortbyexternalobjectarray":{"Name":"Get Array of an Object's values sorted by an external array","Address":"fable.Utility.objectValuesSortByExternalArray"},"setkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"setvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"histogramkeystoarray":{"Name":"Get Array of an Object's keys","Address":"fable.Utility.objectKeysToArray"},"histogramvaluestoarray":{"Name":"Get Array of an Object's values","Address":"fable.Utility.objectValuesToArray"},"createarrayfromabsolutevalues":{"Name":"Create Array from Absolute Values","Address":"fable.Utility.createArrayFromAbsoluteValues"},"flatten":{"Name":"flatten an array of values","Address":"fable.Utility.flattenArrayOfSolverInputs"},"findfirstvaluebyexactmatch":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByExactMatchInternal"},"findfirstvaluebystringincludes":{"Name":"find + map on array of objects","Address":"fable.Utility.findFirstValueByStringIncludesInternal"},"match":{"Name":"Implementation of sheets MATCH() function","Address":"fable.Utility.findIndexInternal"},"resolvehtmlentities":{"Name":"resolve HTML entities","Address":"fable.DataFormat.resolveHtmlEntities"},"concat":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsInternal"},"concatraw":{"Name":"concatenate an array of values and output a string","Address":"fable.DataFormat.concatenateStringsRawInternal"},"join":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsInternal"},"joinraw":{"Name":"join an array of values and output a string","Address":"fable.DataFormat.joinStringsRawInternal"},"if":{"Name":"perform a conditional operator on two values, and choose one of two outcomes based on the result","Address":"fable.Logic.checkIf"},"when":{"Name":"perform a 'truthy' check on one value, and return one of two outcomes based on the result","Address":"fable.Logic.when"},"entryinset":{"Name":"Entry in Set","Address":"fable.Math.entryInSet"},"smallestinset":{"Name":"Smallest in Set","Address":"fable.Math.smallestInSet"},"largestinset":{"Name":"Largest in Set","Address":"fable.Math.largestInSet"},"aggregationhistogram":{"Name":"Generate a Histogram by Exact Value Aggregation","Address":"fable.Math.histogramAggregationByExactValueFromInternalState"},"aggregationhistogrambyobject":{"Name":"Generate a Histogram by Exact Value Aggregation from Object Property","Address":"fable.Math.histogramAggregationByExactValue"},"distributionhistogram":{"Name":"Generate a Histogram Based on Value Distribution","Address":"fable.Math.histogramDistributionByExactValueFromInternalState"},"distributionhistogrambyobject":{"Name":"Generate a Histogram Based on Value Distribution from Object Property","Address":"fable.Math.histogramDistributionByExactValue"},"setconcatenate":{"Name":"Set Concatenate","Address":"fable.Math.setConcatenate"},"getvaluearray":{"Name":"Get Value Array from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueArrayByHashParametersFromInternal"},"getvalueobject":{"Name":"Get Value Object from Application State or Services (AppData, etc.)","Address":"fable.Utility.createValueObjectByHashParametersFromInternal"},"cleanvaluearray":{"Name":"Clean Value Array","Address":"fable.Math.cleanValueArray"},"cleanvalueobject":{"Name":"Clean Value Object","Address":"fable.Math.cleanValueObject"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"randominteger":{"Name":"Random Integer","Address":"fable.DataGeneration.randomInteger"},"randomintegerbetween":{"Name":"Random Integer Between Two Numbers","Address":"fable.DataGeneration.randomIntegerBetween"},"randomintegerupto":{"Name":"Random Integer","Address":"fable.DataGeneration.randomIntegerUpTo"},"randomfloat":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloat"},"randomfloatbetween":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatBetween"},"randomfloatupto":{"Name":"Random Float","Address":"fable.DataGeneration.randomFloatUpTo"},"datemilliseconddifference":{"Name":"Date Difference in Milliseconds","Address":"fable.Dates.dateMillisecondDifference"},"dateseconddifference":{"Name":"Date Difference in Seconds","Address":"fable.Dates.dateSecondDifference"},"dateminutedifference":{"Name":"Date Difference in Minutes","Address":"fable.Dates.dateMinuteDifference"},"datehourdifference":{"Name":"Date Difference in Hours","Address":"fable.Dates.dateHourDifference"},"datedaydifference":{"Name":"Date Difference in Days","Address":"fable.Dates.dateDayDifference"},"dateweekdifference":{"Name":"Date Difference in Weeks","Address":"fable.Dates.dateWeekDifference"},"datemonthdifference":{"Name":"Date Difference in Months","Address":"fable.Dates.dateMonthDifference"},"dateyeardifference":{"Name":"Date Difference in Years","Address":"fable.Dates.dateYearDifference"},"datemathadd":{"Name":"Date Math Add","Address":"fable.Dates.dateMath"},"dateaddmilliseconds":{"Name":"Date Add Milliseconds","Address":"fable.Dates.dateAddMilliseconds"},"dateaddseconds":{"Name":"Date Add Seconds","Address":"fable.Dates.dateAddSeconds"},"dateaddminutes":{"Name":"Date Add Minutes","Address":"fable.Dates.dateAddMinutes"},"dateaddhours":{"Name":"Date Add Hours","Address":"fable.Dates.dateAddHours"},"dateadddays":{"Name":"Date Add Days","Address":"fable.Dates.dateAddDays"},"dateaddweeks":{"Name":"Date Add Weeks","Address":"fable.Dates.dateAddWeeks"},"dateaddmonths":{"Name":"Date Add Months","Address":"fable.Dates.dateAddMonths"},"dateaddyears":{"Name":"Date Add Years","Address":"fable.Dates.dateAddYears"},"datefromparts":{"Name":"Date From Parts","Address":"fable.Dates.dateFromParts"},"createvalueobjectbyhashes":{"Name":"Create Value Object by Hashes","Address":"fable.Utility.createValueObjectByHashes"},"polynomialregression":{"Name":"Perform an nth degree Polynomial Regression on a Set of X and Y Values","Address":"fable.Math.polynomialRegression"},"leastsquares":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"linest":{"Name":"Perform a Least Squares Regression on a Set of Independent Variable Vectors and a Dependent Variable Vector","Address":"fable.Math.leastSquares"},"matrixtranspose":{"Name":"Transpose a Matrix","Address":"fable.Math.matrixTranspose"},"matrixmultiply":{"Name":"Multiply Two Matrices","Address":"fable.Math.matrixMultiply"},"matrixvectormultiply":{"Name":"Multiply a Matrix by a Vector","Address":"fable.Math.matrixVectorMultiply"},"matrixinverse":{"Name":"Inverse a Matrix","Address":"fable.Math.matrixInverse"},"gaussianelimination":{"Name":"Solve a System of Linear Equations using Gaussian Elimination","Address":"fable.Math.gaussianElimination"}};},{}],163:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionParserLinter extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Linter';}lintTokenizedExpression(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.LinterResults=[];// Guard against bad data being passed in
3780
3823
  if(!Array.isArray(pTokenizedExpression)){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression was passed a non-array tokenized expression.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return pTokenizedExpression;}if(pTokenizedExpression.length<1){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression was passed an empty tokenized expression.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return pTokenizedExpression;}// 1. Check for balanced parenthesis
3781
3824
  let tmpParenthesisDepth=0;// If it is in a state address, we don't care about the parenthesis
3782
3825
  // State addresses are between squiggly brackets
3783
3826
  let tmpInStateAddress=false;for(let i=0;i<pTokenizedExpression.length;i++){if(pTokenizedExpression[i]==='('&&!tmpInStateAddress){tmpParenthesisDepth++;}if(pTokenizedExpression[i]===')'&&!tmpInStateAddress){tmpParenthesisDepth--;}if(pTokenizedExpression[i]==='{'){tmpInStateAddress=true;}if(pTokenizedExpression[i]==='}'){tmpInStateAddress=false;}if(tmpParenthesisDepth<0){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression found an unbalanced parenthesis in the tokenized expression at token index ${i}`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}if(tmpParenthesisDepth>0){// TODO: Should we add the closing parenthesis?
3784
3827
  tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.lintTokenizedExpression found an unbalanced parenthesis in the tokenized expression (ended without closing last set of parenthesis) -- appropriate closing parenthesis will be added.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}// 2. Check for balanced squiggly braces
3785
3828
  tmpInStateAddress=false;for(let i=0;i<pTokenizedExpression.length;i++){if(pTokenizedExpression[i]==='{'){tmpInStateAddress=true;}if(pTokenizedExpression[i]==='}'&&tmpInStateAddress){tmpInStateAddress=false;}if(pTokenizedExpression[i]==='}'&&!tmpInStateAddress){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression found an unbalanced closing squiggly brace "}" in the tokenized expression at token index ${i}`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}if(tmpInStateAddress){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.lintTokenizedExpression found an open squiggly brace in the tokenized expression at index ${i}`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}// 3. Check for an equality assignment
3786
- let tmpEqualityAssignmentCount=0;let tmpEqualityAssignmentIndex=false;for(let i=0;i<pTokenizedExpression.length;i++){if(this.ExpressionParser.tokenMap[pTokenizedExpression[i]]&&this.ExpressionParser.tokenMap[pTokenizedExpression[i]].Type==='Assignment'){tmpEqualityAssignmentCount++;tmpEqualityAssignmentIndex=i;if(tmpEqualityAssignmentCount>1){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression found multiple equality assignments in the tokenized expression; equality assignment #${tmpEqualityAssignmentCount} operator '${pTokenizedExpression[i]}' at token index ${i}.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}}if(tmpEqualityAssignmentCount<1){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.lintTokenizedExpression found no equality assignment in the tokenized expression. One called Result will be added automatically.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}// 4. Make sure the equality assignment only has a single value on the other side of it
3829
+ let tmpEqualityAssignmentCount=0;let tmpEqualityAssignmentIndex=false;for(let i=0;i<pTokenizedExpression.length;i++){if(this.ExpressionParser.tokenMap[pTokenizedExpression[i]]&&this.ExpressionParser.tokenMap[pTokenizedExpression[i]].Type==='Assignment'){tmpEqualityAssignmentCount++;tmpEqualityAssignmentIndex=i;if(tmpEqualityAssignmentCount>1){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.lintTokenizedExpression found multiple equality assignments in the tokenized expression; equality assignment #${tmpEqualityAssignmentCount} operator '${pTokenizedExpression[i]}' at token index ${i}.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}}if(tmpEqualityAssignmentCount<1){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.lintTokenizedExpression found no equality assignment in the tokenized expression. One called Result will be added automatically.`);tmpResults.LinterResults.push(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);//this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);
3830
+ }// 4. Make sure the equality assignment only has a single value on the other side of it
3787
3831
  // (no, this is not a magical algebraic solver, do your own simplification)
3788
3832
  // IF there is only one equality assignment (otherwise we don't even lint this because it's syntax errors all the way down)
3789
3833
  if(tmpEqualityAssignmentCount===1){// If there are exactly three tokens, make sure at least one is an assignable-ish address
@@ -3814,7 +3858,8 @@ if('LeftVirtualSymbolName'in tmpOperation.Operation){tmpOperation.LeftValue=this
3814
3858
  //if ('LeftVirtualSymbolName' in tmpOperation.RightValue)
3815
3859
  if('RightVirtualSymbolName'in tmpOperation.Operation){tmpOperation.RightValue=this.getTokenContainerObject(tmpOperation.Operation.RightVirtualSymbolName,'Token.VirtualSymbol');}else{tmpOperation.RightValue=this.getTokenContainerObject(tmpOperation.RightValue.VirtualSymbolName,'Token.VirtualSymbol');}}tmpOperation.Operation.Parsed=true;return tmpOperation;}buildPostfixedSolveList(pTokenizedExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.PostfixedAssignmentAddress='Result';tmpResults.PostfixedAssignmentOperator=this.ExpressionParser.tokenMap['='];// This is the default assignment operator
3816
3860
  tmpResults.PostfixTokenObjects=[];tmpResults.PostfixSolveList=[];if(pTokenizedExpression.length<3){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.buildPostfixedSolveList was passed a tokenized expression with less than three tokens.`);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixTokenObjects;}// 1. Figure out the Equality Assignment
3817
- let tmpEqualsIndex=-1;for(let i=0;i<pTokenizedExpression.length;i++){if(this.ExpressionParser.tokenMap[pTokenizedExpression[i]]&&this.ExpressionParser.tokenMap[pTokenizedExpression[i]].Type==='Assignment'){if(tmpEqualsIndex<0){tmpEqualsIndex=i;tmpResults.PostfixedAssignmentOperator=this.ExpressionParser.tokenMap[pTokenizedExpression[i]];}else{tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.buildPostfixedSolveList found multiple assignment operators in the tokenized expression; assignment operator '${pTokenizedExpression[i]}' #${tmpEqualsIndex} at token index ${i}.`);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixTokenObjects;}}}if(tmpEqualsIndex==-1){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.buildPostfixedSolveList found no equality assignment in the tokenized expression; defaulting to Result`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}else if(tmpEqualsIndex>1){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.buildPostfixedSolveList found an equality assignment in the tokenized expression at an unexpected location (token index ${tmpEqualsIndex}); the expression cannot be parsed.`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}else if(tmpEqualsIndex===0){// This is an implicit function -- just go to result and return the value.
3861
+ let tmpEqualsIndex=-1;for(let i=0;i<pTokenizedExpression.length;i++){if(this.ExpressionParser.tokenMap[pTokenizedExpression[i]]&&this.ExpressionParser.tokenMap[pTokenizedExpression[i]].Type==='Assignment'){if(tmpEqualsIndex<0){tmpEqualsIndex=i;tmpResults.PostfixedAssignmentOperator=this.ExpressionParser.tokenMap[pTokenizedExpression[i]];}else{tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.buildPostfixedSolveList found multiple assignment operators in the tokenized expression; assignment operator '${pTokenizedExpression[i]}' #${tmpEqualsIndex} at token index ${i}.`);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);return tmpResults.PostfixTokenObjects;}}}if(tmpEqualsIndex==-1){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.buildPostfixedSolveList found no equality assignment in the tokenized expression; defaulting to Result`);//this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);
3862
+ }else if(tmpEqualsIndex>1){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.buildPostfixedSolveList found an equality assignment in the tokenized expression at an unexpected location (token index ${tmpEqualsIndex}); the expression cannot be parsed.`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}else if(tmpEqualsIndex===0){// This is an implicit function -- just go to result and return the value.
3818
3863
  // That is... the user entered something like "= 5 + 3" so we should just return 8, and use the default Result quietly.
3819
3864
  }else{tmpResults.PostfixedAssignmentAddress=pTokenizedExpression[0];}// 2. Categorize tokens in the expression, put them in the "expression list" as a token object
3820
3865
  for(let i=tmpEqualsIndex+1;i<pTokenizedExpression.length;i++){tmpResults.PostfixTokenObjects.push(this.getTokenContainerObject(pTokenizedExpression[i]));}// 3. Decorate mathematical parsing depth and detect functions at the same time
@@ -3945,7 +3990,7 @@ let tmpValue=tmpManifest.getValueByHash(tmpDataSource,tmpToken.Token);// if (!tm
3945
3990
  // // If no hash resolves, try by address.
3946
3991
  // tmpValue = tmpManifest.getValueAtAddress(tmpToken.Token, tmpDataSource);
3947
3992
  // }
3948
- if(!tmpValue){tmpToken.Value=tmpValue;tmpToken.Resolve=true;tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.substituteValuesInTokenizedObjects found no value for the symbol hash or address ${tmpToken.Token} at index ${i}`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);continue;}else{tmpResults.ExpressionParserLog.push(`INFO: ExpressionParser.substituteValuesInTokenizedObjects found a value [${tmpValue}] for the state address ${tmpToken.Token} at index ${i}`);if(this.LogNoisiness>1)this.log.info(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);try{let tmpValueParsed=new this.fable.Utility.bigNumber(tmpValue);tmpToken.Resolved=true;tmpToken.Value=tmpValueParsed.toString();}catch(pError){// TODO: Should we allow this to be a function? Good god the complexity and beauty of that...
3993
+ if(tmpValue==null){tmpToken.Value=tmpValue;tmpToken.Resolve=true;tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.substituteValuesInTokenizedObjects found no value for the symbol hash or address ${tmpToken.Token} at index ${i}`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);continue;}else{tmpResults.ExpressionParserLog.push(`INFO: ExpressionParser.substituteValuesInTokenizedObjects found a value [${tmpValue}] for the state address ${tmpToken.Token} at index ${i}`);if(this.LogNoisiness>1)this.log.info(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);try{let tmpValueParsed=new this.fable.Utility.bigNumber(tmpValue);tmpToken.Resolved=true;tmpToken.Value=tmpValueParsed.toString();}catch(pError){// TODO: Should we allow this to be a function? Good god the complexity and beauty of that...
3949
3994
  if(Array.isArray(tmpValue)||typeof tmpValue==='object'){tmpToken.Resolved=true;tmpToken.Value=tmpValue;}else{tmpToken.Resolved=true;tmpToken.Value=tmpValue;tmpResults.ExpressionParserLog.push(`INFO: ExpressionParser.substituteValuesInTokenizedObjects found a non-numeric value for the state address ${tmpToken.Token} at index ${i}; using raw value.`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);}}}}if(pTokenizedObjects[i].Type==='Token.StateAddress'&&!tmpToken.Resolved){// Symbols are always hashes. This gracefully works for simple shallow objects because hashes default to the address in Manyfest.
3950
3995
  let tmpValue=tmpManifest.getValueAtAddress(tmpDataSource,tmpToken.Token);if(!tmpValue){tmpResults.ExpressionParserLog.push(`WARNING: ExpressionParser.substituteValuesInTokenizedObjects found no value for the state address ${tmpToken.Token} at index ${i}`);this.log.warn(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);continue;}else{//tmpResults.ExpressionParserLog.push(`INFO: ExpressionParser.substituteValuesInTokenizedObjects found a value [${tmpValue}] for the state address ${tmpToken.Token} at index ${i}`);
3951
3996
  this.log.info(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);try{let tmpValueParsed=new this.fable.Utility.bigNumber(tmpValue);tmpToken.Resolved=true;tmpToken.Value=tmpValueParsed.toString();}catch(pError){tmpResults.ExpressionParserLog.push(`ERROR: ExpressionParser.substituteValuesInTokenizedObjects found a non-numeric value for the state address ${tmpToken.Token} at index ${i}`);this.log.error(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);tmpToken.Resolved=false;}}}if(pTokenizedObjects[i].Type==='Token.String'&&!tmpToken.Resolved){tmpResults.ExpressionParserLog.push(`INFO: ExpressionParser.substituteValuesInTokenizedObjects found a value [${tmpToken.Token}] for the string ${tmpToken.Token} at index ${i}`);if(this.LogNoisiness>1)this.log.info(tmpResults.ExpressionParserLog[tmpResults.ExpressionParserLog.length-1]);tmpToken.Resolved=true;// Take the quotes off the string
@@ -4446,7 +4491,11 @@ const n=pCoefficientMatrix.length;const tmpAugmentedMatrix=pCoefficientMatrix.ma
4446
4491
  let maxRow=i;for(let k=i+1;k<n;++k){if(this.gtPrecise(this.absPrecise(tmpAugmentedMatrix[k][i]),this.absPrecise(tmpAugmentedMatrix[maxRow][i]))){maxRow=k;}}const tmpSwapValue=tmpAugmentedMatrix[i];tmpAugmentedMatrix[i]=tmpAugmentedMatrix[maxRow];tmpAugmentedMatrix[maxRow]=tmpSwapValue;// Normalize pivot row
4447
4492
  const tmpPivotValue=tmpAugmentedMatrix[i][i];if(this.comparePrecise(tmpPivotValue,0)==0){throw new Error('Matrix not invertible');}for(let j=i;j<=n;++j){tmpAugmentedMatrix[i][j]=this.dividePrecise(tmpAugmentedMatrix[i][j],tmpPivotValue);}// Eliminate other rows
4448
4493
  for(let k=0;k<n;++k){if(k===i){continue;}const tmpFactor=tmpAugmentedMatrix[k][i];for(let j=i;j<=n;++j){tmpAugmentedMatrix[k][j]=this.subtractPrecise(tmpAugmentedMatrix[k][j],this.multiplyPrecise(tmpFactor,tmpAugmentedMatrix[i][j]));}}}// Extract solution
4449
- return tmpAugmentedMatrix.map(row=>row[n]);}}module.exports=FableServiceMath;},{"./Fable-SetConcatArray.js":183,"fable-serviceproviderbase":59}],172:[function(require,module,exports){const libFableServiceBase=require('fable-serviceproviderbase');/**
4494
+ return tmpAugmentedMatrix.map(row=>row[n]);}generateValueFromEasingDescription(pEasingConfiguration){// Branch based on type
4495
+ switch(pEasingConfiguration.Easing){case'LINEAR':default:let tmpDomainRange=pEasingConfiguration.DomainLength;if(this.comparePrecise(tmpDomainRange,0)==0){return this.parsePrecise(pEasingConfiguration.DomainRangeStart);}// Now, generate a random number and then multiply it to fit in the domain length
4496
+ let tmpRandomFraction=Math.random();// Scale it to the domain
4497
+ let tmpScaledValue=this.multiplyPrecise(tmpRandomFraction,tmpDomainRange);// Shift it to the range start
4498
+ return this.addPrecise(pEasingConfiguration.DomainRangeStart,tmpScaledValue);}}}module.exports=FableServiceMath;},{"./Fable-SetConcatArray.js":183,"fable-serviceproviderbase":59}],172:[function(require,module,exports){const libFableServiceBase=require('fable-serviceproviderbase');/**
4450
4499
  * Precedent Meta-Templating
4451
4500
  * @author Steven Velozo <steven@velozo.com>
4452
4501
  * @description Process text stream trie and postfix tree, parsing out meta-template expression functions.
@@ -4800,6 +4849,17 @@ if(!this.manifest){this.manifest=this.fable.newManyfest();}if(!Array.isArray(pOb
4800
4849
  * @returns {any} - The value from the object
4801
4850
  */findFirstValueByExactMatchInternal(pFableAddress,pValueToMatchAddress,pValueToMatch,pValueAddress){// Lazily create a manifest if it doesn't exist
4802
4851
  if(!this.manifest){this.manifest=this.fable.newManyfest();}if(typeof pFableAddress!='string'){return undefined;}let tmpObjectArray=this.manifest.getValueByHash(this.fable,pFableAddress);return this.findFirstValueByExactMatch(tmpObjectArray,pValueToMatchAddress,pValueToMatch,pValueAddress);}/**
4852
+ * Find the index of a value in an array, using the specified search mode.
4853
+ *
4854
+ * @param {any} pValueToFind - The value to find.
4855
+ * @param {Array<any>|string} pSearchArray - The array to search, or the address of such an array.
4856
+ * @param {string|number} [pSearchMode='1'] - The search mode ('0' for exact match, '1' (or default) for searching sorted sets and finding the first value >= the specifid value. '-1' is the same behavior as '1' but sorted descending.
4857
+ *
4858
+ * @returns {number} - The index of the found value, or -1 if not found.
4859
+ */findIndexInternal(pValueToFind,pSearchArray){let pSearchMode=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'1';let tmpSearchArray=pSearchArray;if(typeof pSearchArray==='string'){if(!this.manifest){this.manifest=this.fable.newManyfest();}tmpSearchArray=this.manifest.getValueByHash(this.fable,pSearchArray);}if(!Array.isArray(tmpSearchArray)){this.fable.log.error('findIndexInternal called with non-array search array.');return-1;}const tmpIsNumericSearch=this.fable.Math.parsePrecise(pValueToFind,null)!==null;let tmpMatchIndex=-1;let tmpComparisonFunction;if(Number(pSearchMode)===0){// Exact match
4860
+ if(tmpIsNumericSearch){tmpComparisonFunction=pCandidate=>this.fable.Math.comparePrecise(pCandidate,pValueToFind)===0;}else{tmpComparisonFunction=pCandidate=>pCandidate===pValueToFind;}}else if(Number(pSearchMode)===-1){// Sorted descending
4861
+ if(tmpIsNumericSearch){tmpComparisonFunction=pCandidate=>this.fable.Math.ltePrecise(pCandidate,pValueToFind);}else{tmpComparisonFunction=pCandidate=>pCandidate<=pValueToFind;}}else{// Sorted ascending
4862
+ if(tmpIsNumericSearch){tmpComparisonFunction=pCandidate=>this.fable.Math.gtePrecise(pCandidate,pValueToFind);}else{tmpComparisonFunction=pCandidate=>pCandidate>=pValueToFind;}}for(let i=0;i<tmpSearchArray.length;i++){if(tmpComparisonFunction(tmpSearchArray[i])){return i;}}return-1;}/**
4803
4863
  * Flatten an array of solver inputs into a single array
4804
4864
  *
4805
4865
  * @param {Array<any>} pInputArray - The array of inputs to flatten