diff --git a/dist/formula.js b/dist/formula.js index ec15cd87..4ee5545c 100644 --- a/dist/formula.js +++ b/dist/formula.js @@ -1,72 +1,72 @@ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(require("jStat"), require("numeric"), require("numeral")); + module.exports = factory(require("numeric"), require("numeral"), require("jStat")); else if(typeof define === 'function' && define.amd) - define(["jStat", "numeric", "numeral"], factory); + define(["numeric", "numeral", "jStat"], factory); else if(typeof exports === 'object') - exports["formulajs"] = factory(require("jStat"), require("numeric"), require("numeral")); + exports["formulajs"] = factory(require("numeric"), require("numeral"), require("jStat")); else - root["formulajs"] = factory(root["jStat"], root["numeric"], root["numeral"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_13__, __WEBPACK_EXTERNAL_MODULE_14__, __WEBPACK_EXTERNAL_MODULE_15__) { + root["formulajs"] = factory(root["numeric"], root["numeral"], root["jStat"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_8__, __WEBPACK_EXTERNAL_MODULE_9__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; -/******/ + /******/ // The require function /******/ function __webpack_require__(moduleId) { -/******/ + /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; -/******/ + /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; -/******/ + /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ + /******/ // Flag the module as loaded /******/ module.loaded = true; -/******/ + /******/ // Return the exports of the module /******/ return module.exports; /******/ } -/******/ -/******/ + + /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; -/******/ + /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; -/******/ + /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; -/******/ + /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { var categories = [ __webpack_require__(1), + __webpack_require__(15), + __webpack_require__(12), + __webpack_require__(16), __webpack_require__(2), - __webpack_require__(3), - __webpack_require__(4), - __webpack_require__(5), - __webpack_require__(6), __webpack_require__(7), - __webpack_require__(8), - __webpack_require__(9), - __webpack_require__(10), + __webpack_require__(14), + __webpack_require__(17), __webpack_require__(11), - __webpack_require__(12) + __webpack_require__(18), + __webpack_require__(6), + __webpack_require__(10) ]; for (var c in categories) { @@ -77,14 +77,14 @@ return /******/ (function(modules) { // webpackBootstrap } -/***/ }, +/***/ }), /* 1 */ -/***/ function(module, exports, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { - var mathTrig = __webpack_require__(5); - var statistical = __webpack_require__(11); - var engineering = __webpack_require__(3); - var dateTime = __webpack_require__(7); + var mathTrig = __webpack_require__(2); + var statistical = __webpack_require__(6); + var engineering = __webpack_require__(12); + var dateTime = __webpack_require__(14); function set(fn, root) { if (root) { @@ -169,3137 +169,3111 @@ return /******/ (function(modules) { // webpackBootstrap exports.ZTEST = statistical.Z.TEST; -/***/ }, +/***/ }), /* 2 */ -/***/ function(module, exports, __webpack_require__) { - - var error = __webpack_require__(16); - var stats = __webpack_require__(11); - var maths = __webpack_require__(5); - var utils = __webpack_require__(17); +/***/ (function(module, exports, __webpack_require__) { - function compact(array) { - if (!array) { return array; } - var result = []; - for (var i = 0; i < array.length; ++i) { - if (!array[i]) { continue; } - result.push(array[i]); - } - return result; - } + var numeric = __webpack_require__(3); + var utils = __webpack_require__(4); + var error = __webpack_require__(5); + var statistical = __webpack_require__(6); + var information = __webpack_require__(11); - exports.FINDFIELD = function(database, title) { - var index = null; - for (var i = 0; i < database.length; i++) { - if (database[i][0] === title) { - index = i; - break; - } + exports.ABS = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return Math.abs(utils.parseNumber(number)); + }; - // Return error if the input field title is incorrect - if (index == null) { - return error.value; + exports.ACOS = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - return index; + return Math.acos(number); }; - function findResultIndex(database, criterias) { - var matches = {}; - for (var i = 1; i < database[0].length; ++i) { - matches[i] = true; - } - var maxCriteriaLength = criterias[0].length; - for (i = 1; i < criterias.length; ++i) { - if (criterias[i].length > maxCriteriaLength) { - maxCriteriaLength = criterias[i].length; - } + exports.ACOSH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return Math.log(number + Math.sqrt(number * number - 1)); + }; - for (var k = 1; k < database.length; ++k) { - for (var l = 1; l < database[k].length; ++l) { - var currentCriteriaResult = false; - var hasMatchingCriteria = false; - for (var j = 0; j < criterias.length; ++j) { - var criteria = criterias[j]; - if (criteria.length < maxCriteriaLength) { - continue; - } - - var criteriaField = criteria[0]; - if (database[k][0] !== criteriaField) { - continue; - } - hasMatchingCriteria = true; - for (var p = 1; p < criteria.length; ++p) { - currentCriteriaResult = currentCriteriaResult || eval(database[k][l] + criteria[p]); // jshint ignore:line - } - } - if (hasMatchingCriteria) { - matches[l] = matches[l] && currentCriteriaResult; - } - } + exports.ACOT = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return Math.atan(1 / number); + }; - var result = []; - for (var n = 0; n < database[0].length; ++n) { - if (matches[n]) { - result.push(n - 1); - } + exports.ACOTH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - return result; - } + return 0.5 * Math.log((number + 1) / (number - 1)); + }; - // Database functions - exports.DAVERAGE = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + //TODO: use options + exports.AGGREGATE = function(function_num, options, ref1, ref2) { + function_num = utils.parseNumber(function_num); + options = utils.parseNumber(function_num); + if (utils.anyIsError(function_num, options)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); - } - var sum = 0; - for (var i = 0; i < resultIndexes.length; i++) { - sum += targetFields[resultIndexes[i]]; + switch (function_num) { + case 1: + return statistical.AVERAGE(ref1); + case 2: + return statistical.COUNT(ref1); + case 3: + return statistical.COUNTA(ref1); + case 4: + return statistical.MAX(ref1); + case 5: + return statistical.MIN(ref1); + case 6: + return exports.PRODUCT(ref1); + case 7: + return statistical.STDEV.S(ref1); + case 8: + return statistical.STDEV.P(ref1); + case 9: + return exports.SUM(ref1); + case 10: + return statistical.VAR.S(ref1); + case 11: + return statistical.VAR.P(ref1); + case 12: + return statistical.MEDIAN(ref1); + case 13: + return statistical.MODE.SNGL(ref1); + case 14: + return statistical.LARGE(ref1, ref2); + case 15: + return statistical.SMALL(ref1, ref2); + case 16: + return statistical.PERCENTILE.INC(ref1, ref2); + case 17: + return statistical.QUARTILE.INC(ref1, ref2); + case 18: + return statistical.PERCENTILE.EXC(ref1, ref2); + case 19: + return statistical.QUARTILE.EXC(ref1, ref2); } - return resultIndexes.length === 0 ? error.div0 : sum / resultIndexes.length; }; - exports.DCOUNT = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.ARABIC = function(text) { + // Credits: Rafa? Kukawski + if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(text)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); - } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; - } - return stats.COUNT(targetValues); + var r = 0; + text.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) { + r += { + M: 1000, + CM: 900, + D: 500, + CD: 400, + C: 100, + XC: 90, + L: 50, + XL: 40, + X: 10, + IX: 9, + V: 5, + IV: 4, + I: 1 + }[i]; + }); + return r; }; - exports.DCOUNTA = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { - return error.value; + exports.ASIN = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + return Math.asin(number); + }; + + exports.ASINH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + return Math.log(number + Math.sqrt(number * number + 1)); + }; + + exports.ATAN = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - return stats.COUNTA(targetValues); + return Math.atan(number); }; - exports.DGET = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.ATAN2 = function(number_x, number_y) { + number_x = utils.parseNumber(number_x); + number_y = utils.parseNumber(number_y); + if (utils.anyIsError(number_x, number_y)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + return Math.atan2(number_x, number_y); + }; + + exports.ATANH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - // Return error if no record meets the criteria - if (resultIndexes.length === 0) { + return Math.log((1 + number) / (1 - number)) / 2; + }; + + exports.BASE = function(number, radix, min_length) { + min_length = min_length || 0; + + number = utils.parseNumber(number); + radix = utils.parseNumber(radix); + min_length = utils.parseNumber(min_length); + if (utils.anyIsError(number, radix, min_length)) { return error.value; } - // Returns the #NUM! error value because more than one record meets the - // criteria - if (resultIndexes.length > 1) { - return error.num; - } - - return targetFields[resultIndexes[0]]; + min_length = (min_length === undefined) ? 0 : min_length; + var result = number.toString(radix); + return new Array(Math.max(min_length + 1 - result.length, 0)).join('0') + result; }; - exports.DMAX = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.CEILING = function(number, significance, mode) { + significance = (significance === undefined) ? 1 : significance; + mode = (mode === undefined) ? 0 : mode; + + number = utils.parseNumber(number); + significance = utils.parseNumber(significance); + mode = utils.parseNumber(mode); + if (utils.anyIsError(number, significance, mode)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + if (significance === 0) { + return 0; } - var maxValue = targetFields[resultIndexes[0]]; - for (var i = 1; i < resultIndexes.length; i++) { - if (maxValue < targetFields[resultIndexes[i]]) { - maxValue = targetFields[resultIndexes[i]]; + + significance = Math.abs(significance); + if (number >= 0) { + return Math.ceil(number / significance) * significance; + } else { + if (mode === 0) { + return -1 * Math.floor(Math.abs(number) / significance) * significance; + } else { + return -1 * Math.ceil(Math.abs(number) / significance) * significance; } } - return maxValue; }; - exports.DMIN = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.CEILING.MATH = exports.CEILING; + + exports.CEILING.PRECISE = exports.CEILING; + + exports.COMBIN = function(number, number_chosen) { + number = utils.parseNumber(number); + number_chosen = utils.parseNumber(number_chosen); + if (utils.anyIsError(number, number_chosen)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); - } - var minValue = targetFields[resultIndexes[0]]; - for (var i = 1; i < resultIndexes.length; i++) { - if (minValue > targetFields[resultIndexes[i]]) { - minValue = targetFields[resultIndexes[i]]; - } - } - return minValue; + return exports.FACT(number) / (exports.FACT(number_chosen) * exports.FACT(number - number_chosen)); }; - exports.DPRODUCT = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.COMBINA = function(number, number_chosen) { + number = utils.parseNumber(number); + number_chosen = utils.parseNumber(number_chosen); + if (utils.anyIsError(number, number_chosen)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + return (number === 0 && number_chosen === 0) ? 1 : exports.COMBIN(number + number_chosen - 1, number - 1); + }; + + exports.COS = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + return Math.cos(number); + }; + + exports.COSH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - targetValues = compact(targetValues); - var result = 1; - for (i = 0; i < targetValues.length; i++) { - result *= targetValues[i]; + return (Math.exp(number) + Math.exp(-number)) / 2; + }; + + exports.COT = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - return result; + return 1 / Math.tan(number); }; - exports.DSTDEV = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { - return error.value; + exports.COTH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + var e2 = Math.exp(2 * number); + return (e2 + 1) / (e2 - 1); + }; + + exports.CSC = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + return 1 / Math.sin(number); + }; + + exports.CSCH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - targetValues = compact(targetValues); - return stats.STDEV.S(targetValues); + return 2 / (Math.exp(number) - Math.exp(-number)); }; - exports.DSTDEVP = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.DECIMAL = function(number, radix) { + if (arguments.length < 1) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + + + return parseInt(number, radix); + }; + + exports.DEGREES = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + return number * 180 / Math.PI; + }; + + exports.EVEN = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - targetValues = compact(targetValues); - return stats.STDEV.P(targetValues); + return exports.CEILING(number, -2, -1); }; - exports.DSUM = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { - return error.value; + exports.EXP = Math.exp; + + var MEMOIZED_FACT = []; + exports.FACT = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); + var n = Math.floor(number); + if (n === 0 || n === 1) { + return 1; + } else if (MEMOIZED_FACT[n] > 0) { + return MEMOIZED_FACT[n]; } else { - targetFields = utils.rest(database[field]); - } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + MEMOIZED_FACT[n] = exports.FACT(n - 1) * n; + return MEMOIZED_FACT[n]; } - return maths.SUM(targetValues); }; - exports.DVAR = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { - return error.value; + exports.FACTDOUBLE = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); + var n = Math.floor(number); + if (n <= 0) { + return 1; } else { - targetFields = utils.rest(database[field]); - } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + return n * exports.FACTDOUBLE(n - 2); } - return stats.VAR.S(targetValues); }; - exports.DVARP = function(database, field, criteria) { - // Return error if field is not a number and not a string - if (isNaN(field) && (typeof field !== "string")) { + exports.FLOOR = function(number, significance, mode) { + significance = (significance === undefined) ? 1 : significance; + mode = (mode === undefined) ? 0 : mode; + + number = utils.parseNumber(number); + significance = utils.parseNumber(significance); + mode = utils.parseNumber(mode); + if (utils.anyIsError(number, significance, mode)) { return error.value; } - var resultIndexes = findResultIndex(database, criteria); - var targetFields = []; - if (typeof field === "string") { - var index = exports.FINDFIELD(database, field); - targetFields = utils.rest(database[index]); - } else { - targetFields = utils.rest(database[field]); + if (significance === 0) { + return 0; } - var targetValues = []; - for (var i = 0; i < resultIndexes.length; i++) { - targetValues[i] = targetFields[resultIndexes[i]]; + + significance = Math.abs(significance); + if (number >= 0) { + return Math.floor(number / significance) * significance; + } else { + if (mode === 0) { + return -1 * Math.ceil(Math.abs(number) / significance) * significance; + } else { + return -1 * Math.floor(Math.abs(number) / significance) * significance; + } } - return stats.VAR.P(targetValues); }; + exports.FLOOR.MATH = exports.FLOOR; -/***/ }, -/* 3 */ -/***/ function(module, exports, __webpack_require__) { - - var error = __webpack_require__(16); - var jStat = __webpack_require__(13).jStat; - var text = __webpack_require__(6); - var utils = __webpack_require__(17); - var bessel = __webpack_require__(18); - - function isValidBinaryNumber(number) { - return (/^[01]{1,10}$/).test(number); - } + // Deprecated + exports.FLOOR.PRECISE = exports.FLOOR.MATH; - exports.BESSELI = function(x, n) { - x = utils.parseNumber(x); - n = utils.parseNumber(n); - if (utils.anyIsError(x, n)) { - return error.value; + // adapted http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript + exports.GCD = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; } - return bessel.besseli(x, n); - }; - - exports.BESSELJ = function(x, n) { - x = utils.parseNumber(x); - n = utils.parseNumber(n); - if (utils.anyIsError(x, n)) { - return error.value; + var n = range.length; + var r0 = range[0]; + var x = r0 < 0 ? -r0 : r0; + for (var i = 1; i < n; i++) { + var ri = range[i]; + var y = ri < 0 ? -ri : ri; + while (x && y) { + if (x > y) { + x %= y; + } else { + y %= x; + } + } + x += y; } - return bessel.besselj(x, n); + return x; }; - exports.BESSELK = function(x, n) { - x = utils.parseNumber(x); - n = utils.parseNumber(n); - if (utils.anyIsError(x, n)) { - return error.value; + + exports.INT = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - return bessel.besselk(x, n); + return Math.floor(number); }; - exports.BESSELY = function(x, n) { - x = utils.parseNumber(x); - n = utils.parseNumber(n); - if (utils.anyIsError(x, n)) { - return error.value; - } - return bessel.bessely(x, n); + //TODO: verify + exports.ISO = { + CEILING: exports.CEILING }; - exports.BIN2DEC = function(number) { - // Return error if number is not binary or contains more than 10 characters (10 digits) - if (!isValidBinaryNumber(number)) { - return error.num; + exports.LCM = function() { + // Credits: Jonas Raoni Soares Silva + var o = utils.parseNumberArray(utils.flatten(arguments)); + if (o instanceof Error) { + return o; } - - // Convert binary number to decimal - var result = parseInt(number, 2); - - // Handle negative numbers - var stringified = number.toString(); - if (stringified.length === 10 && stringified.substring(0, 1) === '1') { - return parseInt(stringified.substring(1), 2) - 512; - } else { - return result; + for (var i, j, n, d, r = 1; + (n = o.pop()) !== undefined;) { + while (n > 1) { + if (n % 2) { + for (i = 3, j = Math.floor(Math.sqrt(n)); i <= j && n % i; i += 2) { + //empty + } + d = (i <= j) ? i : n; + } else { + d = 2; + } + for (n /= d, r *= d, i = o.length; i; + (o[--i] % d) === 0 && (o[i] /= d) === 1 && o.splice(i, 1)) { + //empty + } + } } + return r; }; - - exports.BIN2HEX = function(number, places) { - // Return error if number is not binary or contains more than 10 characters (10 digits) - if (!isValidBinaryNumber(number)) { - return error.num; - } - - // Ignore places and return a 10-character hexadecimal number if number is negative - var stringified = number.toString(); - if (stringified.length === 10 && stringified.substring(0, 1) === '1') { - return (1099511627264 + parseInt(stringified.substring(1), 2)).toString(16); + exports.LN = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return Math.log(number); + }; - // Convert binary number to hexadecimal - var result = parseInt(number, 2).toString(16); - - // Return hexadecimal number using the minimum number of characters necessary if places is undefined - if (places === undefined) { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; - } + exports.LOG = function(number, base) { + number = utils.parseNumber(number); + base = (base === undefined) ? 10 : utils.parseNumber(base); - // Return error if places is negative - if (places < 0) { - return error.num; - } + if (utils.anyIsError(number, base)) { + return error.value; + } - // Truncate places in case it is not an integer - places = Math.floor(places); + return Math.log(number) / Math.log(base); + }; - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + exports.LOG10 = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return Math.log(number) / Math.log(10); }; - exports.BIN2OCT = function(number, places) { - // Return error if number is not binary or contains more than 10 characters (10 digits) - if (!isValidBinaryNumber(number)) { - return error.num; + exports.MDETERM = function(matrix) { + matrix = utils.parseMatrix(matrix); + if (matrix instanceof Error) { + return matrix; } + return numeric.det(matrix); + }; - // Ignore places and return a 10-character octal number if number is negative - var stringified = number.toString(); - if (stringified.length === 10 && stringified.substring(0, 1) === '1') { - return (1073741312 + parseInt(stringified.substring(1), 2)).toString(8); + exports.MINVERSE = function(matrix) { + matrix = utils.parseMatrix(matrix); + if (matrix instanceof Error) { + return matrix; } + return numeric.inv(matrix); + }; - // Convert binary number to octal - var result = parseInt(number, 2).toString(8); - - // Return octal number using the minimum number of characters necessary if places is undefined - if (places === undefined) { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; - } - - // Return error if places is negative - if (places < 0) { - return error.num; - } - - // Truncate places in case it is not an integer - places = Math.floor(places); - - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + exports.MMULT = function(matrix1, matrix2) { + matrix1 = utils.parseMatrix(matrix1); + matrix2 = utils.parseMatrix(matrix2); + if (utils.anyIsError(matrix1, matrix2)) { + return error.value; } + return numeric.dot(matrix1, matrix2); }; - exports.BITAND = function(number1, number2) { - // Return error if either number is a non-numeric value - number1 = utils.parseNumber(number1); - number2 = utils.parseNumber(number2); - if (utils.anyIsError(number1, number2)) { + exports.MOD = function(dividend, divisor) { + dividend = utils.parseNumber(dividend); + divisor = utils.parseNumber(divisor); + if (utils.anyIsError(dividend, divisor)) { return error.value; } - - // Return error if either number is less than 0 - if (number1 < 0 || number2 < 0) { - return error.num; + if (divisor === 0) { + return error.div0; } + var modulus = Math.abs(dividend % divisor); + return (divisor > 0) ? modulus : -modulus; + }; - // Return error if either number is a non-integer - if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) { - return error.num; + exports.MROUND = function(number, multiple) { + number = utils.parseNumber(number); + multiple = utils.parseNumber(multiple); + if (utils.anyIsError(number, multiple)) { + return error.value; } - - // Return error if either number is greater than (2^48)-1 - if (number1 > 281474976710655 || number2 > 281474976710655) { + if (number * multiple < 0) { return error.num; } - // Return bitwise AND of two numbers - return number1 & number2; + return Math.round(number / multiple) * multiple; }; - exports.BITLSHIFT = function(number, shift) { - number = utils.parseNumber(number); - shift = utils.parseNumber(shift); - if (utils.anyIsError(number, shift)) { - return error.value; - } - - // Return error if number is less than 0 - if (number < 0) { - return error.num; + exports.MULTINOMIAL = function() { + var args = utils.parseNumberArray(utils.flatten(arguments)); + if (args instanceof Error) { + return args; } - - // Return error if number is a non-integer - if (Math.floor(number) !== number) { - return error.num; + var sum = 0; + var divisor = 1; + for (var i = 0; i < args.length; i++) { + sum += args[i]; + divisor *= exports.FACT(args[i]); } + return exports.FACT(sum) / divisor; + }; - // Return error if number is greater than (2^48)-1 - if (number > 281474976710655) { - return error.num; + exports.MUNIT = function(dimension) { + dimension = utils.parseNumber(dimension); + if (dimension instanceof Error) { + return dimension; } + return numeric.identity(dimension); + }; - // Return error if the absolute value of shift is greater than 53 - if (Math.abs(shift) > 53) { - return error.num; + exports.ODD = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + var temp = Math.ceil(Math.abs(number)); + temp = (temp & 1) ? temp : temp + 1; + return (number > 0) ? temp : -temp; + }; - // Return number shifted by shift bits to the left or to the right if shift is negative - return (shift >= 0) ? number << shift : number >> -shift; + exports.PI = function() { + return Math.PI; }; - exports.BITOR = function(number1, number2) { - number1 = utils.parseNumber(number1); - number2 = utils.parseNumber(number2); - if (utils.anyIsError(number1, number2)) { + exports.POWER = function(number, power) { + number = utils.parseNumber(number); + power = utils.parseNumber(power); + if (utils.anyIsError(number, power)) { return error.value; } - - // Return error if either number is less than 0 - if (number1 < 0 || number2 < 0) { + var result = Math.pow(number, power); + if (isNaN(result)) { return error.num; } - // Return error if either number is a non-integer - if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) { - return error.num; - } + return result; + }; - // Return error if either number is greater than (2^48)-1 - if (number1 > 281474976710655 || number2 > 281474976710655) { - return error.num; + exports.PRODUCT = function() { + var args = utils.parseNumberArray(utils.flatten(arguments)); + if (args instanceof Error) { + return args; } - - // Return bitwise OR of two numbers - return number1 | number2; + var result = 1; + for (var i = 0; i < args.length; i++) { + result *= args[i]; + } + return result; }; - exports.BITRSHIFT = function(number, shift) { - number = utils.parseNumber(number); - shift = utils.parseNumber(shift); - if (utils.anyIsError(number, shift)) { + exports.QUOTIENT = function(numerator, denominator) { + numerator = utils.parseNumber(numerator); + denominator = utils.parseNumber(denominator); + if (utils.anyIsError(numerator, denominator)) { return error.value; } + return parseInt(numerator / denominator, 10); + }; - // Return error if number is less than 0 - if (number < 0) { - return error.num; + exports.RADIANS = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return number * Math.PI / 180; + }; - // Return error if number is a non-integer - if (Math.floor(number) !== number) { - return error.num; - } + exports.RAND = function() { + return Math.random(); + }; - // Return error if number is greater than (2^48)-1 - if (number > 281474976710655) { - return error.num; + exports.RANDBETWEEN = function(bottom, top) { + bottom = utils.parseNumber(bottom); + top = utils.parseNumber(top); + if (utils.anyIsError(bottom, top)) { + return error.value; } + // Creative Commons Attribution 3.0 License + // Copyright (c) 2012 eqcode + return bottom + Math.ceil((top - bottom + 1) * Math.random()) - 1; + }; - // Return error if the absolute value of shift is greater than 53 - if (Math.abs(shift) > 53) { - return error.num; + // TODO + exports.ROMAN = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - - // Return number shifted by shift bits to the right or to the left if shift is negative - return (shift >= 0) ? number >> shift : number << -shift; + // The MIT License + // Copyright (c) 2008 Steven Levithan + var digits = String(number).split(''); + var key = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']; + var roman = ''; + var i = 3; + while (i--) { + roman = (key[+digits.pop() + (i * 10)] || '') + roman; + } + return new Array(+digits.join('') + 1).join('M') + roman; }; - exports.BITXOR = function(number1, number2) { - number1 = utils.parseNumber(number1); - number2 = utils.parseNumber(number2); - if (utils.anyIsError(number1, number2)) { + exports.ROUND = function(number, digits) { + number = utils.parseNumber(number); + digits = utils.parseNumber(digits); + if (utils.anyIsError(number, digits)) { return error.value; } + return Math.round(number * Math.pow(10, digits)) / Math.pow(10, digits); + }; - // Return error if either number is less than 0 - if (number1 < 0 || number2 < 0) { - return error.num; + exports.ROUNDDOWN = function(number, digits) { + number = utils.parseNumber(number); + digits = utils.parseNumber(digits); + if (utils.anyIsError(number, digits)) { + return error.value; } + var sign = (number > 0) ? 1 : -1; + return sign * (Math.floor(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits); + }; - // Return error if either number is a non-integer - if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) { - return error.num; + exports.ROUNDUP = function(number, digits) { + number = utils.parseNumber(number); + digits = utils.parseNumber(digits); + if (utils.anyIsError(number, digits)) { + return error.value; } + var sign = (number > 0) ? 1 : -1; + return sign * (Math.ceil(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits); + }; - // Return error if either number is greater than (2^48)-1 - if (number1 > 281474976710655 || number2 > 281474976710655) { - return error.num; + exports.SEC = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - - // Return bitwise XOR of two numbers - return number1 ^ number2; + return 1 / Math.cos(number); }; - exports.COMPLEX = function(real, imaginary, suffix) { - real = utils.parseNumber(real); - imaginary = utils.parseNumber(imaginary); - if (utils.anyIsError(real, imaginary)) { - return real; + exports.SECH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return 2 / (Math.exp(number) + Math.exp(-number)); + }; - // Set suffix - suffix = (suffix === undefined) ? 'i' : suffix; - - // Return error if suffix is neither "i" nor "j" - if (suffix !== 'i' && suffix !== 'j') { + exports.SERIESSUM = function(x, n, m, coefficients) { + x = utils.parseNumber(x); + n = utils.parseNumber(n); + m = utils.parseNumber(m); + coefficients = utils.parseNumberArray(coefficients); + if (utils.anyIsError(x, n, m, coefficients)) { return error.value; } + var result = coefficients[0] * Math.pow(x, n); + for (var i = 1; i < coefficients.length; i++) { + result += coefficients[i] * Math.pow(x, n + i * m); + } + return result; + }; - // Return complex number - if (real === 0 && imaginary === 0) { + exports.SIGN = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; + } + if (number < 0) { + return -1; + } else if (number === 0) { return 0; - } else if (real === 0) { - return (imaginary === 1) ? suffix : imaginary.toString() + suffix; - } else if (imaginary === 0) { - return real.toString(); } else { - var sign = (imaginary > 0) ? '+' : ''; - return real.toString() + sign + ((imaginary === 1) ? suffix : imaginary.toString() + suffix); + return 1; } }; - exports.CONVERT = function(number, from_unit, to_unit) { + exports.SIN = function(number) { number = utils.parseNumber(number); if (number instanceof Error) { return number; } + return Math.sin(number); + }; - // List of units supported by CONVERT and units defined by the International System of Units - // [Name, Symbol, Alternate symbols, Quantity, ISU, CONVERT, Conversion ratio] - var units = [ - ["a.u. of action", "?", null, "action", false, false, 1.05457168181818e-34], - ["a.u. of charge", "e", null, "electric_charge", false, false, 1.60217653141414e-19], - ["a.u. of energy", "Eh", null, "energy", false, false, 4.35974417757576e-18], - ["a.u. of length", "a?", null, "length", false, false, 5.29177210818182e-11], - ["a.u. of mass", "m?", null, "mass", false, false, 9.10938261616162e-31], - ["a.u. of time", "?/Eh", null, "time", false, false, 2.41888432650516e-17], - ["admiralty knot", "admkn", null, "speed", false, true, 0.514773333], - ["ampere", "A", null, "electric_current", true, false, 1], - ["ampere per meter", "A/m", null, "magnetic_field_intensity", true, false, 1], - ["ångström", "Å", ["ang"], "length", false, true, 1e-10], - ["are", "ar", null, "area", false, true, 100], - ["astronomical unit", "ua", null, "length", false, false, 1.49597870691667e-11], - ["bar", "bar", null, "pressure", false, false, 100000], - ["barn", "b", null, "area", false, false, 1e-28], - ["becquerel", "Bq", null, "radioactivity", true, false, 1], - ["bit", "bit", ["b"], "information", false, true, 1], - ["btu", "BTU", ["btu"], "energy", false, true, 1055.05585262], - ["byte", "byte", null, "information", false, true, 8], - ["candela", "cd", null, "luminous_intensity", true, false, 1], - ["candela per square metre", "cd/m?", null, "luminance", true, false, 1], - ["coulomb", "C", null, "electric_charge", true, false, 1], - ["cubic ångström", "ang3", ["ang^3"], "volume", false, true, 1e-30], - ["cubic foot", "ft3", ["ft^3"], "volume", false, true, 0.028316846592], - ["cubic inch", "in3", ["in^3"], "volume", false, true, 0.000016387064], - ["cubic light-year", "ly3", ["ly^3"], "volume", false, true, 8.46786664623715e-47], - ["cubic metre", "m?", null, "volume", true, true, 1], - ["cubic mile", "mi3", ["mi^3"], "volume", false, true, 4168181825.44058], - ["cubic nautical mile", "Nmi3", ["Nmi^3"], "volume", false, true, 6352182208], - ["cubic Pica", "Pica3", ["Picapt3", "Pica^3", "Picapt^3"], "volume", false, true, 7.58660370370369e-8], - ["cubic yard", "yd3", ["yd^3"], "volume", false, true, 0.764554857984], - ["cup", "cup", null, "volume", false, true, 0.0002365882365], - ["dalton", "Da", ["u"], "mass", false, false, 1.66053886282828e-27], - ["day", "d", ["day"], "time", false, true, 86400], - ["degree", "°", null, "angle", false, false, 0.0174532925199433], - ["degrees Rankine", "Rank", null, "temperature", false, true, 0.555555555555556], - ["dyne", "dyn", ["dy"], "force", false, true, 0.00001], - ["electronvolt", "eV", ["ev"], "energy", false, true, 1.60217656514141], - ["ell", "ell", null, "length", false, true, 1.143], - ["erg", "erg", ["e"], "energy", false, true, 1e-7], - ["farad", "F", null, "electric_capacitance", true, false, 1], - ["fluid ounce", "oz", null, "volume", false, true, 0.0000295735295625], - ["foot", "ft", null, "length", false, true, 0.3048], - ["foot-pound", "flb", null, "energy", false, true, 1.3558179483314], - ["gal", "Gal", null, "acceleration", false, false, 0.01], - ["gallon", "gal", null, "volume", false, true, 0.003785411784], - ["gauss", "G", ["ga"], "magnetic_flux_density", false, true, 1], - ["grain", "grain", null, "mass", false, true, 0.0000647989], - ["gram", "g", null, "mass", false, true, 0.001], - ["gray", "Gy", null, "absorbed_dose", true, false, 1], - ["gross registered ton", "GRT", ["regton"], "volume", false, true, 2.8316846592], - ["hectare", "ha", null, "area", false, true, 10000], - ["henry", "H", null, "inductance", true, false, 1], - ["hertz", "Hz", null, "frequency", true, false, 1], - ["horsepower", "HP", ["h"], "power", false, true, 745.69987158227], - ["horsepower-hour", "HPh", ["hh", "hph"], "energy", false, true, 2684519.538], - ["hour", "h", ["hr"], "time", false, true, 3600], - ["imperial gallon (U.K.)", "uk_gal", null, "volume", false, true, 0.00454609], - ["imperial hundredweight", "lcwt", ["uk_cwt", "hweight"], "mass", false, true, 50.802345], - ["imperial quart (U.K)", "uk_qt", null, "volume", false, true, 0.0011365225], - ["imperial ton", "brton", ["uk_ton", "LTON"], "mass", false, true, 1016.046909], - ["inch", "in", null, "length", false, true, 0.0254], - ["international acre", "uk_acre", null, "area", false, true, 4046.8564224], - ["IT calorie", "cal", null, "energy", false, true, 4.1868], - ["joule", "J", null, "energy", true, true, 1], - ["katal", "kat", null, "catalytic_activity", true, false, 1], - ["kelvin", "K", ["kel"], "temperature", true, true, 1], - ["kilogram", "kg", null, "mass", true, true, 1], - ["knot", "kn", null, "speed", false, true, 0.514444444444444], - ["light-year", "ly", null, "length", false, true, 9460730472580800], - ["litre", "L", ["l", "lt"], "volume", false, true, 0.001], - ["lumen", "lm", null, "luminous_flux", true, false, 1], - ["lux", "lx", null, "illuminance", true, false, 1], - ["maxwell", "Mx", null, "magnetic_flux", false, false, 1e-18], - ["measurement ton", "MTON", null, "volume", false, true, 1.13267386368], - ["meter per hour", "m/h", ["m/hr"], "speed", false, true, 0.00027777777777778], - ["meter per second", "m/s", ["m/sec"], "speed", true, true, 1], - ["meter per second squared", "m?s??", null, "acceleration", true, false, 1], - ["parsec", "pc", ["parsec"], "length", false, true, 30856775814671900], - ["meter squared per second", "m?/s", null, "kinematic_viscosity", true, false, 1], - ["metre", "m", null, "length", true, true, 1], - ["miles per hour", "mph", null, "speed", false, true, 0.44704], - ["millimetre of mercury", "mmHg", null, "pressure", false, false, 133.322], - ["minute", "?", null, "angle", false, false, 0.000290888208665722], - ["minute", "min", ["mn"], "time", false, true, 60], - ["modern teaspoon", "tspm", null, "volume", false, true, 0.000005], - ["mole", "mol", null, "amount_of_substance", true, false, 1], - ["morgen", "Morgen", null, "area", false, true, 2500], - ["n.u. of action", "?", null, "action", false, false, 1.05457168181818e-34], - ["n.u. of mass", "m?", null, "mass", false, false, 9.10938261616162e-31], - ["n.u. of speed", "c?", null, "speed", false, false, 299792458], - ["n.u. of time", "?/(me?c??)", null, "time", false, false, 1.28808866778687e-21], - ["nautical mile", "M", ["Nmi"], "length", false, true, 1852], - ["newton", "N", null, "force", true, true, 1], - ["œrsted", "Oe ", null, "magnetic_field_intensity", false, false, 79.5774715459477], - ["ohm", "Ω", null, "electric_resistance", true, false, 1], - ["ounce mass", "ozm", null, "mass", false, true, 0.028349523125], - ["pascal", "Pa", null, "pressure", true, false, 1], - ["pascal second", "Pa?s", null, "dynamic_viscosity", true, false, 1], - ["pferdestärke", "PS", null, "power", false, true, 735.49875], - ["phot", "ph", null, "illuminance", false, false, 0.0001], - ["pica (1/6 inch)", "pica", null, "length", false, true, 0.00035277777777778], - ["pica (1/72 inch)", "Pica", ["Picapt"], "length", false, true, 0.00423333333333333], - ["poise", "P", null, "dynamic_viscosity", false, false, 0.1], - ["pond", "pond", null, "force", false, true, 0.00980665], - ["pound force", "lbf", null, "force", false, true, 4.4482216152605], - ["pound mass", "lbm", null, "mass", false, true, 0.45359237], - ["quart", "qt", null, "volume", false, true, 0.000946352946], - ["radian", "rad", null, "angle", true, false, 1], - ["second", "?", null, "angle", false, false, 0.00000484813681109536], - ["second", "s", ["sec"], "time", true, true, 1], - ["short hundredweight", "cwt", ["shweight"], "mass", false, true, 45.359237], - ["siemens", "S", null, "electrical_conductance", true, false, 1], - ["sievert", "Sv", null, "equivalent_dose", true, false, 1], - ["slug", "sg", null, "mass", false, true, 14.59390294], - ["square ångström", "ang2", ["ang^2"], "area", false, true, 1e-20], - ["square foot", "ft2", ["ft^2"], "area", false, true, 0.09290304], - ["square inch", "in2", ["in^2"], "area", false, true, 0.00064516], - ["square light-year", "ly2", ["ly^2"], "area", false, true, 8.95054210748189e+31], - ["square meter", "m?", null, "area", true, true, 1], - ["square mile", "mi2", ["mi^2"], "area", false, true, 2589988.110336], - ["square nautical mile", "Nmi2", ["Nmi^2"], "area", false, true, 3429904], - ["square Pica", "Pica2", ["Picapt2", "Pica^2", "Picapt^2"], "area", false, true, 0.00001792111111111], - ["square yard", "yd2", ["yd^2"], "area", false, true, 0.83612736], - ["statute mile", "mi", null, "length", false, true, 1609.344], - ["steradian", "sr", null, "solid_angle", true, false, 1], - ["stilb", "sb", null, "luminance", false, false, 0.0001], - ["stokes", "St", null, "kinematic_viscosity", false, false, 0.0001], - ["stone", "stone", null, "mass", false, true, 6.35029318], - ["tablespoon", "tbs", null, "volume", false, true, 0.0000147868], - ["teaspoon", "tsp", null, "volume", false, true, 0.00000492892], - ["tesla", "T", null, "magnetic_flux_density", true, true, 1], - ["thermodynamic calorie", "c", null, "energy", false, true, 4.184], - ["ton", "ton", null, "mass", false, true, 907.18474], - ["tonne", "t", null, "mass", false, false, 1000], - ["U.K. pint", "uk_pt", null, "volume", false, true, 0.00056826125], - ["U.S. bushel", "bushel", null, "volume", false, true, 0.03523907], - ["U.S. oil barrel", "barrel", null, "volume", false, true, 0.158987295], - ["U.S. pint", "pt", ["us_pt"], "volume", false, true, 0.000473176473], - ["U.S. survey mile", "survey_mi", null, "length", false, true, 1609.347219], - ["U.S. survey/statute acre", "us_acre", null, "area", false, true, 4046.87261], - ["volt", "V", null, "voltage", true, false, 1], - ["watt", "W", null, "power", true, true, 1], - ["watt-hour", "Wh", ["wh"], "energy", false, true, 3600], - ["weber", "Wb", null, "magnetic_flux", true, false, 1], - ["yard", "yd", null, "length", false, true, 0.9144], - ["year", "yr", null, "time", false, true, 31557600] - ]; - - // Binary prefixes - // [Name, Prefix power of 2 value, Previx value, Abbreviation, Derived from] - var binary_prefixes = { - Yi: ["yobi", 80, 1208925819614629174706176, "Yi", "yotta"], - Zi: ["zebi", 70, 1180591620717411303424, "Zi", "zetta"], - Ei: ["exbi", 60, 1152921504606846976, "Ei", "exa"], - Pi: ["pebi", 50, 1125899906842624, "Pi", "peta"], - Ti: ["tebi", 40, 1099511627776, "Ti", "tera"], - Gi: ["gibi", 30, 1073741824, "Gi", "giga"], - Mi: ["mebi", 20, 1048576, "Mi", "mega"], - ki: ["kibi", 10, 1024, "ki", "kilo"] - }; - - // Unit prefixes - // [Name, Multiplier, Abbreviation] - var unit_prefixes = { - Y: ["yotta", 1e+24, "Y"], - Z: ["zetta", 1e+21, "Z"], - E: ["exa", 1e+18, "E"], - P: ["peta", 1e+15, "P"], - T: ["tera", 1e+12, "T"], - G: ["giga", 1e+09, "G"], - M: ["mega", 1e+06, "M"], - k: ["kilo", 1e+03, "k"], - h: ["hecto", 1e+02, "h"], - e: ["dekao", 1e+01, "e"], - d: ["deci", 1e-01, "d"], - c: ["centi", 1e-02, "c"], - m: ["milli", 1e-03, "m"], - u: ["micro", 1e-06, "u"], - n: ["nano", 1e-09, "n"], - p: ["pico", 1e-12, "p"], - f: ["femto", 1e-15, "f"], - a: ["atto", 1e-18, "a"], - z: ["zepto", 1e-21, "z"], - y: ["yocto", 1e-24, "y"] + exports.SINH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; + } + return (Math.exp(number) - Math.exp(-number)) / 2; }; - // Initialize units and multipliers - var from = null; - var to = null; - var base_from_unit = from_unit; - var base_to_unit = to_unit; - var from_multiplier = 1; - var to_multiplier = 1; - var alt; - - // Lookup from and to units - for (var i = 0; i < units.length; i++) { - alt = (units[i][2] === null) ? [] : units[i][2]; - if (units[i][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) { - from = units[i]; + exports.SQRT = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - if (units[i][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) { - to = units[i]; + if (number < 0) { + return error.num; } - } - - // Lookup from prefix - if (from === null) { - var from_binary_prefix = binary_prefixes[from_unit.substring(0, 2)]; - var from_unit_prefix = unit_prefixes[from_unit.substring(0, 1)]; + return Math.sqrt(number); + }; - // Handle dekao unit prefix (only unit prefix with two characters) - if (from_unit.substring(0, 2) === 'da') { - from_unit_prefix = ["dekao", 1e+01, "da"]; + exports.SQRTPI = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } + return Math.sqrt(number * Math.PI); + }; - // Handle binary prefixes first (so that 'Yi' is processed before 'Y') - if (from_binary_prefix) { - from_multiplier = from_binary_prefix[2]; - base_from_unit = from_unit.substring(2); - } else if (from_unit_prefix) { - from_multiplier = from_unit_prefix[1]; - base_from_unit = from_unit.substring(from_unit_prefix[2].length); - } + exports.SUBTOTAL = function(function_code, ref1) { + function_code = utils.parseNumber(function_code); + if (function_code instanceof Error) { + return function_code; + } + switch (function_code) { + case 1: + return statistical.AVERAGE(ref1); + case 2: + return statistical.COUNT(ref1); + case 3: + return statistical.COUNTA(ref1); + case 4: + return statistical.MAX(ref1); + case 5: + return statistical.MIN(ref1); + case 6: + return exports.PRODUCT(ref1); + case 7: + return statistical.STDEV.S(ref1); + case 8: + return statistical.STDEV.P(ref1); + case 9: + return exports.SUM(ref1); + case 10: + return statistical.VAR.S(ref1); + case 11: + return statistical.VAR.P(ref1); + // no hidden values for us + case 101: + return statistical.AVERAGE(ref1); + case 102: + return statistical.COUNT(ref1); + case 103: + return statistical.COUNTA(ref1); + case 104: + return statistical.MAX(ref1); + case 105: + return statistical.MIN(ref1); + case 106: + return exports.PRODUCT(ref1); + case 107: + return statistical.STDEV.S(ref1); + case 108: + return statistical.STDEV.P(ref1); + case 109: + return exports.SUM(ref1); + case 110: + return statistical.VAR.S(ref1); + case 111: + return statistical.VAR.P(ref1); - // Lookup from unit - for (var j = 0; j < units.length; j++) { - alt = (units[j][2] === null) ? [] : units[j][2]; - if (units[j][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) { - from = units[j]; - } - } } + }; - // Lookup to prefix - if (to === null) { - var to_binary_prefix = binary_prefixes[to_unit.substring(0, 2)]; - var to_unit_prefix = unit_prefixes[to_unit.substring(0, 1)]; + exports.ADD = function (num1, num2) { + if (arguments.length !== 2) { + return error.na; + } - // Handle dekao unit prefix (only unit prefix with two characters) - if (to_unit.substring(0, 2) === 'da') { - to_unit_prefix = ["dekao", 1e+01, "da"]; - } + num1 = utils.parseNumber(num1); + num2 = utils.parseNumber(num2); + if (utils.anyIsError(num1, num2)) { + return error.value; + } - // Handle binary prefixes first (so that 'Yi' is processed before 'Y') - if (to_binary_prefix) { - to_multiplier = to_binary_prefix[2]; - base_to_unit = to_unit.substring(2); - } else if (to_unit_prefix) { - to_multiplier = to_unit_prefix[1]; - base_to_unit = to_unit.substring(to_unit_prefix[2].length); - } + return num1 + num2; + }; - // Lookup to unit - for (var k = 0; k < units.length; k++) { - alt = (units[k][2] === null) ? [] : units[k][2]; - if (units[k][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) { - to = units[k]; - } - } + exports.MINUS = function (num1, num2) { + if (arguments.length !== 2) { + return error.na; } - // Return error if a unit does not exist - if (from === null || to === null) { - return error.na; + num1 = utils.parseNumber(num1); + num2 = utils.parseNumber(num2); + if (utils.anyIsError(num1, num2)) { + return error.value; } - // Return error if units represent different quantities - if (from[3] !== to[3]) { + return num1 - num2; + }; + + exports.DIVIDE = function (dividend, divisor) { + if (arguments.length !== 2) { return error.na; } - // Return converted number - return number * from[6] * from_multiplier / (to[6] * to_multiplier); - }; + dividend = utils.parseNumber(dividend); + divisor = utils.parseNumber(divisor); + if (utils.anyIsError(dividend, divisor)) { + return error.value; + } - exports.DEC2BIN = function(number, places) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + if (divisor === 0) { + return error.div0; } - // Return error if number is not decimal, is lower than -512, or is greater than 511 - if (!/^-?[0-9]{1,3}$/.test(number) || number < -512 || number > 511) { - return error.num; + return dividend / divisor; + }; + + exports.MULTIPLY = function (factor1, factor2) { + if (arguments.length !== 2) { + return error.na; } - // Ignore places and return a 10-character binary number if number is negative - if (number < 0) { - return '1' + text.REPT('0', 9 - (512 + number).toString(2).length) + (512 + number).toString(2); + factor1 = utils.parseNumber(factor1); + factor2 = utils.parseNumber(factor2); + if (utils.anyIsError(factor1, factor2)) { + return error.value; } - // Convert decimal number to binary - var result = parseInt(number, 10).toString(2); + return factor1 * factor2; + }; - // Return binary number using the minimum number of characters necessary if places is undefined - if (typeof places === 'undefined') { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; - } + exports.GTE = function (num1, num2) { + if (arguments.length !== 2) { + return error.na; + } - // Return error if places is negative - if (places < 0) { - return error.num; - } + num1 = utils.parseNumber(num1); + num2 = utils.parseNumber(num2); + if (utils.anyIsError(num1, num2)) { + return error.error; + } - // Truncate places in case it is not an integer - places = Math.floor(places); + return num1 >= num2; + }; - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + exports.LT = function (num1, num2) { + if (arguments.length !== 2) { + return error.na; + } + + num1 = utils.parseNumber(num1); + num2 = utils.parseNumber(num2); + if (utils.anyIsError(num1, num2)) { + return error.error; } + + return num1 < num2; }; - exports.DEC2HEX = function(number, places) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + + exports.LTE = function (num1, num2) { + if (arguments.length !== 2) { + return error.na; } - // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887 - if (!/^-?[0-9]{1,12}$/.test(number) || number < -549755813888 || number > 549755813887) { - return error.num; + num1 = utils.parseNumber(num1); + num2 = utils.parseNumber(num2); + if (utils.anyIsError(num1, num2)) { + return error.error; } - // Ignore places and return a 10-character hexadecimal number if number is negative - if (number < 0) { - return (1099511627776 + number).toString(16); + return num1 <= num2; + }; + + exports.EQ = function (value1, value2) { + if (arguments.length !== 2) { + return error.na; } - // Convert decimal number to hexadecimal - var result = parseInt(number, 10).toString(16); + return value1 === value2; + }; - // Return hexadecimal number using the minimum number of characters necessary if places is undefined - if (typeof places === 'undefined') { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; - } + exports.NE = function (value1, value2) { + if (arguments.length !== 2) { + return error.na; + } - // Return error if places is negative - if (places < 0) { - return error.num; - } + return value1 !== value2; + }; - // Truncate places in case it is not an integer - places = Math.floor(places); + exports.POW = function (base, exponent) { + if (arguments.length !== 2) { + return error.na; + } - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + base = utils.parseNumber(base); + exponent = utils.parseNumber(exponent); + if (utils.anyIsError(base, exponent)) { + return error.error; } + + return exports.POWER(base, exponent); }; - exports.DEC2OCT = function(number, places) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.SUM = function() { + var result = 0; + var argsKeys = Object.keys(arguments); + for (var i = 0; i < argsKeys.length; ++i) { + var elt = arguments[argsKeys[i]]; + if (typeof elt === 'number') { + result += elt; + } else if (typeof elt === 'string') { + var parsed = parseFloat(elt); + !isNaN(parsed) && (result += parsed); + } else if (Array.isArray(elt)) { + result += exports.SUM.apply(null, elt); + } } + return result; + }; - // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887 - if (!/^-?[0-9]{1,9}$/.test(number) || number < -536870912 || number > 536870911) { - return error.num; + exports.SUMIF = function(range, criteria, sum_range) { + range = utils.flatten(range); + sum_range = sum_range || range; + sum_range = utils.parseNumberArray(utils.flatten(sum_range)); + if (sum_range instanceof Error) { + return sum_range; } + if (!/[<>=!]/.test(criteria)) { + criteria = '==' + criteria; + } + if (/=[^=]/.test(criteria)) { + criteria = '=' + criteria; + } + var result = 0; + for (var i = 0; i < range.length; i++) { + result += (eval(range[i] + criteria)) ? sum_range[i] : 0; // jshint ignore:line + } + return result; + }; - // Ignore places and return a 10-character octal number if number is negative - if (number < 0) { - return (1073741824 + number).toString(8); + exports.SUMIFS = function() { + var args = utils.argsToArray(arguments); + var range = utils.parseNumberArray(utils.flatten(args.shift())); + if (range instanceof Error) { + return range; } + var criteria = args; - // Convert decimal number to octal - var result = parseInt(number, 10).toString(8); + var n_range_elements = range.length; + var n_criterias = criteria.length; - // Return octal number using the minimum number of characters necessary if places is undefined - if (typeof places === 'undefined') { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; + var result = 0; + for (var i = 0; i < n_range_elements; i++) { + var el = range[i]; + var condition = ''; + for (var c = 0; c < n_criterias; c++) { + condition += el + criteria[c]; + if (c !== n_criterias - 1) { + condition += '&&'; + } } - - // Return error if places is negative - if (places < 0) { - return error.num; + if (eval(condition)) { // jshint ignore:line + result += el; } - - // Truncate places in case it is not an integer - places = Math.floor(places); - - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; } + return result; }; - exports.DELTA = function(number1, number2) { - // Set number2 to zero if undefined - number2 = (number2 === undefined) ? 0 : number2; - number1 = utils.parseNumber(number1); - number2 = utils.parseNumber(number2); - if (utils.anyIsError(number1, number2)) { + exports.SUMPRODUCT = function() { + if (!arguments || arguments.length === 0) { return error.value; } - - // Return delta - return (number1 === number2) ? 1 : 0; + var arrays = arguments.length + 1; + var result = 0; + var product; + var k; + var _i; + var _ij; + for (var i = 0; i < arguments[0].length; i++) { + if (!(arguments[0][i] instanceof Array)) { + product = 1; + for (k = 1; k < arrays; k++) { + _i = utils.parseNumber(arguments[k - 1][i]); + if (_i instanceof Error) { + return _i; + } + product *= _i; + } + result += product; + } else { + for (var j = 0; j < arguments[0][i].length; j++) { + product = 1; + for (k = 1; k < arrays; k++) { + _ij = utils.parseNumber(arguments[k - 1][i][j]); + if (_ij instanceof Error) { + return _ij; + } + product *= _ij; + } + result += product; + } + } + } + return result; }; - // TODO: why is upper_bound not used ? The excel documentation has no examples with upper_bound - exports.ERF = function(lower_bound, upper_bound) { - // Set number2 to zero if undefined - upper_bound = (upper_bound === undefined) ? 0 : upper_bound; - - lower_bound = utils.parseNumber(lower_bound); - upper_bound = utils.parseNumber(upper_bound); - if (utils.anyIsError(lower_bound, upper_bound)) { - return error.value; + exports.SUMSQ = function() { + var numbers = utils.parseNumberArray(utils.flatten(arguments)); + if (numbers instanceof Error) { + return numbers; } - - return jStat.erf(lower_bound); + var result = 0; + var length = numbers.length; + for (var i = 0; i < length; i++) { + result += (information.ISNUMBER(numbers[i])) ? numbers[i] * numbers[i] : 0; + } + return result; }; - // TODO - exports.ERF.PRECISE = function() { - throw new Error('ERF.PRECISE is not implemented'); + exports.SUMX2MY2 = function(array_x, array_y) { + array_x = utils.parseNumberArray(utils.flatten(array_x)); + array_y = utils.parseNumberArray(utils.flatten(array_y)); + if (utils.anyIsError(array_x, array_y)) { + return error.value; + } + var result = 0; + for (var i = 0; i < array_x.length; i++) { + result += array_x[i] * array_x[i] - array_y[i] * array_y[i]; + } + return result; }; - exports.ERFC = function(x) { - // Return error if x is not a number - if (isNaN(x)) { + exports.SUMX2PY2 = function(array_x, array_y) { + array_x = utils.parseNumberArray(utils.flatten(array_x)); + array_y = utils.parseNumberArray(utils.flatten(array_y)); + if (utils.anyIsError(array_x, array_y)) { return error.value; } - - return jStat.erfc(x); + var result = 0; + array_x = utils.parseNumberArray(utils.flatten(array_x)); + array_y = utils.parseNumberArray(utils.flatten(array_y)); + for (var i = 0; i < array_x.length; i++) { + result += array_x[i] * array_x[i] + array_y[i] * array_y[i]; + } + return result; }; - // TODO - exports.ERFC.PRECISE = function() { - throw new Error('ERFC.PRECISE is not implemented'); + exports.SUMXMY2 = function(array_x, array_y) { + array_x = utils.parseNumberArray(utils.flatten(array_x)); + array_y = utils.parseNumberArray(utils.flatten(array_y)); + if (utils.anyIsError(array_x, array_y)) { + return error.value; + } + var result = 0; + array_x = utils.flatten(array_x); + array_y = utils.flatten(array_y); + for (var i = 0; i < array_x.length; i++) { + result += Math.pow(array_x[i] - array_y[i], 2); + } + return result; }; - exports.GESTEP = function(number, step) { - step = step || 0; + exports.TAN = function(number) { number = utils.parseNumber(number); - if (utils.anyIsError(step, number)) { + if (number instanceof Error) { return number; } + return Math.tan(number); + }; - // Return delta - return (number >= step) ? 1 : 0; + exports.TANH = function(number) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; + } + var e2 = Math.exp(2 * number); + return (e2 - 1) / (e2 + 1); }; - exports.HEX2BIN = function(number, places) { - // Return error if number is not hexadecimal or contains more than ten characters (10 digits) - if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) { - return error.num; + exports.TRUNC = function(number, digits) { + digits = (digits === undefined) ? 0 : digits; + number = utils.parseNumber(number); + digits = utils.parseNumber(digits); + if (utils.anyIsError(number, digits)) { + return error.value; } + var sign = (number > 0) ? 1 : -1; + return sign * (Math.floor(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits); + }; - // Check if number is negative - var negative = (number.length === 10 && number.substring(0, 1).toLowerCase() === 'f') ? true : false; - // Convert hexadecimal number to decimal - var decimal = (negative) ? parseInt(number, 16) - 1099511627776 : parseInt(number, 16); +/***/ }), +/* 3 */ +/***/ (function(module, exports) { - // Return error if number is lower than -512 or greater than 511 - if (decimal < -512 || decimal > 511) { - return error.num; - } + module.exports = __WEBPACK_EXTERNAL_MODULE_3__; - // Ignore places and return a 10-character binary number if number is negative - if (negative) { - return '1' + text.REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2); - } +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { - // Convert decimal number to binary - var result = decimal.toString(2); + var error = __webpack_require__(5); - // Return binary number using the minimum number of characters necessary if places is undefined - if (places === undefined) { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; + function flattenShallow(array) { + if (!array || !array.reduce) { return array; } + return array.reduce(function(a, b) { + var aIsArray = Array.isArray(a); + var bIsArray = Array.isArray(b); + if (aIsArray && bIsArray ) { + return a.concat(b); } - - // Return error if places is negative - if (places < 0) { - return error.num; + if (aIsArray) { + a.push(b); + return a; + } + if (bIsArray) { + return [a].concat(b); } + return [a, b]; + }); + } - // Truncate places in case it is not an integer - places = Math.floor(places); + function isFlat(array) { + if (!array) { return false; } + for (var i = 0; i < array.length; ++i) { + if (Array.isArray(array[i])) { + return false; + } + } + return true; + } - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + exports.flatten = function() { + var result = exports.argsToArray.apply(null, arguments); + while (!isFlat(result)) { + result = flattenShallow(result); } + return result; }; - exports.HEX2DEC = function(number) { - // Return error if number is not hexadecimal or contains more than ten characters (10 digits) - if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) { - return error.num; - } + exports.argsToArray = function(args) { + return Array.prototype.slice.call(args, 0); + }; - // Convert hexadecimal number to decimal - var decimal = parseInt(number, 16); + exports.numbers = function() { + var possibleNumbers = this.flatten.apply(null, arguments); + return possibleNumbers.filter(function(el) { + return typeof el === 'number'; + }); + }; - // Return decimal number - return (decimal >= 549755813888) ? decimal - 1099511627776 : decimal; + exports.cleanFloat = function(number) { + var power = 1e14; + return Math.round(number * power) / power; }; - exports.HEX2OCT = function(number, places) { - // Return error if number is not hexadecimal or contains more than ten characters (10 digits) - if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) { - return error.num; + exports.parseBool = function(bool) { + if (typeof bool === 'boolean') { + return bool; } - // Convert hexadecimal number to decimal - var decimal = parseInt(number, 16); - - // Return error if number is positive and greater than 0x1fffffff (536870911) - if (decimal > 536870911 && decimal < 1098974756864) { - return error.num; + if (bool instanceof Error) { + return bool; } - // Ignore places and return a 10-character octal number if number is negative - if (decimal >= 1098974756864) { - return (decimal - 1098437885952).toString(8); + if (typeof bool === 'number') { + return bool !== 0; } - // Convert decimal number to octal - var result = decimal.toString(8); - - // Return octal number using the minimum number of characters necessary if places is undefined - if (places === undefined) { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; + if (typeof bool === 'string') { + var up = bool.toUpperCase(); + if (up === 'TRUE') { + return true; } - // Return error if places is negative - if (places < 0) { - return error.num; + if (up === 'FALSE') { + return false; } - - // Truncate places in case it is not an integer - places = Math.floor(places); - - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; } - }; - - exports.IMABS = function(inumber) { - // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - // Return error if either coefficient is not a number - if (utils.anyIsError(x, y)) { - return error.value; + if (bool instanceof Date && !isNaN(bool)) { + return true; } - // Return absolute value of complex number - return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + return error.value; }; - exports.IMAGINARY = function(inumber) { - if (inumber === undefined || inumber === true || inumber === false) { + exports.parseNumber = function(string) { + if (string === undefined || string === '') { return error.value; } - - // Return 0 if inumber is equal to 0 - if (inumber === 0 || inumber === '0') { - return 0; + if (!isNaN(string)) { + return parseFloat(string); } + return error.value; + }; - // Handle special cases - if (['i', 'j'].indexOf(inumber) >= 0) { - return 1; + exports.parseNumberArray = function(arr) { + var len; + if (!arr || (len = arr.length) === 0) { + return error.value; } - - // Normalize imaginary coefficient - inumber = inumber.replace('+i', '+1i').replace('-i', '-1i').replace('+j', '+1j').replace('-j', '-1j'); - - // Lookup sign - var plus = inumber.indexOf('+'); - var minus = inumber.indexOf('-'); - if (plus === 0) { - plus = inumber.indexOf('+', 1); + var parsed; + while (len--) { + parsed = exports.parseNumber(arr[len]); + if (parsed === error.value) { + return parsed; + } + arr[len] = parsed; } + return arr; + }; - if (minus === 0) { - minus = inumber.indexOf('-', 1); + exports.parseMatrix = function(matrix) { + var n; + if (!matrix || (n = matrix.length) === 0) { + return error.value; } + var pnarr; + for (var i = 0; i < matrix.length; i++) { + pnarr = exports.parseNumberArray(matrix[i]); + matrix[i] = pnarr; + if (pnarr instanceof Error) { + return pnarr; + } + } + return matrix; + }; - // Lookup imaginary unit - var last = inumber.substring(inumber.length - 1, inumber.length); - var unit = (last === 'i' || last === 'j'); - - if (plus >= 0 || minus >= 0) { - // Return error if imaginary unit is neither i nor j - if (!unit) { + var d1900 = new Date(1900, 0, 1); + exports.parseDate = function(date) { + if (!isNaN(date)) { + if (date instanceof Date) { + return new Date(date); + } + var d = parseInt(date, 10); + if (d < 0) { return error.num; } - - // Return imaginary coefficient of complex number - if (plus >= 0) { - return (isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))) ? - error.num : - Number(inumber.substring(plus + 1, inumber.length - 1)); - } else { - return (isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))) ? - error.num : - -Number(inumber.substring(minus + 1, inumber.length - 1)); + if (d <= 60) { + return new Date(d1900.getTime() + (d - 1) * 86400000); } - } else { - if (unit) { - return (isNaN(inumber.substring(0, inumber.length - 1))) ? error.num : inumber.substring(0, inumber.length - 1); - } else { - return (isNaN(inumber)) ? error.num : 0; + return new Date(d1900.getTime() + (d - 2) * 86400000); + } + if (typeof date === 'string') { + date = new Date(date); + if (!isNaN(date)) { + return date; } } + return error.value; }; - exports.IMARGUMENT = function(inumber) { - // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - // Return error if either coefficient is not a number - if (utils.anyIsError(x, y)) { - return error.value; - } - - // Return error if inumber is equal to zero - if (x === 0 && y === 0) { - return error.div0; - } - - // Return PI/2 if x is equal to zero and y is positive - if (x === 0 && y > 0) { - return Math.PI / 2; + exports.parseDateArray = function(arr) { + var len = arr.length; + var parsed; + while (len--) { + parsed = this.parseDate(arr[len]); + if (parsed === error.value) { + return parsed; + } + arr[len] = parsed; } + return arr; + }; - // Return -PI/2 if x is equal to zero and y is negative - if (x === 0 && y < 0) { - return -Math.PI / 2; + exports.anyIsError = function() { + var n = arguments.length; + while (n--) { + if (arguments[n] instanceof Error) { + return true; + } } + return false; + }; - // Return zero if x is negative and y is equal to zero - if (y === 0 && x > 0) { - return 0; + exports.arrayValuesToNumbers = function(arr) { + var n = arr.length; + var el; + while (n--) { + el = arr[n]; + if (typeof el === 'number') { + continue; + } + if (el === true) { + arr[n] = 1; + continue; + } + if (el === false) { + arr[n] = 0; + continue; + } + if (typeof el === 'string') { + var number = this.parseNumber(el); + if (number instanceof Error) { + arr[n] = 0; + } else { + arr[n] = number; + } + } } + return arr; + }; - // Return zero if x is negative and y is equal to zero - if (y === 0 && x < 0) { - return -Math.PI; + exports.rest = function(array, idx) { + idx = idx || 1; + if (!array || typeof array.slice !== 'function') { + return array; } + return array.slice(idx); + }; - // Return argument of complex number - if (x > 0) { - return Math.atan(y / x); - } else if (x < 0 && y >= 0) { - return Math.atan(y / x) + Math.PI; - } else { - return Math.atan(y / x) - Math.PI; + exports.initial = function(array, idx) { + idx = idx || 1; + if (!array || typeof array.slice !== 'function') { + return array; } + return array.slice(0, array.length - idx); }; - exports.IMCONJUGATE = function(inumber) { - // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - if (utils.anyIsError(x, y)) { - return error.value; - } +/***/ }), +/* 5 */ +/***/ (function(module, exports) { - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; + exports.nil = new Error('#NULL!'); + exports.div0 = new Error('#DIV/0!'); + exports.value = new Error('#VALUE?'); + exports.ref = new Error('#REF!'); + exports.name = new Error('#NAME?'); + exports.num = new Error('#NUM!'); + exports.na = new Error('#N/A'); + exports.error = new Error('#ERROR!'); + exports.data = new Error('#GETTING_DATA'); - // Return conjugate of complex number - return (y !== 0) ? exports.COMPLEX(x, -y, unit) : inumber; - }; - exports.IMCOS = function(inumber) { - // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { - if (utils.anyIsError(x, y)) { - return error.value; - } + var mathTrig = __webpack_require__(2); + var text = __webpack_require__(7); + var jStat = __webpack_require__(9).jStat; + var utils = __webpack_require__(4); + var error = __webpack_require__(5); + var misc = __webpack_require__(10); - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; + var SQRT2PI = 2.5066282746310002; - // Return cosine of complex number - return exports.COMPLEX(Math.cos(x) * (Math.exp(y) + Math.exp(-y)) / 2, -Math.sin(x) * (Math.exp(y) - Math.exp(-y)) / 2, unit); + exports.AVEDEV = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; + } + return jStat.sum(jStat(range).subtract(jStat.mean(range)).abs()[0]) / range.length; }; - exports.IMCOSH = function(inumber) { - // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - if (utils.anyIsError(x, y)) { - return error.value; + exports.AVERAGE = function() { + var range = utils.numbers(utils.flatten(arguments)); + var n = range.length; + var sum = 0; + var count = 0; + for (var i = 0; i < n; i++) { + sum += range[i]; + count += 1; } + return sum / count; + }; - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Return hyperbolic cosine of complex number - return exports.COMPLEX(Math.cos(y) * (Math.exp(x) + Math.exp(-x)) / 2, Math.sin(y) * (Math.exp(x) - Math.exp(-x)) / 2, unit); + exports.AVERAGEA = function() { + var range = utils.flatten(arguments); + var n = range.length; + var sum = 0; + var count = 0; + for (var i = 0; i < n; i++) { + var el = range[i]; + if (typeof el === 'number') { + sum += el; + } + if (el === true) { + sum++; + } + if (el !== null) { + count++; + } + } + return sum / count; }; - exports.IMCOT = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.AVERAGEIF = function(range, criteria, average_range) { + average_range = average_range || range; + range = utils.flatten(range); + average_range = utils.parseNumberArray(utils.flatten(average_range)); + if (average_range instanceof Error) { + return average_range; + } + var average_count = 0; + var result = 0; + for (var i = 0; i < range.length; i++) { + if (eval(range[i] + criteria)) { // jshint ignore:line + result += average_range[i]; + average_count++; + } + } + return result / average_count; + }; - if (utils.anyIsError(x, y)) { - return error.value; + exports.AVERAGEIFS = function() { + // Does not work with multi dimensional ranges yet! + //http://office.microsoft.com/en-001/excel-help/averageifs-function-HA010047493.aspx + var args = utils.argsToArray(arguments); + var criteria = (args.length - 1) / 2; + var range = utils.flatten(args[0]); + var count = 0; + var result = 0; + for (var i = 0; i < range.length; i++) { + var condition = ''; + for (var j = 0; j < criteria; j++) { + condition += args[2 * j + 1][i] + args[2 * j + 2]; + if (j !== criteria - 1) { + condition += '&&'; + } + } + if (eval(condition)) { // jshint ignore:line + result += range[i]; + count++; + } } - // Return cotangent of complex number - return exports.IMDIV(exports.IMCOS(inumber), exports.IMSIN(inumber)); + var average = result / count; + if (isNaN(average)) { + return 0; + } else { + return average; + } }; - exports.IMDIV = function(inumber1, inumber2) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var a = exports.IMREAL(inumber1); - var b = exports.IMAGINARY(inumber1); - var c = exports.IMREAL(inumber2); - var d = exports.IMAGINARY(inumber2); + exports.BETA = {}; - if (utils.anyIsError(a, b, c, d)) { + exports.BETA.DIST = function(x, alpha, beta, cumulative, A, B) { + if (arguments.length < 4) { return error.value; } - // Lookup imaginary unit - var unit1 = inumber1.substring(inumber1.length - 1); - var unit2 = inumber2.substring(inumber2.length - 1); - var unit = 'i'; - if (unit1 === 'j') { - unit = 'j'; - } else if (unit2 === 'j') { - unit = 'j'; - } + A = (A === undefined) ? 0 : A; + B = (B === undefined) ? 1 : B; - // Return error if inumber2 is null - if (c === 0 && d === 0) { - return error.num; + x = utils.parseNumber(x); + alpha = utils.parseNumber(alpha); + beta = utils.parseNumber(beta); + A = utils.parseNumber(A); + B = utils.parseNumber(B); + if (utils.anyIsError(x, alpha, beta, A, B)) { + return error.value; } - // Return exponential of complex number - var den = c * c + d * d; - return exports.COMPLEX((a * c + b * d) / den, (b * c - a * d) / den, unit); + x = (x - A) / (B - A); + return (cumulative) ? jStat.beta.cdf(x, alpha, beta) : jStat.beta.pdf(x, alpha, beta); }; - exports.IMEXP = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.BETA.INV = function(probability, alpha, beta, A, B) { + A = (A === undefined) ? 0 : A; + B = (B === undefined) ? 1 : B; - if (utils.anyIsError(x, y)) { + probability = utils.parseNumber(probability); + alpha = utils.parseNumber(alpha); + beta = utils.parseNumber(beta); + A = utils.parseNumber(A); + B = utils.parseNumber(B); + if (utils.anyIsError(probability, alpha, beta, A, B)) { return error.value; } - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Return exponential of complex number - var e = Math.exp(x); - return exports.COMPLEX(e * Math.cos(y), e * Math.sin(y), unit); + return jStat.beta.inv(probability, alpha, beta) * (B - A) + A; }; - exports.IMLN = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.BINOM = {}; - if (utils.anyIsError(x, y)) { + exports.BINOM.DIST = function(successes, trials, probability, cumulative) { + successes = utils.parseNumber(successes); + trials = utils.parseNumber(trials); + probability = utils.parseNumber(probability); + cumulative = utils.parseNumber(cumulative); + if (utils.anyIsError(successes, trials, probability, cumulative)) { return error.value; } - - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Return exponential of complex number - return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)), Math.atan(y / x), unit); + return (cumulative) ? jStat.binomial.cdf(successes, trials, probability) : jStat.binomial.pdf(successes, trials, probability); }; - exports.IMLOG10 = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.BINOM.DIST.RANGE = function(trials, probability, successes, successes2) { + successes2 = (successes2 === undefined) ? successes : successes2; - if (utils.anyIsError(x, y)) { + trials = utils.parseNumber(trials); + probability = utils.parseNumber(probability); + successes = utils.parseNumber(successes); + successes2 = utils.parseNumber(successes2); + if (utils.anyIsError(trials, probability, successes, successes2)) { return error.value; } - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Return exponential of complex number - return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(10), Math.atan(y / x) / Math.log(10), unit); + var result = 0; + for (var i = successes; i <= successes2; i++) { + result += mathTrig.COMBIN(trials, i) * Math.pow(probability, i) * Math.pow(1 - probability, trials - i); + } + return result; }; - exports.IMLOG2 = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - if (utils.anyIsError(x, y)) { + exports.BINOM.INV = function(trials, probability, alpha) { + trials = utils.parseNumber(trials); + probability = utils.parseNumber(probability); + alpha = utils.parseNumber(alpha); + if (utils.anyIsError(trials, probability, alpha)) { return error.value; } - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Return exponential of complex number - return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(2), Math.atan(y / x) / Math.log(2), unit); + var x = 0; + while (x <= trials) { + if (jStat.binomial.cdf(x, trials, probability) >= alpha) { + return x; + } + x++; + } }; - exports.IMPOWER = function(inumber, number) { - number = utils.parseNumber(number); - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - if (utils.anyIsError(number, x, y)) { + exports.CHISQ = {}; + + exports.CHISQ.DIST = function(x, k, cumulative) { + x = utils.parseNumber(x); + k = utils.parseNumber(k); + if (utils.anyIsError(x, k)) { return error.value; } - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; + return (cumulative) ? jStat.chisquare.cdf(x, k) : jStat.chisquare.pdf(x, k); + }; - // Calculate power of modulus - var p = Math.pow(exports.IMABS(inumber), number); + exports.CHISQ.DIST.RT = function(x, k) { + if (!x | !k) { + return error.na; + } - // Calculate argument - var t = exports.IMARGUMENT(inumber); + if (x < 1 || k > Math.pow(10, 10)) { + return error.num; + } - // Return exponential of complex number - return exports.COMPLEX(p * Math.cos(number * t), p * Math.sin(number * t), unit); + if ((typeof x !== 'number') || (typeof k !== 'number')) { + return error.value; + } + + return 1 - jStat.chisquare.cdf(x, k); }; - exports.IMPRODUCT = function() { - // Initialize result - var result = arguments[0]; + exports.CHISQ.INV = function(probability, k) { + probability = utils.parseNumber(probability); + k = utils.parseNumber(k); + if (utils.anyIsError(probability, k)) { + return error.value; + } + return jStat.chisquare.inv(probability, k); + }; - // Loop on all numbers - for (var i = 1; i < arguments.length; i++) { - // Lookup coefficients of two complex numbers - var a = exports.IMREAL(result); - var b = exports.IMAGINARY(result); - var c = exports.IMREAL(arguments[i]); - var d = exports.IMAGINARY(arguments[i]); + exports.CHISQ.INV.RT = function(p, k) { + if (!p | !k) { + return error.na; + } - if (utils.anyIsError(a, b, c, d)) { - return error.value; - } + if (p < 0 || p > 1 || k < 1 || k > Math.pow(10, 10)) { + return error.num; + } - // Complute product of two complex numbers - result = exports.COMPLEX(a * c - b * d, a * d + b * c); + if ((typeof p !== 'number') || (typeof k !== 'number')) { + return error.value; } - // Return product of complex numbers - return result; + return jStat.chisquare.inv(1.0 - p, k); }; - exports.IMREAL = function(inumber) { - if (inumber === undefined || inumber === true || inumber === false) { - return error.value; + exports.CHISQ.TEST = function(observed, expected) { + if (arguments.length !== 2) { + return error.na; } - // Return 0 if inumber is equal to 0 - if (inumber === 0 || inumber === '0') { - return 0; + if ((!(observed instanceof Array)) || (!(expected instanceof Array))) { + return error.value; } - // Handle special cases - if (['i', '+i', '1i', '+1i', '-i', '-1i', 'j', '+j', '1j', '+1j', '-j', '-1j'].indexOf(inumber) >= 0) { - return 0; + if (observed.length !== expected.length) { + return error.value; } - // Lookup sign - var plus = inumber.indexOf('+'); - var minus = inumber.indexOf('-'); - if (plus === 0) { - plus = inumber.indexOf('+', 1); + if (observed[0] && expected[0] && + observed[0].length !== expected[0].length) { + return error.value; } - if (minus === 0) { - minus = inumber.indexOf('-', 1); + + var row = observed.length; + var tmp, i, j; + + // Convert single-dimension array into two-dimension array + for (i = 0; i < row; i ++) { + if (!(observed[i] instanceof Array)) { + tmp = observed[i]; + observed[i] = []; + observed[i].push(tmp); + } + if (!(expected[i] instanceof Array)) { + tmp = expected[i]; + expected[i] = []; + expected[i].push(tmp); + } } - // Lookup imaginary unit - var last = inumber.substring(inumber.length - 1, inumber.length); - var unit = (last === 'i' || last === 'j'); + var col = observed[0].length; + var dof = (col === 1) ? row-1 : (row-1)*(col-1); + var xsqr = 0; + var Pi =Math.PI; - if (plus >= 0 || minus >= 0) { - // Return error if imaginary unit is neither i nor j - if (!unit) { - return error.num; + for (i = 0; i < row; i ++) { + for (j = 0; j < col; j ++) { + xsqr += Math.pow((observed[i][j] - expected[i][j]), 2) / expected[i][j]; } + } - // Return real coefficient of complex number - if (plus >= 0) { - return (isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))) ? - error.num : - Number(inumber.substring(0, plus)); - } else { - return (isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))) ? - error.num : - Number(inumber.substring(0, minus)); + // Get independency by X square and its degree of freedom + function ChiSq(xsqr, dof) { + var p = Math.exp(-0.5 * xsqr); + if((dof%2) === 1) { + p = p * Math.sqrt(2 * xsqr/Pi); } - } else { - if (unit) { - return (isNaN(inumber.substring(0, inumber.length - 1))) ? error.num : 0; - } else { - return (isNaN(inumber)) ? error.num : inumber; + var k = dof; + while(k >= 2) { + p = p * xsqr/k; + k = k - 2; + } + var t = p; + var a = dof; + while (t > 0.0000000001*p) { + a = a + 2; + t = t * xsqr/a; + p = p + t; } + return 1-p; } + + return Math.round(ChiSq(xsqr, dof) * 1000000) / 1000000; }; - exports.IMSEC = function(inumber) { - // Return error if inumber is a logical value - if (inumber === true || inumber === false) { - return error.value; + exports.COLUMN = function(matrix, index) { + if (arguments.length !== 2) { + return error.na; } - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + if (index < 0) { + return error.num; + } - if (utils.anyIsError(x, y)) { + if (!(matrix instanceof Array) || (typeof index !== 'number')) { return error.value; } - // Return secant of complex number - return exports.IMDIV('1', exports.IMCOS(inumber)); - }; - - exports.IMSECH = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - if (utils.anyIsError(x, y)) { - return error.value; + if (matrix.length === 0) { + return undefined; } - // Return hyperbolic secant of complex number - return exports.IMDIV('1', exports.IMCOSH(inumber)); + return jStat.col(matrix, index); }; - exports.IMSIN = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.COLUMNS = function(matrix) { + if (arguments.length !== 1) { + return error.na; + } - if (utils.anyIsError(x, y)) { + if (!(matrix instanceof Array)) { return error.value; } - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; + if (matrix.length === 0) { + return 0; + } - // Return sine of complex number - return exports.COMPLEX(Math.sin(x) * (Math.exp(y) + Math.exp(-y)) / 2, Math.cos(x) * (Math.exp(y) - Math.exp(-y)) / 2, unit); + return jStat.cols(matrix); }; - exports.IMSINH = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.CONFIDENCE = {}; - if (utils.anyIsError(x, y)) { + exports.CONFIDENCE.NORM = function(alpha, sd, n) { + alpha = utils.parseNumber(alpha); + sd = utils.parseNumber(sd); + n = utils.parseNumber(n); + if (utils.anyIsError(alpha, sd, n)) { return error.value; } - - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Return hyperbolic sine of complex number - return exports.COMPLEX(Math.cos(y) * (Math.exp(x) - Math.exp(-x)) / 2, Math.sin(y) * (Math.exp(x) + Math.exp(-x)) / 2, unit); + return jStat.normalci(1, alpha, sd, n)[1] - 1; }; - exports.IMSQRT = function(inumber) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - if (utils.anyIsError(x, y)) { + exports.CONFIDENCE.T = function(alpha, sd, n) { + alpha = utils.parseNumber(alpha); + sd = utils.parseNumber(sd); + n = utils.parseNumber(n); + if (utils.anyIsError(alpha, sd, n)) { return error.value; } + return jStat.tci(1, alpha, sd, n)[1] - 1; + }; - // Lookup imaginary unit - var unit = inumber.substring(inumber.length - 1); - unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - - // Calculate power of modulus - var s = Math.sqrt(exports.IMABS(inumber)); + exports.CORREL = function(array1, array2) { + array1 = utils.parseNumberArray(utils.flatten(array1)); + array2 = utils.parseNumberArray(utils.flatten(array2)); + if (utils.anyIsError(array1, array2)) { + return error.value; + } + return jStat.corrcoeff(array1, array2); + }; - // Calculate argument - var t = exports.IMARGUMENT(inumber); + exports.COUNT = function() { + return utils.numbers(utils.flatten(arguments)).length; + }; - // Return exponential of complex number - return exports.COMPLEX(s * Math.cos(t / 2), s * Math.sin(t / 2), unit); + exports.COUNTA = function() { + var range = utils.flatten(arguments); + return range.length - exports.COUNTBLANK(range); }; - exports.IMCSC = function (inumber) { - // Return error if inumber is a logical value - if (inumber === true || inumber === false) { - return error.value; + exports.COUNTIN = function (range, value) { + var result = 0; + for (var i = 0; i < range.length; i++) { + if (range[i] === value) { + result++; + } } + return result; + }; - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - // Return error if either coefficient is not a number - if (utils.anyIsError(x, y)) { - return error.num; + exports.COUNTBLANK = function() { + var range = utils.flatten(arguments); + var blanks = 0; + var element; + for (var i = 0; i < range.length; i++) { + element = range[i]; + if (element === null || element === '') { + blanks++; + } } - - // Return cosecant of complex number - return exports.IMDIV('1', exports.IMSIN(inumber)); + return blanks; }; - exports.IMCSCH = function (inumber) { - // Return error if inumber is a logical value - if (inumber === true || inumber === false) { - return error.value; + exports.COUNTIF = function(range, criteria) { + range = utils.flatten(range); + if (!/[<>=!]/.test(criteria)) { + criteria = '=="' + criteria + '"'; } + var matches = 0; + for (var i = 0; i < range.length; i++) { + if (typeof range[i] !== 'string') { + if (eval(range[i] + criteria)) { // jshint ignore:line + matches++; + } + } else { + if (eval('"' + range[i] + '"' + criteria)) { // jshint ignore:line + matches++; + } + } + } + return matches; + }; - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); - - // Return error if either coefficient is not a number - if (utils.anyIsError(x, y)) { - return error.num; + exports.COUNTIFS = function() { + var args = utils.argsToArray(arguments); + var results = new Array(utils.flatten(args[0]).length); + for (var i = 0; i < results.length; i++) { + results[i] = true; + } + for (i = 0; i < args.length; i += 2) { + var range = utils.flatten(args[i]); + var criteria = args[i + 1]; + if (!/[<>=!]/.test(criteria)) { + criteria = '=="' + criteria + '"'; + } + for (var j = 0; j < range.length; j++) { + if (typeof range[j] !== 'string') { + results[j] = results[j] && eval(range[j] + criteria); // jshint ignore:line + } else { + results[j] = results[j] && eval('"' + range[j] + '"' + criteria); // jshint ignore:line + } + } + } + var result = 0; + for (i = 0; i < results.length; i++) { + if (results[i]) { + result++; + } } + return result; + }; - // Return hyperbolic cosecant of complex number - return exports.IMDIV('1', exports.IMSINH(inumber)); + exports.COUNTUNIQUE = function () { + return misc.UNIQUE.apply(null, utils.flatten(arguments)).length; }; - exports.IMSUB = function(inumber1, inumber2) { - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var a = this.IMREAL(inumber1); - var b = this.IMAGINARY(inumber1); - var c = this.IMREAL(inumber2); - var d = this.IMAGINARY(inumber2); + exports.COVARIANCE = {}; - if (utils.anyIsError(a, b, c, d)) { + exports.COVARIANCE.P = function(array1, array2) { + array1 = utils.parseNumberArray(utils.flatten(array1)); + array2 = utils.parseNumberArray(utils.flatten(array2)); + if (utils.anyIsError(array1, array2)) { return error.value; } - - // Lookup imaginary unit - var unit1 = inumber1.substring(inumber1.length - 1); - var unit2 = inumber2.substring(inumber2.length - 1); - var unit = 'i'; - if (unit1 === 'j') { - unit = 'j'; - } else if (unit2 === 'j') { - unit = 'j'; + var mean1 = jStat.mean(array1); + var mean2 = jStat.mean(array2); + var result = 0; + var n = array1.length; + for (var i = 0; i < n; i++) { + result += (array1[i] - mean1) * (array2[i] - mean2); } - - // Return _ of two complex numbers - return this.COMPLEX(a - c, b - d, unit); + return result / n; }; - exports.IMSUM = function() { - var args = utils.flatten(arguments); - - // Initialize result - var result = args[0]; - - // Loop on all numbers - for (var i = 1; i < args.length; i++) { - // Lookup coefficients of two complex numbers - var a = this.IMREAL(result); - var b = this.IMAGINARY(result); - var c = this.IMREAL(args[i]); - var d = this.IMAGINARY(args[i]); - - if (utils.anyIsError(a, b, c, d)) { - return error.value; - } - - // Complute product of two complex numbers - result = this.COMPLEX(a + c, b + d); + exports.COVARIANCE.S = function(array1, array2) { + array1 = utils.parseNumberArray(utils.flatten(array1)); + array2 = utils.parseNumberArray(utils.flatten(array2)); + if (utils.anyIsError(array1, array2)) { + return error.value; } + return jStat.covariance(array1, array2); + }; - // Return sum of complex numbers + exports.DEVSQ = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; + } + var mean = jStat.mean(range); + var result = 0; + for (var i = 0; i < range.length; i++) { + result += Math.pow((range[i] - mean), 2); + } return result; }; - exports.IMTAN = function(inumber) { - // Return error if inumber is a logical value - if (inumber === true || inumber === false) { + exports.EXPON = {}; + + exports.EXPON.DIST = function(x, lambda, cumulative) { + x = utils.parseNumber(x); + lambda = utils.parseNumber(lambda); + if (utils.anyIsError(x, lambda)) { return error.value; } + return (cumulative) ? jStat.exponential.cdf(x, lambda) : jStat.exponential.pdf(x, lambda); + }; - // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] - var x = exports.IMREAL(inumber); - var y = exports.IMAGINARY(inumber); + exports.F = {}; - if (utils.anyIsError(x, y)) { + exports.F.DIST = function(x, d1, d2, cumulative) { + x = utils.parseNumber(x); + d1 = utils.parseNumber(d1); + d2 = utils.parseNumber(d2); + if (utils.anyIsError(x, d1, d2)) { return error.value; } - - // Return tangent of complex number - return this.IMDIV(this.IMSIN(inumber), this.IMCOS(inumber)); + return (cumulative) ? jStat.centralF.cdf(x, d1, d2) : jStat.centralF.pdf(x, d1, d2); }; - exports.OCT2BIN = function(number, places) { - // Return error if number is not hexadecimal or contains more than ten characters (10 digits) - if (!/^[0-7]{1,10}$/.test(number)) { - return error.num; + exports.F.DIST.RT = function(x, d1, d2) { + if (arguments.length !== 3) { + return error.na; } - // Check if number is negative - var negative = (number.length === 10 && number.substring(0, 1) === '7') ? true : false; - - // Convert octal number to decimal - var decimal = (negative) ? parseInt(number, 8) - 1073741824 : parseInt(number, 8); - - // Return error if number is lower than -512 or greater than 511 - if (decimal < -512 || decimal > 511) { + if (x < 0 || d1 < 1 || d2 < 1) { return error.num; } - // Ignore places and return a 10-character binary number if number is negative - if (negative) { - return '1' + text.REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2); + if ((typeof x !== 'number') || (typeof d1 !== 'number') || (typeof d2 !== 'number')) { + return error.value; } - // Convert decimal number to binary - var result = decimal.toString(2); - - // Return binary number using the minimum number of characters necessary if places is undefined - if (typeof places === 'undefined') { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; - } - - // Return error if places is negative - if (places < 0) { - return error.num; - } - - // Truncate places in case it is not an integer - places = Math.floor(places); - - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; - } + return 1 - jStat.centralF.cdf(x, d1, d2); }; - exports.OCT2DEC = function(number) { - // Return error if number is not octal or contains more than ten characters (10 digits) - if (!/^[0-7]{1,10}$/.test(number)) { + exports.F.INV = function(probability, d1, d2) { + probability = utils.parseNumber(probability); + d1 = utils.parseNumber(d1); + d2 = utils.parseNumber(d2); + if (utils.anyIsError(probability, d1, d2)) { + return error.value; + } + if (probability <= 0.0 || probability > 1.0) { return error.num; } - // Convert octal number to decimal - var decimal = parseInt(number, 8); - - // Return decimal number - return (decimal >= 536870912) ? decimal - 1073741824 : decimal; + return jStat.centralF.inv(probability, d1, d2); }; - exports.OCT2HEX = function(number, places) { - // Return error if number is not octal or contains more than ten characters (10 digits) - if (!/^[0-7]{1,10}$/.test(number)) { - return error.num; + exports.F.INV.RT = function(p, d1, d2) { + if (arguments.length !== 3) { + return error.na; } - // Convert octal number to decimal - var decimal = parseInt(number, 8); - - // Ignore places and return a 10-character octal number if number is negative - if (decimal >= 536870912) { - return 'ff' + (decimal + 3221225472).toString(16); + if (p < 0 || p > 1 || d1 < 1 || d1 > Math.pow(10, 10) || d2 < 1 || d2 > Math.pow(10, 10)) { + return error.num; } - // Convert decimal number to hexadecimal - var result = decimal.toString(16); - - // Return hexadecimal number using the minimum number of characters necessary if places is undefined - if (places === undefined) { - return result; - } else { - // Return error if places is nonnumeric - if (isNaN(places)) { - return error.value; - } - - // Return error if places is negative - if (places < 0) { - return error.num; - } - - // Truncate places in case it is not an integer - places = Math.floor(places); - - // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) - return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + if ((typeof p !== 'number') || (typeof d1 !== 'number') || (typeof d2 !== 'number')) { + return error.value; } - }; - -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { - - var error = __webpack_require__(16); - var utils = __webpack_require__(17); - var information = __webpack_require__(9); - exports.AND = function() { - var args = utils.flatten(arguments); - var result = true; - for (var i = 0; i < args.length; i++) { - if (!args[i]) { - result = false; - } - } - return result; + return jStat.centralF.inv(1.0 - p, d1, d2); }; - exports.CHOOSE = function() { - if (arguments.length < 2) { + exports.F.TEST = function(array1, array2) { + if (!array1 || !array2) { return error.na; } - var index = arguments[0]; - if (index < 1 || index > 254) { - return error.value; + if (!(array1 instanceof Array) || !(array2 instanceof Array)) { + return error.na; } - if (arguments.length < index + 1) { - return error.value; + if (array1.length < 2 || array2.length < 2) { + return error.div0; } - return arguments[index]; - }; + var sumOfSquares = function(values, x1) { + var sum = 0; + for (var i = 0; i < values.length; i++) { + sum +=Math.pow((values[i] - x1), 2); + } + return sum; + }; - exports.FALSE = function() { - return false; - }; + var x1 = mathTrig.SUM(array1) / array1.length; + var x2 = mathTrig.SUM(array2) / array2.length; + var sum1 = sumOfSquares(array1, x1) / (array1.length - 1); + var sum2 = sumOfSquares(array2, x2) / (array2.length - 1); - exports.IF = function(test, then_value, otherwise_value) { - return test ? then_value : otherwise_value; + return sum1 / sum2; }; - exports.IFERROR = function(value, valueIfError) { - if (information.ISERROR(value)) { - return valueIfError; + exports.FISHER = function(x) { + x = utils.parseNumber(x); + if (x instanceof Error) { + return x; } - return value; - }; - - exports.IFNA = function(value, value_if_na) { - return value === error.na ? value_if_na : value; - }; - - exports.NOT = function(logical) { - return !logical; + return Math.log((1 + x) / (1 - x)) / 2; }; - exports.OR = function() { - var args = utils.flatten(arguments); - var result = false; - for (var i = 0; i < args.length; i++) { - if (args[i]) { - result = true; - } + exports.FISHERINV = function(y) { + y = utils.parseNumber(y); + if (y instanceof Error) { + return y; } - return result; - }; - - exports.TRUE = function() { - return true; + var e2y = Math.exp(2 * y); + return (e2y - 1) / (e2y + 1); }; - exports.XOR = function() { - var args = utils.flatten(arguments); - var result = 0; - for (var i = 0; i < args.length; i++) { - if (args[i]) { - result++; - } + exports.FORECAST = function(x, data_y, data_x) { + x = utils.parseNumber(x); + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + if (utils.anyIsError(x, data_y, data_x)) { + return error.value; } - return (Math.floor(Math.abs(result)) & 1) ? true : false; - }; - - exports.SWITCH = function () { - var result; - if (arguments.length > 0) { - var targetValue = arguments[0]; - var argc = arguments.length - 1; - var switchCount = Math.floor(argc / 2); - var switchSatisfied = false; - var defaultClause = argc % 2 === 0 ? null : arguments[arguments.length - 1]; + var xmean = jStat.mean(data_x); + var ymean = jStat.mean(data_y); + var n = data_x.length; + var num = 0; + var den = 0; + for (var i = 0; i < n; i++) { + num += (data_x[i] - xmean) * (data_y[i] - ymean); + den += Math.pow(data_x[i] - xmean, 2); + } + var b = num / den; + var a = ymean - b * xmean; + return a + b * x; + }; - if (switchCount) { - for (var index = 0; index < switchCount; index++) { - if (targetValue === arguments[index * 2 + 1]) { - result = arguments[index * 2 + 2]; - switchSatisfied = true; - break; + exports.FREQUENCY = function(data, bins) { + data = utils.parseNumberArray(utils.flatten(data)); + bins = utils.parseNumberArray(utils.flatten(bins)); + if (utils.anyIsError(data, bins)) { + return error.value; + } + var n = data.length; + var b = bins.length; + var r = []; + for (var i = 0; i <= b; i++) { + r[i] = 0; + for (var j = 0; j < n; j++) { + if (i === 0) { + if (data[j] <= bins[0]) { + r[0] += 1; + } + } else if (i < b) { + if (data[j] > bins[i - 1] && data[j] <= bins[i]) { + r[i] += 1; + } + } else if (i === b) { + if (data[j] > bins[b - 1]) { + r[b] += 1; } } } - - if (!switchSatisfied && defaultClause) { - result = defaultClause; - } } - - return result; + return r; }; -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { - - var numeric = __webpack_require__(14); - var utils = __webpack_require__(17); - var error = __webpack_require__(16); - var statistical = __webpack_require__(11); - var information = __webpack_require__(9); - - exports.ABS = function(number) { + exports.GAMMA = function(number) { number = utils.parseNumber(number); if (number instanceof Error) { return number; } - return Math.abs(utils.parseNumber(number)); - }; - exports.ACOS = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + if (number === 0) { + return error.num; } - return Math.acos(number); - }; - exports.ACOSH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + if (parseInt(number, 10) === number && number < 0) { + return error.num; } - return Math.log(number + Math.sqrt(number * number - 1)); - }; - exports.ACOT = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - return Math.atan(1 / number); + return jStat.gammafn(number); }; - exports.ACOTH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.GAMMA.DIST = function(value, alpha, beta, cumulative) { + if (arguments.length !== 4) { + return error.na; } - return 0.5 * Math.log((number + 1) / (number - 1)); - }; - //TODO: use options - exports.AGGREGATE = function(function_num, options, ref1, ref2) { - function_num = utils.parseNumber(function_num); - options = utils.parseNumber(function_num); - if (utils.anyIsError(function_num, options)) { + if (value < 0 || alpha <= 0 || beta <= 0) { return error.value; } - switch (function_num) { - case 1: - return statistical.AVERAGE(ref1); - case 2: - return statistical.COUNT(ref1); - case 3: - return statistical.COUNTA(ref1); - case 4: - return statistical.MAX(ref1); - case 5: - return statistical.MIN(ref1); - case 6: - return exports.PRODUCT(ref1); - case 7: - return statistical.STDEV.S(ref1); - case 8: - return statistical.STDEV.P(ref1); - case 9: - return exports.SUM(ref1); - case 10: - return statistical.VAR.S(ref1); - case 11: - return statistical.VAR.P(ref1); - case 12: - return statistical.MEDIAN(ref1); - case 13: - return statistical.MODE.SNGL(ref1); - case 14: - return statistical.LARGE(ref1, ref2); - case 15: - return statistical.SMALL(ref1, ref2); - case 16: - return statistical.PERCENTILE.INC(ref1, ref2); - case 17: - return statistical.QUARTILE.INC(ref1, ref2); - case 18: - return statistical.PERCENTILE.EXC(ref1, ref2); - case 19: - return statistical.QUARTILE.EXC(ref1, ref2); - } - }; - exports.ARABIC = function(text) { - // Credits: Rafa? Kukawski - if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(text)) { + if ((typeof value !== 'number') || (typeof alpha !== 'number') || (typeof beta !== 'number')) { return error.value; } - var r = 0; - text.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) { - r += { - M: 1000, - CM: 900, - D: 500, - CD: 400, - C: 100, - XC: 90, - L: 50, - XL: 40, - X: 10, - IX: 9, - V: 5, - IV: 4, - I: 1 - }[i]; - }); - return r; - }; - exports.ASIN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - return Math.asin(number); + return cumulative ? jStat.gamma.cdf(value, alpha, beta, true) : jStat.gamma.pdf(value, alpha, beta, false); }; - exports.ASINH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.GAMMA.INV = function(probability, alpha, beta) { + if (arguments.length !== 3) { + return error.na; } - return Math.log(number + Math.sqrt(number * number + 1)); - }; - exports.ATAN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + if (probability < 0 || probability > 1 || alpha <= 0 || beta <= 0) { + return error.num; } - return Math.atan(number); - }; - exports.ATAN2 = function(number_x, number_y) { - number_x = utils.parseNumber(number_x); - number_y = utils.parseNumber(number_y); - if (utils.anyIsError(number_x, number_y)) { + if ((typeof probability !== 'number') || (typeof alpha !== 'number') || (typeof beta !== 'number')) { return error.value; } - return Math.atan2(number_x, number_y); + + return jStat.gamma.inv(probability, alpha, beta); }; - exports.ATANH = function(number) { + exports.GAMMALN = function(number) { number = utils.parseNumber(number); if (number instanceof Error) { return number; } - return Math.log((1 + number) / (1 - number)) / 2; + return jStat.gammaln(number); }; - exports.BASE = function(number, radix, min_length) { - min_length = min_length || 0; - - number = utils.parseNumber(number); - radix = utils.parseNumber(radix); - min_length = utils.parseNumber(min_length); - if (utils.anyIsError(number, radix, min_length)) { - return error.value; + exports.GAMMALN.PRECISE = function(x) { + if (arguments.length !== 1) { + return error.na; } - min_length = (min_length === undefined) ? 0 : min_length; - var result = number.toString(radix); - return new Array(Math.max(min_length + 1 - result.length, 0)).join('0') + result; - }; - exports.CEILING = function(number, significance, mode) { - significance = (significance === undefined) ? 1 : Math.abs(significance); - mode = mode || 0; + if (x <= 0) { + return error.num; + } - number = utils.parseNumber(number); - significance = utils.parseNumber(significance); - mode = utils.parseNumber(mode); - if (utils.anyIsError(number, significance, mode)) { + if (typeof x !== 'number') { return error.value; } - if (significance === 0) { - return 0; + + return jStat.gammaln(x); + }; + + exports.GAUSS = function(z) { + z = utils.parseNumber(z); + if (z instanceof Error) { + return z; } - var precision = -Math.floor(Math.log(significance) / Math.log(10)); - if (number >= 0) { - return exports.ROUND(Math.ceil(number / significance) * significance, precision); - } else { - if (mode === 0) { - return -exports.ROUND(Math.floor(Math.abs(number) / significance) * significance, precision); - } else { - return -exports.ROUND(Math.ceil(Math.abs(number) / significance) * significance, precision); - } + return jStat.normal.cdf(z, 0, 1) - 0.5; + }; + + exports.GEOMEAN = function() { + var args = utils.parseNumberArray(utils.flatten(arguments)); + if (args instanceof Error) { + return args; } + return jStat.geomean(args); }; - exports.CEILING.MATH = exports.CEILING; + exports.GROWTH = function(known_y, known_x, new_x, use_const) { + // Credits: Ilmari Karonen (http://stackoverflow.com/questions/14161990/how-to-implement-growth-function-in-javascript) - exports.CEILING.PRECISE = exports.CEILING; + known_y = utils.parseNumberArray(known_y); + if (known_y instanceof Error) { + return known_y; + } - exports.COMBIN = function(number, number_chosen) { - number = utils.parseNumber(number); - number_chosen = utils.parseNumber(number_chosen); - if (utils.anyIsError(number, number_chosen)) { - return error.value; + // Default values for optional parameters: + var i; + if (known_x === undefined) { + known_x = []; + for (i = 1; i <= known_y.length; i++) { + known_x.push(i); + } + } + if (new_x === undefined) { + new_x = []; + for (i = 1; i <= known_y.length; i++) { + new_x.push(i); + } } - return exports.FACT(number) / (exports.FACT(number_chosen) * exports.FACT(number - number_chosen)); - }; - exports.COMBINA = function(number, number_chosen) { - number = utils.parseNumber(number); - number_chosen = utils.parseNumber(number_chosen); - if (utils.anyIsError(number, number_chosen)) { + known_x = utils.parseNumberArray(known_x); + new_x = utils.parseNumberArray(new_x); + if (utils.anyIsError(known_x, new_x)) { return error.value; } - return (number === 0 && number_chosen === 0) ? 1 : exports.COMBIN(number + number_chosen - 1, number - 1); - }; - exports.COS = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - return Math.cos(number); - }; - exports.COSH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + if (use_const === undefined) { + use_const = true; } - return (Math.exp(number) + Math.exp(-number)) / 2; - }; - exports.COT = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + // Calculate sums over the data: + var n = known_y.length; + var avg_x = 0; + var avg_y = 0; + var avg_xy = 0; + var avg_xx = 0; + for (i = 0; i < n; i++) { + var x = known_x[i]; + var y = Math.log(known_y[i]); + avg_x += x; + avg_y += y; + avg_xy += x * y; + avg_xx += x * x; } - return 1 / Math.tan(number); - }; + avg_x /= n; + avg_y /= n; + avg_xy /= n; + avg_xx /= n; - exports.COTH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + // Compute linear regression coefficients: + var beta; + var alpha; + if (use_const) { + beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x); + alpha = avg_y - beta * avg_x; + } else { + beta = avg_xy / avg_xx; + alpha = 0; } - var e2 = Math.exp(2 * number); - return (e2 + 1) / (e2 - 1); - }; - exports.CSC = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + // Compute and return result array: + var new_y = []; + for (i = 0; i < new_x.length; i++) { + new_y.push(Math.exp(alpha + beta * new_x[i])); } - return 1 / Math.sin(number); + return new_y; }; - exports.CSCH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.HARMEAN = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; } - return 2 / (Math.exp(number) - Math.exp(-number)); + var n = range.length; + var den = 0; + for (var i = 0; i < n; i++) { + den += 1 / range[i]; + } + return n / den; }; - exports.DECIMAL = function(number, radix) { - if (arguments.length < 1) { + exports.HYPGEOM = {}; + + exports.HYPGEOM.DIST = function(x, n, M, N, cumulative) { + x = utils.parseNumber(x); + n = utils.parseNumber(n); + M = utils.parseNumber(M); + N = utils.parseNumber(N); + if (utils.anyIsError(x, n, M, N)) { return error.value; } - - return parseInt(number, radix); - }; - - exports.DEGREES = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + function pdf(x, n, M, N) { + return mathTrig.COMBIN(M, x) * mathTrig.COMBIN(N - M, n - x) / mathTrig.COMBIN(N, n); } - return number * 180 / Math.PI; - }; - exports.EVEN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + function cdf(x, n, M, N) { + var result = 0; + for (var i = 0; i <= x; i++) { + result += pdf(i, n, M, N); + } + return result; } - return exports.CEILING(number, -2, -1); - }; - exports.EXP = Math.exp; + return (cumulative) ? cdf(x, n, M, N) : pdf(x, n, M, N); + }; - var MEMOIZED_FACT = []; - exports.FACT = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.INTERCEPT = function(known_y, known_x) { + known_y = utils.parseNumberArray(known_y); + known_x = utils.parseNumberArray(known_x); + if (utils.anyIsError(known_y, known_x)) { + return error.value; } - var n = Math.floor(number); - if (n === 0 || n === 1) { - return 1; - } else if (MEMOIZED_FACT[n] > 0) { - return MEMOIZED_FACT[n]; - } else { - MEMOIZED_FACT[n] = exports.FACT(n - 1) * n; - return MEMOIZED_FACT[n]; + if (known_y.length !== known_x.length) { + return error.na; } + return exports.FORECAST(0, known_y, known_x); }; - exports.FACTDOUBLE = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.KURT = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; } - var n = Math.floor(number); - if (n <= 0) { - return 1; - } else { - return n * exports.FACTDOUBLE(n - 2); + var mean = jStat.mean(range); + var n = range.length; + var sigma = 0; + for (var i = 0; i < n; i++) { + sigma += Math.pow(range[i] - mean, 4); } + sigma = sigma / Math.pow(jStat.stdev(range, true), 4); + return ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sigma - 3 * (n - 1) * (n - 1) / ((n - 2) * (n - 3)); }; - exports.FLOOR = function(number, significance) { - number = utils.parseNumber(number); - significance = utils.parseNumber(significance); - if (utils.anyIsError(number, significance)) { - return error.value; - } - if (significance === 0) { - return 0; + exports.LARGE = function(range, k) { + range = utils.parseNumberArray(utils.flatten(range)); + k = utils.parseNumber(k); + if (utils.anyIsError(range, k)) { + return range; } + return range.sort(function(a, b) { + return b - a; + })[k - 1]; + }; - if (!(number > 0 && significance > 0) && !(number < 0 && significance < 0)) { - return error.num; + exports.LINEST = function(data_y, data_x) { + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + if (utils.anyIsError(data_y, data_x)) { + return error.value; } - - significance = Math.abs(significance); - var precision = -Math.floor(Math.log(significance) / Math.log(10)); - if (number >= 0) { - return exports.ROUND(Math.floor(number / significance) * significance, precision); - } else { - return -exports.ROUND(Math.ceil(Math.abs(number) / significance), precision); + var ymean = jStat.mean(data_y); + var xmean = jStat.mean(data_x); + var n = data_x.length; + var num = 0; + var den = 0; + for (var i = 0; i < n; i++) { + num += (data_x[i] - xmean) * (data_y[i] - ymean); + den += Math.pow(data_x[i] - xmean, 2); } + var m = num / den; + var b = ymean - m * xmean; + return [m, b]; }; - //TODO: Verify - exports.FLOOR.MATH = function(number, significance, mode) { - significance = (significance === undefined) ? 1 : significance; - mode = (mode === undefined) ? 0 : mode; - - number = utils.parseNumber(number); - significance = utils.parseNumber(significance); - mode = utils.parseNumber(mode); - if (utils.anyIsError(number, significance, mode)) { + // According to Microsoft: + // http://office.microsoft.com/en-us/starter-help/logest-function-HP010342665.aspx + // LOGEST returns are based on the following linear model: + // ln y = x1 ln m1 + ... + xn ln mn + ln b + exports.LOGEST = function(data_y, data_x) { + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + if (utils.anyIsError(data_y, data_x)) { return error.value; } - if (significance === 0) { - return 0; + for (var i = 0; i < data_y.length; i ++) { + data_y[i] = Math.log(data_y[i]); } - significance = significance ? Math.abs(significance) : 1; - var precision = -Math.floor(Math.log(significance) / Math.log(10)); - if (number >= 0) { - return exports.ROUND(Math.floor(number / significance) * significance, precision); - } else if (mode === 0 || mode === undefined) { - return -exports.ROUND(Math.ceil(Math.abs(number) / significance) * significance, precision); - } - return -exports.ROUND(Math.floor(Math.abs(number) / significance) * significance, precision); + var result = exports.LINEST(data_y, data_x); + result[0] = Math.round(Math.exp(result[0])*1000000)/1000000; + result[1] = Math.round(Math.exp(result[1])*1000000)/1000000; + return result; }; - // Deprecated - exports.FLOOR.PRECISE = exports.FLOOR.MATH; + exports.LOGNORM = {}; - // adapted http://rosettacode.org/wiki/Greatest_common_divisor#JavaScript - exports.GCD = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; - } - var n = range.length; - var r0 = range[0]; - var x = r0 < 0 ? -r0 : r0; - for (var i = 1; i < n; i++) { - var ri = range[i]; - var y = ri < 0 ? -ri : ri; - while (x && y) { - if (x > y) { - x %= y; - } else { - y %= x; - } - } - x += y; + exports.LOGNORM.DIST = function(x, mean, sd, cumulative) { + x = utils.parseNumber(x); + mean = utils.parseNumber(mean); + sd = utils.parseNumber(sd); + if (utils.anyIsError(x, mean, sd)) { + return error.value; } - return x; + return (cumulative) ? jStat.lognormal.cdf(x, mean, sd) : jStat.lognormal.pdf(x, mean, sd); }; - - exports.INT = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.LOGNORM.INV = function(probability, mean, sd) { + probability = utils.parseNumber(probability); + mean = utils.parseNumber(mean); + sd = utils.parseNumber(sd); + if (utils.anyIsError(probability, mean, sd)) { + return error.value; } - return Math.floor(number); + return jStat.lognormal.inv(probability, mean, sd); }; - //TODO: verify - exports.ISO = { - CEILING: exports.CEILING + exports.MAX = function() { + var range = utils.numbers(utils.flatten(arguments)); + return (range.length === 0) ? 0 : Math.max.apply(Math, range); }; - exports.LCM = function() { - // Credits: Jonas Raoni Soares Silva - var o = utils.parseNumberArray(utils.flatten(arguments)); - if (o instanceof Error) { - return o; - } - for (var i, j, n, d, r = 1; - (n = o.pop()) !== undefined;) { - while (n > 1) { - if (n % 2) { - for (i = 3, j = Math.floor(Math.sqrt(n)); i <= j && n % i; i += 2) { - //empty - } - d = (i <= j) ? i : n; - } else { - d = 2; - } - for (n /= d, r *= d, i = o.length; i; - (o[--i] % d) === 0 && (o[i] /= d) === 1 && o.splice(i, 1)) { - //empty - } - } - } - return r; + exports.MAXA = function() { + var range = utils.arrayValuesToNumbers(utils.flatten(arguments)); + return (range.length === 0) ? 0 : Math.max.apply(Math, range); }; - exports.LN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - return Math.log(number); + exports.MEDIAN = function() { + var range = utils.arrayValuesToNumbers(utils.flatten(arguments)); + return jStat.median(range); }; - exports.LOG = function(number, base) { - number = utils.parseNumber(number); - base = (base === undefined) ? 10 : utils.parseNumber(base); - - if (utils.anyIsError(number, base)) { - return error.value; - } - - return Math.log(number) / Math.log(base); + exports.MIN = function() { + var range = utils.numbers(utils.flatten(arguments)); + return (range.length === 0) ? 0 : Math.min.apply(Math, range); }; - exports.LOG10 = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - return Math.log(number) / Math.log(10); + exports.MINA = function() { + var range = utils.arrayValuesToNumbers(utils.flatten(arguments)); + return (range.length === 0) ? 0 : Math.min.apply(Math, range); }; - exports.MDETERM = function(matrix) { - matrix = utils.parseMatrix(matrix); - if (matrix instanceof Error) { - return matrix; + exports.MODE = {}; + + exports.MODE.MULT = function() { + // Credits: Roönaän + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; } - return numeric.det(matrix); - }; + var n = range.length; + var count = {}; + var maxItems = []; + var max = 0; + var currentItem; - exports.MINVERSE = function(matrix) { - matrix = utils.parseMatrix(matrix); - if (matrix instanceof Error) { - return matrix; + for (var i = 0; i < n; i++) { + currentItem = range[i]; + count[currentItem] = count[currentItem] ? count[currentItem] + 1 : 1; + if (count[currentItem] > max) { + max = count[currentItem]; + maxItems = []; + } + if (count[currentItem] === max) { + maxItems[maxItems.length] = currentItem; + } } - return numeric.inv(matrix); + return maxItems; }; - exports.MMULT = function(matrix1, matrix2) { - matrix1 = utils.parseMatrix(matrix1); - matrix2 = utils.parseMatrix(matrix2); - if (utils.anyIsError(matrix1, matrix2)) { - return error.value; + exports.MODE.SNGL = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; } - return numeric.dot(matrix1, matrix2); + return exports.MODE.MULT(range).sort(function(a, b) { + return a - b; + })[0]; }; - exports.MOD = function(dividend, divisor) { - dividend = utils.parseNumber(dividend); - divisor = utils.parseNumber(divisor); - if (utils.anyIsError(dividend, divisor)) { + exports.NEGBINOM = {}; + + exports.NEGBINOM.DIST = function(k, r, p, cumulative) { + k = utils.parseNumber(k); + r = utils.parseNumber(r); + p = utils.parseNumber(p); + if (utils.anyIsError(k, r, p)) { return error.value; } - if (divisor === 0) { - return error.div0; - } - var modulus = Math.abs(dividend % divisor); - return (divisor > 0) ? modulus : -modulus; + return (cumulative) ? jStat.negbin.cdf(k, r, p) : jStat.negbin.pdf(k, r, p); }; - exports.MROUND = function(number, multiple) { - number = utils.parseNumber(number); - multiple = utils.parseNumber(multiple); - if (utils.anyIsError(number, multiple)) { + exports.NORM = {}; + + exports.NORM.DIST = function(x, mean, sd, cumulative) { + x = utils.parseNumber(x); + mean = utils.parseNumber(mean); + sd = utils.parseNumber(sd); + if (utils.anyIsError(x, mean, sd)) { return error.value; } - if (number * multiple < 0) { + if (sd <= 0) { return error.num; } - return Math.round(number / multiple) * multiple; + // Return normal distribution computed by jStat [http://jstat.org] + return (cumulative) ? jStat.normal.cdf(x, mean, sd) : jStat.normal.pdf(x, mean, sd); }; - exports.MULTINOMIAL = function() { - var args = utils.parseNumberArray(utils.flatten(arguments)); - if (args instanceof Error) { - return args; - } - var sum = 0; - var divisor = 1; - for (var i = 0; i < args.length; i++) { - sum += args[i]; - divisor *= exports.FACT(args[i]); + exports.NORM.INV = function(probability, mean, sd) { + probability = utils.parseNumber(probability); + mean = utils.parseNumber(mean); + sd = utils.parseNumber(sd); + if (utils.anyIsError(probability, mean, sd)) { + return error.value; } - return exports.FACT(sum) / divisor; + return jStat.normal.inv(probability, mean, sd); }; - exports.MUNIT = function(dimension) { - dimension = utils.parseNumber(dimension); - if (dimension instanceof Error) { - return dimension; - } - return numeric.identity(dimension); - }; + exports.NORM.S = {}; - exports.ODD = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.NORM.S.DIST = function(z, cumulative) { + z = utils.parseNumber(z); + if (z instanceof Error) { + return error.value; } - var temp = Math.ceil(Math.abs(number)); - temp = (temp & 1) ? temp : temp + 1; - return (number > 0) ? temp : -temp; - }; - - exports.PI = function() { - return Math.PI; + return (cumulative) ? jStat.normal.cdf(z, 0, 1) : jStat.normal.pdf(z, 0, 1); }; - exports.POWER = function(number, power) { - number = utils.parseNumber(number); - power = utils.parseNumber(power); - if (utils.anyIsError(number, power)) { + exports.NORM.S.INV = function(probability) { + probability = utils.parseNumber(probability); + if (probability instanceof Error) { return error.value; } - var result = Math.pow(number, power); - if (isNaN(result)) { - return error.num; - } - - return result; + return jStat.normal.inv(probability, 0, 1); }; - exports.PRODUCT = function() { - var args = utils.parseNumberArray(utils.flatten(arguments)); - if (args instanceof Error) { - return args; + exports.PEARSON = function(data_x, data_y) { + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + if (utils.anyIsError(data_y, data_x)) { + return error.value; } - var result = 1; - for (var i = 0; i < args.length; i++) { - result *= args[i]; + var xmean = jStat.mean(data_x); + var ymean = jStat.mean(data_y); + var n = data_x.length; + var num = 0; + var den1 = 0; + var den2 = 0; + for (var i = 0; i < n; i++) { + num += (data_x[i] - xmean) * (data_y[i] - ymean); + den1 += Math.pow(data_x[i] - xmean, 2); + den2 += Math.pow(data_y[i] - ymean, 2); } - return result; + return num / Math.sqrt(den1 * den2); }; - exports.QUOTIENT = function(numerator, denominator) { - numerator = utils.parseNumber(numerator); - denominator = utils.parseNumber(denominator); - if (utils.anyIsError(numerator, denominator)) { + exports.PERCENTILE = {}; + + exports.PERCENTILE.EXC = function(array, k) { + array = utils.parseNumberArray(utils.flatten(array)); + k = utils.parseNumber(k); + if (utils.anyIsError(array, k)) { return error.value; } - return parseInt(numerator / denominator, 10); + array = array.sort(function(a, b) { + { + return a - b; + } + }); + var n = array.length; + if (k < 1 / (n + 1) || k > 1 - 1 / (n + 1)) { + return error.num; + } + var l = k * (n + 1) - 1; + var fl = Math.floor(l); + return utils.cleanFloat((l === fl) ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl])); }; - exports.RADIANS = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.PERCENTILE.INC = function(array, k) { + array = utils.parseNumberArray(utils.flatten(array)); + k = utils.parseNumber(k); + if (utils.anyIsError(array, k)) { + return error.value; } - return number * Math.PI / 180; + array = array.sort(function(a, b) { + return a - b; + }); + var n = array.length; + var l = k * (n - 1); + var fl = Math.floor(l); + return utils.cleanFloat((l === fl) ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl])); }; - exports.RAND = function() { - return Math.random(); - }; + exports.PERCENTRANK = {}; - exports.RANDBETWEEN = function(bottom, top) { - bottom = utils.parseNumber(bottom); - top = utils.parseNumber(top); - if (utils.anyIsError(bottom, top)) { + exports.PERCENTRANK.EXC = function(array, x, significance) { + significance = (significance === undefined) ? 3 : significance; + array = utils.parseNumberArray(utils.flatten(array)); + x = utils.parseNumber(x); + significance = utils.parseNumber(significance); + if (utils.anyIsError(array, x, significance)) { return error.value; } - // Creative Commons Attribution 3.0 License - // Copyright (c) 2012 eqcode - return bottom + Math.ceil((top - bottom + 1) * Math.random()) - 1; + array = array.sort(function(a, b) { + return a - b; + }); + var uniques = misc.UNIQUE.apply(null, array); + var n = array.length; + var m = uniques.length; + var power = Math.pow(10, significance); + var result = 0; + var match = false; + var i = 0; + while (!match && i < m) { + if (x === uniques[i]) { + result = (array.indexOf(uniques[i]) + 1) / (n + 1); + match = true; + } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) { + result = (array.indexOf(uniques[i]) + 1 + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n + 1); + match = true; + } + i++; + } + return Math.floor(result * power) / power; }; - // TODO - exports.ROMAN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.PERCENTRANK.INC = function(array, x, significance) { + significance = (significance === undefined) ? 3 : significance; + array = utils.parseNumberArray(utils.flatten(array)); + x = utils.parseNumber(x); + significance = utils.parseNumber(significance); + if (utils.anyIsError(array, x, significance)) { + return error.value; } - // The MIT License - // Copyright (c) 2008 Steven Levithan - var digits = String(number).split(''); - var key = ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX']; - var roman = ''; - var i = 3; - while (i--) { - roman = (key[+digits.pop() + (i * 10)] || '') + roman; + array = array.sort(function(a, b) { + return a - b; + }); + var uniques = misc.UNIQUE.apply(null, array); + var n = array.length; + var m = uniques.length; + var power = Math.pow(10, significance); + var result = 0; + var match = false; + var i = 0; + while (!match && i < m) { + if (x === uniques[i]) { + result = array.indexOf(uniques[i]) / (n - 1); + match = true; + } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) { + result = (array.indexOf(uniques[i]) + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n - 1); + match = true; + } + i++; } - return new Array(+digits.join('') + 1).join('M') + roman; + return Math.floor(result * power) / power; }; - exports.ROUND = function(number, digits) { + exports.PERMUT = function(number, number_chosen) { number = utils.parseNumber(number); - digits = utils.parseNumber(digits); - if (utils.anyIsError(number, digits)) { + number_chosen = utils.parseNumber(number_chosen); + if (utils.anyIsError(number, number_chosen)) { return error.value; } - return Math.round(number * Math.pow(10, digits)) / Math.pow(10, digits); + return mathTrig.FACT(number) / mathTrig.FACT(number - number_chosen); }; - exports.ROUNDDOWN = function(number, digits) { + exports.PERMUTATIONA = function(number, number_chosen) { number = utils.parseNumber(number); - digits = utils.parseNumber(digits); - if (utils.anyIsError(number, digits)) { + number_chosen = utils.parseNumber(number_chosen); + if (utils.anyIsError(number, number_chosen)) { return error.value; } - var sign = (number > 0) ? 1 : -1; - return sign * (Math.floor(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits); + return Math.pow(number, number_chosen); }; - exports.ROUNDUP = function(number, digits) { - number = utils.parseNumber(number); - digits = utils.parseNumber(digits); - if (utils.anyIsError(number, digits)) { + exports.PHI = function(x) { + x = utils.parseNumber(x); + if (x instanceof Error) { return error.value; } - var sign = (number > 0) ? 1 : -1; - return sign * (Math.ceil(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits); + return Math.exp(-0.5 * x * x) / SQRT2PI; }; - exports.SEC = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.POISSON = {}; + + exports.POISSON.DIST = function(x, mean, cumulative) { + x = utils.parseNumber(x); + mean = utils.parseNumber(mean); + if (utils.anyIsError(x, mean)) { + return error.value; } - return 1 / Math.cos(number); + return (cumulative) ? jStat.poisson.cdf(x, mean) : jStat.poisson.pdf(x, mean); }; - exports.SECH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.PROB = function(range, probability, lower, upper) { + if (lower === undefined) { + return 0; } - return 2 / (Math.exp(number) + Math.exp(-number)); - }; + upper = (upper === undefined) ? lower : upper; - exports.SERIESSUM = function(x, n, m, coefficients) { - x = utils.parseNumber(x); - n = utils.parseNumber(n); - m = utils.parseNumber(m); - coefficients = utils.parseNumberArray(coefficients); - if (utils.anyIsError(x, n, m, coefficients)) { + range = utils.parseNumberArray(utils.flatten(range)); + probability = utils.parseNumberArray(utils.flatten(probability)); + lower = utils.parseNumber(lower); + upper = utils.parseNumber(upper); + if (utils.anyIsError(range, probability, lower, upper)) { return error.value; } - var result = coefficients[0] * Math.pow(x, n); - for (var i = 1; i < coefficients.length; i++) { - result += coefficients[i] * Math.pow(x, n + i * m); + + if (lower === upper) { + return (range.indexOf(lower) >= 0) ? probability[range.indexOf(lower)] : 0; + } + + var sorted = range.sort(function(a, b) { + return a - b; + }); + var n = sorted.length; + var result = 0; + for (var i = 0; i < n; i++) { + if (sorted[i] >= lower && sorted[i] <= upper) { + result += probability[range.indexOf(sorted[i])]; + } } return result; }; - exports.SIGN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.QUARTILE = {}; + + exports.QUARTILE.EXC = function(range, quart) { + range = utils.parseNumberArray(utils.flatten(range)); + quart = utils.parseNumber(quart); + if (utils.anyIsError(range, quart)) { + return error.value; } - if (number < 0) { - return -1; - } else if (number === 0) { - return 0; - } else { - return 1; + switch (quart) { + case 1: + return exports.PERCENTILE.EXC(range, 0.25); + case 2: + return exports.PERCENTILE.EXC(range, 0.5); + case 3: + return exports.PERCENTILE.EXC(range, 0.75); + default: + return error.num; } }; - exports.SIN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.QUARTILE.INC = function(range, quart) { + range = utils.parseNumberArray(utils.flatten(range)); + quart = utils.parseNumber(quart); + if (utils.anyIsError(range, quart)) { + return error.value; + } + switch (quart) { + case 1: + return exports.PERCENTILE.INC(range, 0.25); + case 2: + return exports.PERCENTILE.INC(range, 0.5); + case 3: + return exports.PERCENTILE.INC(range, 0.75); + default: + return error.num; } - return Math.sin(number); }; - exports.SINH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - return (Math.exp(number) - Math.exp(-number)) / 2; - }; + exports.RANK = {}; - exports.SQRT = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; - } - if (number < 0) { - return error.num; - } - return Math.sqrt(number); + exports.RANK.AVG = function(number, range, order) { + number = utils.parseNumber(number); + range = utils.parseNumberArray(utils.flatten(range)); + if (utils.anyIsError(number, range)) { + return error.value; + } + range = utils.flatten(range); + order = order || false; + var sort = (order) ? function(a, b) { + return a - b; + } : function(a, b) { + return b - a; }; + range = range.sort(sort); - exports.SQRTPI = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + var length = range.length; + var count = 0; + for (var i = 0; i < length; i++) { + if (range[i] === number) { + count++; } - return Math.sqrt(number * Math.PI); - }; - - exports.SUBTOTAL = function(function_code, ref1) { - function_code = utils.parseNumber(function_code); - if (function_code instanceof Error) { - return function_code; } - switch (function_code) { - case 1: - return statistical.AVERAGE(ref1); - case 2: - return statistical.COUNT(ref1); - case 3: - return statistical.COUNTA(ref1); - case 4: - return statistical.MAX(ref1); - case 5: - return statistical.MIN(ref1); - case 6: - return exports.PRODUCT(ref1); - case 7: - return statistical.STDEV.S(ref1); - case 8: - return statistical.STDEV.P(ref1); - case 9: - return exports.SUM(ref1); - case 10: - return statistical.VAR.S(ref1); - case 11: - return statistical.VAR.P(ref1); - // no hidden values for us - case 101: - return statistical.AVERAGE(ref1); - case 102: - return statistical.COUNT(ref1); - case 103: - return statistical.COUNTA(ref1); - case 104: - return statistical.MAX(ref1); - case 105: - return statistical.MIN(ref1); - case 106: - return exports.PRODUCT(ref1); - case 107: - return statistical.STDEV.S(ref1); - case 108: - return statistical.STDEV.P(ref1); - case 109: - return exports.SUM(ref1); - case 110: - return statistical.VAR.S(ref1); - case 111: - return statistical.VAR.P(ref1); + return (count > 1) ? (2 * range.indexOf(number) + count + 1) / 2 : range.indexOf(number) + 1; + }; + + exports.RANK.EQ = function(number, range, order) { + number = utils.parseNumber(number); + range = utils.parseNumberArray(utils.flatten(range)); + if (utils.anyIsError(number, range)) { + return error.value; } + order = order || false; + var sort = (order) ? function(a, b) { + return a - b; + } : function(a, b) { + return b - a; + }; + range = range.sort(sort); + return range.indexOf(number) + 1; }; - exports.ADD = function (num1, num2) { + exports.ROW = function(matrix, index) { if (arguments.length !== 2) { return error.na; } - num1 = utils.parseNumber(num1); - num2 = utils.parseNumber(num2); - if (utils.anyIsError(num1, num2)) { + if (index < 0) { + return error.num; + } + + if (!(matrix instanceof Array) || (typeof index !== 'number')) { return error.value; } - return num1 + num2; + if (matrix.length === 0) { + return undefined; + } + + return jStat.row(matrix, index); }; - exports.MINUS = function (num1, num2) { - if (arguments.length !== 2) { + exports.ROWS = function(matrix) { + if (arguments.length !== 1) { return error.na; } - num1 = utils.parseNumber(num1); - num2 = utils.parseNumber(num2); - if (utils.anyIsError(num1, num2)) { + if (!(matrix instanceof Array)) { return error.value; } - return num1 - num2; + if (matrix.length === 0) { + return 0; + } + + return jStat.rows(matrix); }; - exports.DIVIDE = function (dividend, divisor) { - if (arguments.length !== 2) { - return error.na; + exports.RSQ = function(data_x, data_y) { // no need to flatten here, PEARSON will take care of that + data_x = utils.parseNumberArray(utils.flatten(data_x)); + data_y = utils.parseNumberArray(utils.flatten(data_y)); + if (utils.anyIsError(data_x, data_y)) { + return error.value; } + return Math.pow(exports.PEARSON(data_x, data_y), 2); + }; - dividend = utils.parseNumber(dividend); - divisor = utils.parseNumber(divisor); - if (utils.anyIsError(dividend, divisor)) { - return error.value; + exports.SKEW = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; } + var mean = jStat.mean(range); + var n = range.length; + var sigma = 0; + for (var i = 0; i < n; i++) { + sigma += Math.pow(range[i] - mean, 3); + } + return n * sigma / ((n - 1) * (n - 2) * Math.pow(jStat.stdev(range, true), 3)); + }; - if (divisor === 0) { - return error.div0; + exports.SKEW.P = function() { + var range = utils.parseNumberArray(utils.flatten(arguments)); + if (range instanceof Error) { + return range; + } + var mean = jStat.mean(range); + var n = range.length; + var m2 = 0; + var m3 = 0; + for (var i = 0; i < n; i++) { + m3 += Math.pow(range[i] - mean, 3); + m2 += Math.pow(range[i] - mean, 2); } + m3 = m3 / n; + m2 = m2 / n; + return m3 / Math.pow(m2, 3 / 2); + }; - return dividend / divisor; + exports.SLOPE = function(data_y, data_x) { + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + if (utils.anyIsError(data_y, data_x)) { + return error.value; + } + var xmean = jStat.mean(data_x); + var ymean = jStat.mean(data_y); + var n = data_x.length; + var num = 0; + var den = 0; + for (var i = 0; i < n; i++) { + num += (data_x[i] - xmean) * (data_y[i] - ymean); + den += Math.pow(data_x[i] - xmean, 2); + } + return num / den; }; - exports.MULTIPLY = function (factor1, factor2) { - if (arguments.length !== 2) { - return error.na; + exports.SMALL = function(range, k) { + range = utils.parseNumberArray(utils.flatten(range)); + k = utils.parseNumber(k); + if (utils.anyIsError(range, k)) { + return range; } + return range.sort(function(a, b) { + return a - b; + })[k - 1]; + }; - factor1 = utils.parseNumber(factor1); - factor2 = utils.parseNumber(factor2); - if (utils.anyIsError(factor1, factor2)) { + exports.STANDARDIZE = function(x, mean, sd) { + x = utils.parseNumber(x); + mean = utils.parseNumber(mean); + sd = utils.parseNumber(sd); + if (utils.anyIsError(x, mean, sd)) { return error.value; } + return (x - mean) / sd; + }; - return factor1 * factor2; + exports.STDEV = {}; + + exports.STDEV.P = function() { + var v = exports.VAR.P.apply(this, arguments); + return Math.sqrt(v); }; - exports.GTE = function (num1, num2) { - if (arguments.length !== 2) { - return error.na; - } + exports.STDEV.S = function() { + var v = exports.VAR.S.apply(this, arguments); + return Math.sqrt(v); + }; - num1 = utils.parseNumber(num1); - num2 = utils.parseNumber(num2); - if (utils.anyIsError(num1, num2)) { - return error.error; - } + exports.STDEVA = function() { + var v = exports.VARA.apply(this, arguments); + return Math.sqrt(v); + }; - return num1 >= num2; + exports.STDEVPA = function() { + var v = exports.VARPA.apply(this, arguments); + return Math.sqrt(v); }; - exports.LT = function (num1, num2) { - if (arguments.length !== 2) { + + exports.STEYX = function(data_y, data_x) { + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + if (utils.anyIsError(data_y, data_x)) { + return error.value; + } + var xmean = jStat.mean(data_x); + var ymean = jStat.mean(data_y); + var n = data_x.length; + var lft = 0; + var num = 0; + var den = 0; + for (var i = 0; i < n; i++) { + lft += Math.pow(data_y[i] - ymean, 2); + num += (data_x[i] - xmean) * (data_y[i] - ymean); + den += Math.pow(data_x[i] - xmean, 2); + } + return Math.sqrt((lft - num * num / den) / (n - 2)); + }; + + exports.TRANSPOSE = function(matrix) { + if (!matrix) { return error.na; } + return jStat.transpose(matrix); + }; - num1 = utils.parseNumber(num1); - num2 = utils.parseNumber(num2); - if (utils.anyIsError(num1, num2)) { - return error.error; + exports.T = text.T; + + exports.T.DIST = function(x, df, cumulative) { + x = utils.parseNumber(x); + df = utils.parseNumber(df); + if (utils.anyIsError(x, df)) { + return error.value; } - - return num1 < num2; + return (cumulative) ? jStat.studentt.cdf(x, df) : jStat.studentt.pdf(x, df); }; - - exports.LTE = function (num1, num2) { + exports.T.DIST['2T'] = function(x, df) { if (arguments.length !== 2) { return error.na; } - num1 = utils.parseNumber(num1); - num2 = utils.parseNumber(num2); - if (utils.anyIsError(num1, num2)) { - return error.error; + if (x < 0 || df < 1) { + return error.num; } - return num1 <= num2; - }; - - exports.EQ = function (value1, value2) { - if (arguments.length !== 2) { - return error.na; + if ((typeof x !== 'number') || (typeof df !== 'number')) { + return error.value; } - return value1 === value2; + return (1 - jStat.studentt.cdf(x , df)) * 2; }; - exports.NE = function (value1, value2) { + exports.T.DIST.RT = function(x, df) { if (arguments.length !== 2) { return error.na; } - return value1 !== value2; - }; - - exports.POW = function (base, exponent) { - if (arguments.length !== 2) { - return error.na; + if (x < 0 || df < 1) { + return error.num; } - base = utils.parseNumber(base); - exponent = utils.parseNumber(exponent); - if (utils.anyIsError(base, exponent)) { - return error.error; + if ((typeof x !== 'number') || (typeof df !== 'number')) { + return error.value; } - return exports.POWER(base, exponent); + return 1 - jStat.studentt.cdf(x , df); }; - exports.SUM = function() { - var result = 0; - var argsKeys = Object.keys(arguments); - for (var i = 0; i < argsKeys.length; ++i) { - var elt = arguments[argsKeys[i]]; - if (typeof elt === 'number') { - result += elt; - } else if (typeof elt === 'string') { - var parsed = parseFloat(elt); - !isNaN(parsed) && (result += parsed); - } else if (Array.isArray(elt)) { - result += exports.SUM.apply(null, elt); - } + exports.T.INV = function(probability, df) { + probability = utils.parseNumber(probability); + df = utils.parseNumber(df); + if (utils.anyIsError(probability, df)) { + return error.value; } - return result; + return jStat.studentt.inv(probability, df); }; - exports.SUMIF = function(range, criteria) { - range = utils.parseNumberArray(utils.flatten(range)); - if (range instanceof Error) { - return range; + exports.T.INV['2T'] = function(probability, df) { + probability = utils.parseNumber(probability); + df = utils.parseNumber(df); + if (probability <= 0 || probability > 1 || df < 1) { + return error.num; } - var result = 0; - for (var i = 0; i < range.length; i++) { - result += (eval(range[i] + criteria)) ? range[i] : 0; // jshint ignore:line + if (utils.anyIsError(probability, df)) { + return error.value; } - return result; + return Math.abs(jStat.studentt.inv(probability/2, df)); }; - exports.SUMIFS = function() { - var args = utils.argsToArray(arguments); - var range = utils.parseNumberArray(utils.flatten(args.shift())); - if (range instanceof Error) { - return range; + // The algorithm can be found here: + // http://www.chem.uoa.gr/applets/AppletTtest/Appl_Ttest2.html + exports.T.TEST = function(data_x, data_y) { + data_x = utils.parseNumberArray(utils.flatten(data_x)); + data_y = utils.parseNumberArray(utils.flatten(data_y)); + if (utils.anyIsError(data_x, data_y)) { + return error.value; } - var criteria = args; - var n_range_elements = range.length; - var n_criterias = criteria.length; + var mean_x = jStat.mean(data_x); + var mean_y = jStat.mean(data_y); + var s_x = 0; + var s_y = 0; + var i; - var result = 0; - for (var i = 0; i < n_range_elements; i++) { - var el = range[i]; - var condition = ''; - for (var c = 0; c < n_criterias; c++) { - condition += el + criteria[c]; - if (c !== n_criterias - 1) { - condition += '&&'; - } - } - if (eval(condition)) { // jshint ignore:line - result += el; - } + for (i = 0; i < data_x.length; i++) { + s_x += Math.pow(data_x[i] - mean_x, 2); } - return result; + for (i = 0; i < data_y.length; i++) { + s_y += Math.pow(data_y[i] - mean_y, 2); + } + + s_x = s_x / (data_x.length-1); + s_y = s_y / (data_y.length-1); + + var t = Math.abs(mean_x - mean_y) / Math.sqrt(s_x/data_x.length + s_y/data_y.length); + + return exports.T.DIST['2T'](t, data_x.length+data_y.length-2); }; - exports.SUMPRODUCT = function() { - if (!arguments || arguments.length === 0) { + exports.TREND = function(data_y, data_x, new_data_x) { + data_y = utils.parseNumberArray(utils.flatten(data_y)); + data_x = utils.parseNumberArray(utils.flatten(data_x)); + new_data_x = utils.parseNumberArray(utils.flatten(new_data_x)); + if (utils.anyIsError(data_y, data_x, new_data_x)) { return error.value; } - var arrays = arguments.length + 1; - var result = 0; - var product; - var k; - var _i; - var _ij; - for (var i = 0; i < arguments[0].length; i++) { - if (!(arguments[0][i] instanceof Array)) { - product = 1; - for (k = 1; k < arrays; k++) { - _i = utils.parseNumber(arguments[k - 1][i]); - if (_i instanceof Error) { - return _i; - } - product *= _i; - } - result += product; - } else { - for (var j = 0; j < arguments[0][i].length; j++) { - product = 1; - for (k = 1; k < arrays; k++) { - _ij = utils.parseNumber(arguments[k - 1][i][j]); - if (_ij instanceof Error) { - return _ij; - } - product *= _ij; - } - result += product; - } - } - } - return result; - }; + var linest = exports.LINEST(data_y, data_x); + var m = linest[0]; + var b = linest[1]; + var result = []; + + new_data_x.forEach(function(x) { + result.push(m * x + b); + }); - exports.SUMSQ = function() { - var numbers = utils.parseNumberArray(utils.flatten(arguments)); - if (numbers instanceof Error) { - return numbers; - } - var result = 0; - var length = numbers.length; - for (var i = 0; i < length; i++) { - result += (information.ISNUMBER(numbers[i])) ? numbers[i] * numbers[i] : 0; - } return result; }; - exports.SUMX2MY2 = function(array_x, array_y) { - array_x = utils.parseNumberArray(utils.flatten(array_x)); - array_y = utils.parseNumberArray(utils.flatten(array_y)); - if (utils.anyIsError(array_x, array_y)) { + exports.TRIMMEAN = function(range, percent) { + range = utils.parseNumberArray(utils.flatten(range)); + percent = utils.parseNumber(percent); + if (utils.anyIsError(range, percent)) { return error.value; } - var result = 0; - for (var i = 0; i < array_x.length; i++) { - result += array_x[i] * array_x[i] - array_y[i] * array_y[i]; - } - return result; + var trim = mathTrig.FLOOR(range.length * percent, 2) / 2; + return jStat.mean(utils.initial(utils.rest(range.sort(function(a, b) { + return a - b; + }), trim), trim)); }; - exports.SUMX2PY2 = function(array_x, array_y) { - array_x = utils.parseNumberArray(utils.flatten(array_x)); - array_y = utils.parseNumberArray(utils.flatten(array_y)); - if (utils.anyIsError(array_x, array_y)) { - return error.value; - } - var result = 0; - array_x = utils.parseNumberArray(utils.flatten(array_x)); - array_y = utils.parseNumberArray(utils.flatten(array_y)); - for (var i = 0; i < array_x.length; i++) { - result += array_x[i] * array_x[i] + array_y[i] * array_y[i]; + exports.VAR = {}; + + exports.VAR.P = function() { + var range = utils.numbers(utils.flatten(arguments)); + var n = range.length; + var sigma = 0; + var mean = exports.AVERAGE(range); + for (var i = 0; i < n; i++) { + sigma += Math.pow(range[i] - mean, 2); } - return result; + return sigma / n; }; - exports.SUMXMY2 = function(array_x, array_y) { - array_x = utils.parseNumberArray(utils.flatten(array_x)); - array_y = utils.parseNumberArray(utils.flatten(array_y)); - if (utils.anyIsError(array_x, array_y)) { - return error.value; + exports.VAR.S = function() { + var range = utils.numbers(utils.flatten(arguments)); + var n = range.length; + var sigma = 0; + var mean = exports.AVERAGE(range); + for (var i = 0; i < n; i++) { + sigma += Math.pow(range[i] - mean, 2); } - var result = 0; - array_x = utils.flatten(array_x); - array_y = utils.flatten(array_y); - for (var i = 0; i < array_x.length; i++) { - result += Math.pow(array_x[i] - array_y[i], 2); + return sigma / (n - 1); + }; + + exports.VARA = function() { + var range = utils.flatten(arguments); + var n = range.length; + var sigma = 0; + var count = 0; + var mean = exports.AVERAGEA(range); + for (var i = 0; i < n; i++) { + var el = range[i]; + if (typeof el === 'number') { + sigma += Math.pow(el - mean, 2); + } else if (el === true) { + sigma += Math.pow(1 - mean, 2); + } else { + sigma += Math.pow(0 - mean, 2); + } + + if (el !== null) { + count++; + } } - return result; + return sigma / (count - 1); }; - exports.TAN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.VARPA = function() { + var range = utils.flatten(arguments); + var n = range.length; + var sigma = 0; + var count = 0; + var mean = exports.AVERAGEA(range); + for (var i = 0; i < n; i++) { + var el = range[i]; + if (typeof el === 'number') { + sigma += Math.pow(el - mean, 2); + } else if (el === true) { + sigma += Math.pow(1 - mean, 2); + } else { + sigma += Math.pow(0 - mean, 2); + } + + if (el !== null) { + count++; + } } - return Math.tan(number); + return sigma / count; }; - exports.TANH = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.WEIBULL = {}; + + exports.WEIBULL.DIST = function(x, alpha, beta, cumulative) { + x = utils.parseNumber(x); + alpha = utils.parseNumber(alpha); + beta = utils.parseNumber(beta); + if (utils.anyIsError(x, alpha, beta)) { + return error.value; } - var e2 = Math.exp(2 * number); - return (e2 - 1) / (e2 + 1); + return (cumulative) ? 1 - Math.exp(-Math.pow(x / beta, alpha)) : Math.pow(x, alpha - 1) * Math.exp(-Math.pow(x / beta, alpha)) * alpha / Math.pow(beta, alpha); }; - exports.TRUNC = function(number, digits) { - digits = (digits === undefined) ? 0 : digits; - number = utils.parseNumber(number); - digits = utils.parseNumber(digits); - if (utils.anyIsError(number, digits)) { + exports.Z = {}; + + exports.Z.TEST = function(range, x, sd) { + range = utils.parseNumberArray(utils.flatten(range)); + x = utils.parseNumber(x); + if (utils.anyIsError(range, x)) { return error.value; } - var sign = (number > 0) ? 1 : -1; - return sign * (Math.floor(Math.abs(number) * Math.pow(10, digits))) / Math.pow(10, digits); + + sd = sd || exports.STDEV.S(range); + var n = range.length; + return 1 - exports.NORM.S.DIST((exports.AVERAGE(range) - x) / (sd / Math.sqrt(n)), true); }; -/***/ }, -/* 6 */ -/***/ function(module, exports, __webpack_require__) { +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { - var utils = __webpack_require__(17); - var error = __webpack_require__(16); - var numeral = __webpack_require__(15); + var utils = __webpack_require__(4); + var error = __webpack_require__(5); + var numeral = __webpack_require__(8); //TODO exports.ASC = function() { @@ -3558,4153 +3532,4169 @@ return /******/ (function(modules) { // webpackBootstrap return text.replace(new RegExp(old_text, 'g'), new_text); } else { var index = 0; - var i = 0; - while (text.indexOf(old_text, index) > 0) { - index = text.indexOf(old_text, index + 1); - i++; - if (i === occurrence) { - return text.substring(0, index) + new_text + text.substring(index + old_text.length); - } - } - } - }; - - exports.T = function(value) { - return (typeof value === "string") ? value : ''; - }; - - // TODO incomplete implementation - exports.TEXT = function(value, format) { - value = utils.parseNumber(value); - if (utils.anyIsError(value)) { - return error.na; - } - - return numeral(value).format(format); - }; - - exports.TRIM = function(text) { - if (typeof text !== 'string') { - return error.value; - } - return text.replace(/ +/g, ' ').trim(); - }; - - exports.UNICHAR = this.CHAR; - - exports.UNICODE = this.CODE; - - exports.UPPER = function(text) { - if (typeof text !== 'string') { - return error.value; - } - return text.toUpperCase(); - }; - - exports.VALUE = function(text) { - if (typeof text !== 'string') { - return error.value; - } - return numeral().unformat(text); - }; - - -/***/ }, -/* 7 */ -/***/ function(module, exports, __webpack_require__) { - - var error = __webpack_require__(16); - var utils = __webpack_require__(17); - - var d1900 = new Date(1900, 0, 1); - var WEEK_STARTS = [ - undefined, - 0, - 1, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - 1, - 2, - 3, - 4, - 5, - 6, - 0 - ]; - var WEEK_TYPES = [ - [], - [1, 2, 3, 4, 5, 6, 7], - [7, 1, 2, 3, 4, 5, 6], - [6, 0, 1, 2, 3, 4, 5], - [], - [], - [], - [], - [], - [], - [], - [7, 1, 2, 3, 4, 5, 6], - [6, 7, 1, 2, 3, 4, 5], - [5, 6, 7, 1, 2, 3, 4], - [4, 5, 6, 7, 1, 2, 3], - [3, 4, 5, 6, 7, 1, 2], - [2, 3, 4, 5, 6, 7, 1], - [1, 2, 3, 4, 5, 6, 7] - ]; - var WEEKEND_TYPES = [ - [], - [6, 0], - [0, 1], - [1, 2], - [2, 3], - [3, 4], - [4, 5], - [5, 6], - undefined, - undefined, - undefined, [0, 0], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6] - ]; - - exports.DATE = function(year, month, day) { - year = utils.parseNumber(year); - month = utils.parseNumber(month); - day = utils.parseNumber(day); - if (utils.anyIsError(year, month, day)) { - return error.value; - } - if (year < 0 || month < 0 || day < 0) { - return error.num; - } - var date = new Date(year, month - 1, day); - return date; - }; - - exports.DATEVALUE = function(date_text) { - if (typeof date_text !== 'string') { - return error.value; - } - var date = Date.parse(date_text); - if (isNaN(date)) { - return error.value; - } - if (date <= -2203891200000) { - return (date - d1900) / 86400000 + 1; - } - return (date - d1900) / 86400000 + 2; - }; - - exports.DAY = function(serial_number) { - var date = utils.parseDate(serial_number); - if (date instanceof Error) { - return date; - } - return date.getDate(); - }; - - exports.DAYS = function(end_date, start_date) { - end_date = utils.parseDate(end_date); - start_date = utils.parseDate(start_date); - if (end_date instanceof Error) { - return end_date; - } - if (start_date instanceof Error) { - return start_date; - } - return serial(end_date) - serial(start_date); - }; - - exports.DAYS360 = function(start_date, end_date, method) { - method = utils.parseBool(method); - start_date = utils.parseDate(start_date); - end_date = utils.parseDate(end_date); - if (start_date instanceof Error) { - return start_date; - } - if (end_date instanceof Error) { - return end_date; - } - if (method instanceof Error) { - return method; - } - var sm = start_date.getMonth(); - var em = end_date.getMonth(); - var sd, ed; - if (method) { - sd = start_date.getDate() === 31 ? 30 : start_date.getDate(); - ed = end_date.getDate() === 31 ? 30 : end_date.getDate(); - } else { - var smd = new Date(start_date.getFullYear(), sm + 1, 0).getDate(); - var emd = new Date(end_date.getFullYear(), em + 1, 0).getDate(); - sd = start_date.getDate() === smd ? 30 : start_date.getDate(); - if (end_date.getDate() === emd) { - if (sd < 30) { - em++; - ed = 1; - } else { - ed = 30; + var i = 0; + while (text.indexOf(old_text, index) > 0) { + index = text.indexOf(old_text, index + 1); + i++; + if (i === occurrence) { + return text.substring(0, index) + new_text + text.substring(index + old_text.length); } - } else { - ed = end_date.getDate(); } } - return 360 * (end_date.getFullYear() - start_date.getFullYear()) + - 30 * (em - sm) + (ed - sd); }; - exports.EDATE = function(start_date, months) { - start_date = utils.parseDate(start_date); - if (start_date instanceof Error) { - return start_date; + exports.T = function(value) { + return (typeof value === "string") ? value : ''; + }; + + // TODO incomplete implementation + exports.TEXT = function(value, format) { + value = utils.parseNumber(value); + if (utils.anyIsError(value)) { + return error.na; } - if (isNaN(months)) { + + return numeral(value).format(format); + }; + + exports.TRIM = function(text) { + if (typeof text !== 'string') { return error.value; } - months = parseInt(months, 10); - start_date.setMonth(start_date.getMonth() + months); - return serial(start_date); + return text.replace(/ +/g, ' ').trim(); }; - exports.EOMONTH = function(start_date, months) { - start_date = utils.parseDate(start_date); - if (start_date instanceof Error) { - return start_date; - } - if (isNaN(months)) { + exports.UNICHAR = this.CHAR; + + exports.UNICODE = this.CODE; + + exports.UPPER = function(text) { + if (typeof text !== 'string') { return error.value; } - months = parseInt(months, 10); - return serial(new Date(start_date.getFullYear(), start_date.getMonth() + months + 1, 0)); + return text.toUpperCase(); }; - exports.HOUR = function(serial_number) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; + exports.VALUE = function(text) { + if (typeof text !== 'string') { + return error.value; } - return serial_number.getHours(); + return numeral().unformat(text); }; - exports.INTERVAL = function (second) { - if (typeof second !== 'number' && typeof second !== 'string') { - return error.value; - } else { - second = parseInt(second, 10); + +/***/ }), +/* 8 */ +/***/ (function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_8__; + +/***/ }), +/* 9 */ +/***/ (function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_9__; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + + var utils = __webpack_require__(4); + var numeral = __webpack_require__(8); + + exports.UNIQUE = function () { + var result = []; + for (var i = 0; i < arguments.length; ++i) { + var hasElement = false; + var element = arguments[i]; + + // Check if we've already seen this element. + for (var j = 0; j < result.length; ++j) { + hasElement = result[j] === element; + if (hasElement) { break; } + } + + // If we did not find it, add it to the result. + if (!hasElement) { + result.push(element); + } } + return result; + }; - var year = Math.floor(second/946080000); - second = second%946080000; - var month = Math.floor(second/2592000); - second = second%2592000; - var day = Math.floor(second/86400); - second = second%86400; + exports.FLATTEN = utils.flatten; - var hour = Math.floor(second/3600); - second = second%3600; - var min = Math.floor(second/60); - second = second%60; - var sec = second; + exports.ARGS2ARRAY = function () { + return Array.prototype.slice.call(arguments, 0); + }; - year = (year > 0) ? year + 'Y' : ''; - month = (month > 0) ? month + 'M' : ''; - day = (day > 0) ? day + 'D' : ''; - hour = (hour > 0) ? hour + 'H' : ''; - min = (min > 0) ? min + 'M' : ''; - sec = (sec > 0) ? sec + 'S' : ''; + exports.REFERENCE = function (context, reference) { + try { + var path = reference.split('.'); + var result = context; + for (var i = 0; i < path.length; ++i) { + var step = path[i]; + if (step[step.length - 1] === ']') { + var opening = step.indexOf('['); + var index = step.substring(opening + 1, step.length - 1); + result = result[step.substring(0, opening)][index]; + } else { + result = result[step]; + } + } + return result; + } catch (error) {} + }; - return 'P' + year + month + day + - 'T' + hour + min + sec; + exports.JOIN = function (array, separator) { + return array.join(separator); }; - exports.ISOWEEKNUM = function(date) { - date = utils.parseDate(date); - if (date instanceof Error) { - return date; - } + exports.NUMBERS = function () { + var possibleNumbers = utils.flatten(arguments); + return possibleNumbers.filter(function (el) { + return typeof el === 'number'; + }); + }; - date.setHours(0, 0, 0); - date.setDate(date.getDate() + 4 - (date.getDay() || 7)); - var yearStart = new Date(date.getFullYear(), 0, 1); - return Math.ceil((((date - yearStart) / 86400000) + 1) / 7); + exports.NUMERAL = function (number, format) { + return numeral(number).format(format); }; - exports.MINUTE = function(serial_number) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; - } - return serial_number.getMinutes(); +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + + var error = __webpack_require__(5); + + // TODO + exports.CELL = function() { + throw new Error('CELL is not implemented'); }; - exports.MONTH = function(serial_number) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; + exports.ERROR = {}; + exports.ERROR.TYPE = function(error_val) { + switch (error_val) { + case error.nil: return 1; + case error.div0: return 2; + case error.value: return 3; + case error.ref: return 4; + case error.name: return 5; + case error.num: return 6; + case error.na: return 7; + case error.data: return 8; } - return serial_number.getMonth() + 1; + return error.na; }; - exports.NETWORKDAYS = function(start_date, end_date, holidays) { - return this.NETWORKDAYS.INTL(start_date, end_date, 1, holidays); + // TODO + exports.INFO = function() { + throw new Error('INFO is not implemented'); }; - exports.NETWORKDAYS.INTL = function(start_date, end_date, weekend, holidays) { - start_date = utils.parseDate(start_date); - if (start_date instanceof Error) { - return start_date; - } - end_date = utils.parseDate(end_date); - if (end_date instanceof Error) { - return end_date; - } - if (weekend === undefined) { - weekend = WEEKEND_TYPES[1]; - } else { - weekend = WEEKEND_TYPES[weekend]; - } - if (!(weekend instanceof Array)) { - return error.value; - } - if (holidays === undefined) { - holidays = []; - } else if (!(holidays instanceof Array)) { - holidays = [holidays]; - } - for (var i = 0; i < holidays.length; i++) { - var h = utils.parseDate(holidays[i]); - if (h instanceof Error) { - return h; - } - holidays[i] = h; - } - var days = (end_date - start_date) / (1000 * 60 * 60 * 24) + 1; - var total = days; - var day = start_date; - for (i = 0; i < days; i++) { - var d = (new Date().getTimezoneOffset() > 0) ? day.getUTCDay() : day.getDay(); - var dec = false; - if (d === weekend[0] || d === weekend[1]) { - dec = true; - } - for (var j = 0; j < holidays.length; j++) { - var holiday = holidays[j]; - if (holiday.getDate() === day.getDate() && - holiday.getMonth() === day.getMonth() && - holiday.getFullYear() === day.getFullYear()) { - dec = true; - break; - } - } - if (dec) { - total--; - } - day.setDate(day.getDate() + 1); - } - return total; + exports.ISBLANK = function(value) { + return value === null; + }; + + exports.ISBINARY = function (number) { + return (/^[01]{1,10}$/).test(number); + }; + + exports.ISERR = function(value) { + return ([error.value, error.ref, error.div0, error.num, error.name, error.nil]).indexOf(value) >= 0 || + (typeof value === 'number' && (isNaN(value) || !isFinite(value))); + }; + + exports.ISERROR = function(value) { + return exports.ISERR(value) || value === error.na; + }; + + exports.ISEVEN = function(number) { + return (Math.floor(Math.abs(number)) & 1) ? false : true; }; - exports.NOW = function() { - return new Date(); + // TODO + exports.ISFORMULA = function() { + throw new Error('ISFORMULA is not implemented'); }; - exports.SECOND = function(serial_number) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; - } - return serial_number.getSeconds(); + exports.ISLOGICAL = function(value) { + return value === true || value === false; }; - exports.TIME = function(hour, minute, second) { - hour = utils.parseNumber(hour); - minute = utils.parseNumber(minute); - second = utils.parseNumber(second); - if (utils.anyIsError(hour, minute, second)) { - return error.value; - } - if (hour < 0 || minute < 0 || second < 0) { - return error.num; - } - return (3600 * hour + 60 * minute + second) / 86400; + exports.ISNA = function(value) { + return value === error.na; }; - exports.TIMEVALUE = function(time_text) { - time_text = utils.parseDate(time_text); - if (time_text instanceof Error) { - return time_text; - } - return (3600 * time_text.getHours() + - 60 * time_text.getMinutes() + - time_text.getSeconds()) / 86400; + exports.ISNONTEXT = function(value) { + return typeof(value) !== 'string'; }; - exports.TODAY = function() { - return new Date(); + exports.ISNUMBER = function(value) { + return typeof(value) === 'number' && !isNaN(value) && isFinite(value); }; - exports.WEEKDAY = function(serial_number, return_type) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; - } - if (return_type === undefined) { - return_type = 1; - } - var day = serial_number.getDay(); - return WEEK_TYPES[return_type][day]; + exports.ISODD = function(number) { + return (Math.floor(Math.abs(number)) & 1) ? true : false; }; - exports.WEEKNUM = function(serial_number, return_type) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; - } - if (return_type === undefined) { - return_type = 1; - } - if (return_type === 21) { - return this.ISOWEEKNUM(serial_number); - } - var week_start = WEEK_STARTS[return_type]; - var jan = new Date(serial_number.getFullYear(), 0, 1); - var inc = jan.getDay() < week_start ? 1 : 0; - jan -= Math.abs(jan.getDay() - week_start) * 24 * 60 * 60 * 1000; - return Math.floor(((serial_number - jan) / (1000 * 60 * 60 * 24)) / 7 + 1) + inc; + // TODO + exports.ISREF = function() { + throw new Error('ISREF is not implemented'); }; - exports.WORKDAY = function(start_date, days, holidays) { - return this.WORKDAY.INTL(start_date, days, 1, holidays); + exports.ISTEXT = function(value) { + return typeof(value) === 'string'; }; - exports.WORKDAY.INTL = function(start_date, days, weekend, holidays) { - start_date = utils.parseDate(start_date); - if (start_date instanceof Error) { - return start_date; + exports.N = function(value) { + if (this.ISNUMBER(value)) { + return value; } - days = utils.parseNumber(days); - if (days instanceof Error) { - return days; + if (value instanceof Date) { + return value.getTime(); } - if (days < 0) { - return error.num; + if (value === true) { + return 1; } - if (weekend === undefined) { - weekend = WEEKEND_TYPES[1]; - } else { - weekend = WEEKEND_TYPES[weekend]; + if (value === false) { + return 0; } - if (!(weekend instanceof Array)) { - return error.value; + if (this.ISERROR(value)) { + return value; } - if (holidays === undefined) { - holidays = []; - } else if (!(holidays instanceof Array)) { - holidays = [holidays]; + return 0; + }; + + exports.NA = function() { + return error.na; + }; + + + // TODO + exports.SHEET = function() { + throw new Error('SHEET is not implemented'); + }; + + // TODO + exports.SHEETS = function() { + throw new Error('SHEETS is not implemented'); + }; + + exports.TYPE = function(value) { + if (this.ISNUMBER(value)) { + return 1; } - for (var i = 0; i < holidays.length; i++) { - var h = utils.parseDate(holidays[i]); - if (h instanceof Error) { - return h; - } - holidays[i] = h; + if (this.ISTEXT(value)) { + return 2; } - var d = 0; - while (d < days) { - start_date.setDate(start_date.getDate() + 1); - var day = start_date.getDay(); - if (day === weekend[0] || day === weekend[1]) { - continue; - } - for (var j = 0; j < holidays.length; j++) { - var holiday = holidays[j]; - if (holiday.getDate() === start_date.getDate() && - holiday.getMonth() === start_date.getMonth() && - holiday.getFullYear() === start_date.getFullYear()) { - d--; - break; - } - } - d++; + if (this.ISLOGICAL(value)) { + return 4; } - return start_date; - }; - - exports.YEAR = function(serial_number) { - serial_number = utils.parseDate(serial_number); - if (serial_number instanceof Error) { - return serial_number; + if (this.ISERROR(value)) { + return 16; + } + if (Array.isArray(value)) { + return 64; } - return serial_number.getFullYear(); }; - function isLeapYear(year) { - return new Date(year, 1, 29).getMonth() === 1; - } - // TODO : Use DAYS ? - function daysBetween(start_date, end_date) { - return Math.ceil((end_date - start_date) / 1000 / 60 / 60 / 24); +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + + var error = __webpack_require__(5); + var jStat = __webpack_require__(9).jStat; + var text = __webpack_require__(7); + var utils = __webpack_require__(4); + var bessel = __webpack_require__(13); + + function isValidBinaryNumber(number) { + return (/^[01]{1,10}$/).test(number); } - exports.YEARFRAC = function(start_date, end_date, basis) { - start_date = utils.parseDate(start_date); - if (start_date instanceof Error) { - return start_date; - } - end_date = utils.parseDate(end_date); - if (end_date instanceof Error) { - return end_date; + exports.BESSELI = function(x, n) { + x = utils.parseNumber(x); + n = utils.parseNumber(n); + if (utils.anyIsError(x, n)) { + return error.value; } + return bessel.besseli(x, n); + }; - basis = basis || 0; - var sd = start_date.getDate(); - var sm = start_date.getMonth() + 1; - var sy = start_date.getFullYear(); - var ed = end_date.getDate(); - var em = end_date.getMonth() + 1; - var ey = end_date.getFullYear(); + exports.BESSELJ = function(x, n) { + x = utils.parseNumber(x); + n = utils.parseNumber(n); + if (utils.anyIsError(x, n)) { + return error.value; + } + return bessel.besselj(x, n); + }; - switch (basis) { - case 0: - // US (NASD) 30/360 - if (sd === 31 && ed === 31) { - sd = 30; - ed = 30; - } else if (sd === 31) { - sd = 30; - } else if (sd === 30 && ed === 31) { - ed = 30; - } - return ((ed + em * 30 + ey * 360) - (sd + sm * 30 + sy * 360)) / 360; - case 1: - // Actual/actual - var feb29Between = function(date1, date2) { - var year1 = date1.getFullYear(); - var mar1year1 = new Date(year1, 2, 1); - if (isLeapYear(year1) && date1 < mar1year1 && date2 >= mar1year1) { - return true; - } - var year2 = date2.getFullYear(); - var mar1year2 = new Date(year2, 2, 1); - return (isLeapYear(year2) && date2 >= mar1year2 && date1 < mar1year2); - }; - var ylength = 365; - if (sy === ey || ((sy + 1) === ey) && ((sm > em) || ((sm === em) && (sd >= ed)))) { - if ((sy === ey && isLeapYear(sy)) || - feb29Between(start_date, end_date) || - (em === 1 && ed === 29)) { - ylength = 366; - } - return daysBetween(start_date, end_date) / ylength; - } - var years = (ey - sy) + 1; - var days = (new Date(ey + 1, 0, 1) - new Date(sy, 0, 1)) / 1000 / 60 / 60 / 24; - var average = days / years; - return daysBetween(start_date, end_date) / average; - case 2: - // Actual/360 - return daysBetween(start_date, end_date) / 360; - case 3: - // Actual/365 - return daysBetween(start_date, end_date) / 365; - case 4: - // European 30/360 - return ((ed + em * 30 + ey * 360) - (sd + sm * 30 + sy * 360)) / 360; + exports.BESSELK = function(x, n) { + x = utils.parseNumber(x); + n = utils.parseNumber(n); + if (utils.anyIsError(x, n)) { + return error.value; } + return bessel.besselk(x, n); }; - function serial(date) { - var addOn = (date > -2203891200000)?2:1; - return (date - d1900) / 86400000 + addOn; - } + exports.BESSELY = function(x, n) { + x = utils.parseNumber(x); + n = utils.parseNumber(n); + if (utils.anyIsError(x, n)) { + return error.value; + } + return bessel.bessely(x, n); + }; -/***/ }, -/* 8 */ -/***/ function(module, exports, __webpack_require__) { + exports.BIN2DEC = function(number) { + // Return error if number is not binary or contains more than 10 characters (10 digits) + if (!isValidBinaryNumber(number)) { + return error.num; + } - var error = __webpack_require__(16); - var dateTime = __webpack_require__(7); - var utils = __webpack_require__(17); + // Convert binary number to decimal + var result = parseInt(number, 2); - function validDate(d) { - return d && d.getTime && !isNaN(d.getTime()); - } + // Handle negative numbers + var stringified = number.toString(); + if (stringified.length === 10 && stringified.substring(0, 1) === '1') { + return parseInt(stringified.substring(1), 2) - 512; + } else { + return result; + } + }; - function ensureDate(d) { - return (d instanceof Date)?d:new Date(d); - } - exports.ACCRINT = function(issue, first, settlement, rate, par, frequency, basis) { - // Return error if either date is invalid - issue = ensureDate(issue); - first = ensureDate(first); - settlement = ensureDate(settlement); - if (!validDate(issue) || !validDate(first) || !validDate(settlement)) { - return '#VALUE!'; + exports.BIN2HEX = function(number, places) { + // Return error if number is not binary or contains more than 10 characters (10 digits) + if (!isValidBinaryNumber(number)) { + return error.num; } - // Return error if either rate or par are lower than or equal to zero - if (rate <= 0 || par <= 0) { - return '#NUM!'; + // Ignore places and return a 10-character hexadecimal number if number is negative + var stringified = number.toString(); + if (stringified.length === 10 && stringified.substring(0, 1) === '1') { + return (1099511627264 + parseInt(stringified.substring(1), 2)).toString(16); } - // Return error if frequency is neither 1, 2, or 4 - if ([1, 2, 4].indexOf(frequency) === -1) { - return '#NUM!'; + // Convert binary number to hexadecimal + var result = parseInt(number, 2).toString(16); + + // Return hexadecimal number using the minimum number of characters necessary if places is undefined + if (places === undefined) { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } + + // Return error if places is negative + if (places < 0) { + return error.num; + } + + // Truncate places in case it is not an integer + places = Math.floor(places); + + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; } + }; - // Return error if basis is neither 0, 1, 2, 3, or 4 - if ([0, 1, 2, 3, 4].indexOf(basis) === -1) { - return '#NUM!'; + exports.BIN2OCT = function(number, places) { + // Return error if number is not binary or contains more than 10 characters (10 digits) + if (!isValidBinaryNumber(number)) { + return error.num; } - // Return error if settlement is before or equal to issue - if (settlement <= issue) { - return '#NUM!'; + // Ignore places and return a 10-character octal number if number is negative + var stringified = number.toString(); + if (stringified.length === 10 && stringified.substring(0, 1) === '1') { + return (1073741312 + parseInt(stringified.substring(1), 2)).toString(8); } - // Set default values - par = par || 0; - basis = basis || 0; + // Convert binary number to octal + var result = parseInt(number, 2).toString(8); - // Compute accrued interest - return par * rate * dateTime.YEARFRAC(issue, settlement, basis); - }; + // Return octal number using the minimum number of characters necessary if places is undefined + if (places === undefined) { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } - // TODO - exports.ACCRINTM = function() { - throw new Error('ACCRINTM is not implemented'); - }; + // Return error if places is negative + if (places < 0) { + return error.num; + } - // TODO - exports.AMORDEGRC = function() { - throw new Error('AMORDEGRC is not implemented'); - }; + // Truncate places in case it is not an integer + places = Math.floor(places); - // TODO - exports.AMORLINC = function() { - throw new Error('AMORLINC is not implemented'); + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + } }; - // TODO - exports.COUPDAYBS = function() { - throw new Error('COUPDAYBS is not implemented'); - }; + exports.BITAND = function(number1, number2) { + // Return error if either number is a non-numeric value + number1 = utils.parseNumber(number1); + number2 = utils.parseNumber(number2); + if (utils.anyIsError(number1, number2)) { + return error.value; + } - // TODO - exports.COUPDAYS = function() { - throw new Error('COUPDAYS is not implemented'); - }; + // Return error if either number is less than 0 + if (number1 < 0 || number2 < 0) { + return error.num; + } - // TODO - exports.COUPDAYSNC = function() { - throw new Error('COUPDAYSNC is not implemented'); - }; + // Return error if either number is a non-integer + if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) { + return error.num; + } - // TODO - exports.COUPNCD = function() { - throw new Error('COUPNCD is not implemented'); - }; + // Return error if either number is greater than (2^48)-1 + if (number1 > 281474976710655 || number2 > 281474976710655) { + return error.num; + } - // TODO - exports.COUPNUM = function() { - throw new Error('COUPNUM is not implemented'); + // Return bitwise AND of two numbers + return number1 & number2; }; - // TODO - exports.COUPPCD = function() { - throw new Error('COUPPCD is not implemented'); - }; + exports.BITLSHIFT = function(number, shift) { + number = utils.parseNumber(number); + shift = utils.parseNumber(shift); + if (utils.anyIsError(number, shift)) { + return error.value; + } - exports.CUMIPMT = function(rate, periods, value, start, end, type) { - // Credits: algorithm inspired by Apache OpenOffice - // Credits: Hannes Stiebitzhofer for the translations of function and variable names - // Requires exports.FV() and exports.PMT() from exports.js [http://stoic.com/exports/] + // Return error if number is less than 0 + if (number < 0) { + return error.num; + } - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - value = utils.parseNumber(value); - if (utils.anyIsError(rate, periods, value)) { + // Return error if number is a non-integer + if (Math.floor(number) !== number) { + return error.num; + } + + // Return error if number is greater than (2^48)-1 + if (number > 281474976710655) { + return error.num; + } + + // Return error if the absolute value of shift is greater than 53 + if (Math.abs(shift) > 53) { + return error.num; + } + + // Return number shifted by shift bits to the left or to the right if shift is negative + return (shift >= 0) ? number << shift : number >> -shift; + }; + + exports.BITOR = function(number1, number2) { + number1 = utils.parseNumber(number1); + number2 = utils.parseNumber(number2); + if (utils.anyIsError(number1, number2)) { return error.value; } - // Return error if either rate, periods, or value are lower than or equal to zero - if (rate <= 0 || periods <= 0 || value <= 0) { + // Return error if either number is less than 0 + if (number1 < 0 || number2 < 0) { return error.num; } - // Return error if start < 1, end < 1, or start > end - if (start < 1 || end < 1 || start > end) { + // Return error if either number is a non-integer + if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) { return error.num; } - // Return error if type is neither 0 nor 1 - if (type !== 0 && type !== 1) { + // Return error if either number is greater than (2^48)-1 + if (number1 > 281474976710655 || number2 > 281474976710655) { return error.num; } - // Compute cumulative interest - var payment = exports.PMT(rate, periods, value, 0, type); - var interest = 0; + // Return bitwise OR of two numbers + return number1 | number2; + }; - if (start === 1) { - if (type === 0) { - interest = -value; - start++; - } + exports.BITRSHIFT = function(number, shift) { + number = utils.parseNumber(number); + shift = utils.parseNumber(shift); + if (utils.anyIsError(number, shift)) { + return error.value; + } + + // Return error if number is less than 0 + if (number < 0) { + return error.num; + } + + // Return error if number is a non-integer + if (Math.floor(number) !== number) { + return error.num; + } + + // Return error if number is greater than (2^48)-1 + if (number > 281474976710655) { + return error.num; } - for (var i = start; i <= end; i++) { - if (type === 1) { - interest += exports.FV(rate, i - 2, payment, value, 1) - payment; - } else { - interest += exports.FV(rate, i - 1, payment, value, 0); - } + // Return error if the absolute value of shift is greater than 53 + if (Math.abs(shift) > 53) { + return error.num; } - interest *= rate; - // Return cumulative interest - return interest; + // Return number shifted by shift bits to the right or to the left if shift is negative + return (shift >= 0) ? number >> shift : number << -shift; }; - exports.CUMPRINC = function(rate, periods, value, start, end, type) { - // Credits: algorithm inspired by Apache OpenOffice - // Credits: Hannes Stiebitzhofer for the translations of function and variable names - - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - value = utils.parseNumber(value); - if (utils.anyIsError(rate, periods, value)) { + exports.BITXOR = function(number1, number2) { + number1 = utils.parseNumber(number1); + number2 = utils.parseNumber(number2); + if (utils.anyIsError(number1, number2)) { return error.value; } - // Return error if either rate, periods, or value are lower than or equal to zero - if (rate <= 0 || periods <= 0 || value <= 0) { + // Return error if either number is less than 0 + if (number1 < 0 || number2 < 0) { return error.num; } - // Return error if start < 1, end < 1, or start > end - if (start < 1 || end < 1 || start > end) { + // Return error if either number is a non-integer + if (Math.floor(number1) !== number1 || Math.floor(number2) !== number2) { return error.num; } - // Return error if type is neither 0 nor 1 - if (type !== 0 && type !== 1) { + // Return error if either number is greater than (2^48)-1 + if (number1 > 281474976710655 || number2 > 281474976710655) { return error.num; } - // Compute cumulative principal - var payment = exports.PMT(rate, periods, value, 0, type); - var principal = 0; - if (start === 1) { - if (type === 0) { - principal = payment + value * rate; - } else { - principal = payment; - } - start++; - } - for (var i = start; i <= end; i++) { - if (type > 0) { - principal += payment - (exports.FV(rate, i - 2, payment, value, 1) - payment) * rate; - } else { - principal += payment - exports.FV(rate, i - 1, payment, value, 0) * rate; - } - } - - // Return cumulative principal - return principal; + // Return bitwise XOR of two numbers + return number1 ^ number2; }; - exports.DB = function(cost, salvage, life, period, month) { - // Initialize month - month = (month === undefined) ? 12 : month; + exports.COMPLEX = function(real, imaginary, suffix) { + real = utils.parseNumber(real); + imaginary = utils.parseNumber(imaginary); + if (utils.anyIsError(real, imaginary)) { + return real; + } - cost = utils.parseNumber(cost); - salvage = utils.parseNumber(salvage); - life = utils.parseNumber(life); - period = utils.parseNumber(period); - month = utils.parseNumber(month); - if (utils.anyIsError(cost, salvage, life, period, month)) { + // Set suffix + suffix = (suffix === undefined) ? 'i' : suffix; + + // Return error if suffix is neither "i" nor "j" + if (suffix !== 'i' && suffix !== 'j') { return error.value; } - // Return error if any of the parameters is negative - if (cost < 0 || salvage < 0 || life < 0 || period < 0) { - return error.num; + // Return complex number + if (real === 0 && imaginary === 0) { + return 0; + } else if (real === 0) { + return (imaginary === 1) ? suffix : imaginary.toString() + suffix; + } else if (imaginary === 0) { + return real.toString(); + } else { + var sign = (imaginary > 0) ? '+' : ''; + return real.toString() + sign + ((imaginary === 1) ? suffix : imaginary.toString() + suffix); + } + }; + + exports.CONVERT = function(number, from_unit, to_unit) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - // Return error if month is not an integer between 1 and 12 - if ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].indexOf(month) === -1) { - return error.num; - } + // List of units supported by CONVERT and units defined by the International System of Units + // [Name, Symbol, Alternate symbols, Quantity, ISU, CONVERT, Conversion ratio] + var units = [ + ["a.u. of action", "?", null, "action", false, false, 1.05457168181818e-34], + ["a.u. of charge", "e", null, "electric_charge", false, false, 1.60217653141414e-19], + ["a.u. of energy", "Eh", null, "energy", false, false, 4.35974417757576e-18], + ["a.u. of length", "a?", null, "length", false, false, 5.29177210818182e-11], + ["a.u. of mass", "m?", null, "mass", false, false, 9.10938261616162e-31], + ["a.u. of time", "?/Eh", null, "time", false, false, 2.41888432650516e-17], + ["admiralty knot", "admkn", null, "speed", false, true, 0.514773333], + ["ampere", "A", null, "electric_current", true, false, 1], + ["ampere per meter", "A/m", null, "magnetic_field_intensity", true, false, 1], + ["ångström", "Å", ["ang"], "length", false, true, 1e-10], + ["are", "ar", null, "area", false, true, 100], + ["astronomical unit", "ua", null, "length", false, false, 1.49597870691667e-11], + ["bar", "bar", null, "pressure", false, false, 100000], + ["barn", "b", null, "area", false, false, 1e-28], + ["becquerel", "Bq", null, "radioactivity", true, false, 1], + ["bit", "bit", ["b"], "information", false, true, 1], + ["btu", "BTU", ["btu"], "energy", false, true, 1055.05585262], + ["byte", "byte", null, "information", false, true, 8], + ["candela", "cd", null, "luminous_intensity", true, false, 1], + ["candela per square metre", "cd/m?", null, "luminance", true, false, 1], + ["coulomb", "C", null, "electric_charge", true, false, 1], + ["cubic ångström", "ang3", ["ang^3"], "volume", false, true, 1e-30], + ["cubic foot", "ft3", ["ft^3"], "volume", false, true, 0.028316846592], + ["cubic inch", "in3", ["in^3"], "volume", false, true, 0.000016387064], + ["cubic light-year", "ly3", ["ly^3"], "volume", false, true, 8.46786664623715e-47], + ["cubic metre", "m?", null, "volume", true, true, 1], + ["cubic mile", "mi3", ["mi^3"], "volume", false, true, 4168181825.44058], + ["cubic nautical mile", "Nmi3", ["Nmi^3"], "volume", false, true, 6352182208], + ["cubic Pica", "Pica3", ["Picapt3", "Pica^3", "Picapt^3"], "volume", false, true, 7.58660370370369e-8], + ["cubic yard", "yd3", ["yd^3"], "volume", false, true, 0.764554857984], + ["cup", "cup", null, "volume", false, true, 0.0002365882365], + ["dalton", "Da", ["u"], "mass", false, false, 1.66053886282828e-27], + ["day", "d", ["day"], "time", false, true, 86400], + ["degree", "°", null, "angle", false, false, 0.0174532925199433], + ["degrees Rankine", "Rank", null, "temperature", false, true, 0.555555555555556], + ["dyne", "dyn", ["dy"], "force", false, true, 0.00001], + ["electronvolt", "eV", ["ev"], "energy", false, true, 1.60217656514141], + ["ell", "ell", null, "length", false, true, 1.143], + ["erg", "erg", ["e"], "energy", false, true, 1e-7], + ["farad", "F", null, "electric_capacitance", true, false, 1], + ["fluid ounce", "oz", null, "volume", false, true, 0.0000295735295625], + ["foot", "ft", null, "length", false, true, 0.3048], + ["foot-pound", "flb", null, "energy", false, true, 1.3558179483314], + ["gal", "Gal", null, "acceleration", false, false, 0.01], + ["gallon", "gal", null, "volume", false, true, 0.003785411784], + ["gauss", "G", ["ga"], "magnetic_flux_density", false, true, 1], + ["grain", "grain", null, "mass", false, true, 0.0000647989], + ["gram", "g", null, "mass", false, true, 0.001], + ["gray", "Gy", null, "absorbed_dose", true, false, 1], + ["gross registered ton", "GRT", ["regton"], "volume", false, true, 2.8316846592], + ["hectare", "ha", null, "area", false, true, 10000], + ["henry", "H", null, "inductance", true, false, 1], + ["hertz", "Hz", null, "frequency", true, false, 1], + ["horsepower", "HP", ["h"], "power", false, true, 745.69987158227], + ["horsepower-hour", "HPh", ["hh", "hph"], "energy", false, true, 2684519.538], + ["hour", "h", ["hr"], "time", false, true, 3600], + ["imperial gallon (U.K.)", "uk_gal", null, "volume", false, true, 0.00454609], + ["imperial hundredweight", "lcwt", ["uk_cwt", "hweight"], "mass", false, true, 50.802345], + ["imperial quart (U.K)", "uk_qt", null, "volume", false, true, 0.0011365225], + ["imperial ton", "brton", ["uk_ton", "LTON"], "mass", false, true, 1016.046909], + ["inch", "in", null, "length", false, true, 0.0254], + ["international acre", "uk_acre", null, "area", false, true, 4046.8564224], + ["IT calorie", "cal", null, "energy", false, true, 4.1868], + ["joule", "J", null, "energy", true, true, 1], + ["katal", "kat", null, "catalytic_activity", true, false, 1], + ["kelvin", "K", ["kel"], "temperature", true, true, 1], + ["kilogram", "kg", null, "mass", true, true, 1], + ["knot", "kn", null, "speed", false, true, 0.514444444444444], + ["light-year", "ly", null, "length", false, true, 9460730472580800], + ["litre", "L", ["l", "lt"], "volume", false, true, 0.001], + ["lumen", "lm", null, "luminous_flux", true, false, 1], + ["lux", "lx", null, "illuminance", true, false, 1], + ["maxwell", "Mx", null, "magnetic_flux", false, false, 1e-18], + ["measurement ton", "MTON", null, "volume", false, true, 1.13267386368], + ["meter per hour", "m/h", ["m/hr"], "speed", false, true, 0.00027777777777778], + ["meter per second", "m/s", ["m/sec"], "speed", true, true, 1], + ["meter per second squared", "m?s??", null, "acceleration", true, false, 1], + ["parsec", "pc", ["parsec"], "length", false, true, 30856775814671900], + ["meter squared per second", "m?/s", null, "kinematic_viscosity", true, false, 1], + ["metre", "m", null, "length", true, true, 1], + ["miles per hour", "mph", null, "speed", false, true, 0.44704], + ["millimetre of mercury", "mmHg", null, "pressure", false, false, 133.322], + ["minute", "?", null, "angle", false, false, 0.000290888208665722], + ["minute", "min", ["mn"], "time", false, true, 60], + ["modern teaspoon", "tspm", null, "volume", false, true, 0.000005], + ["mole", "mol", null, "amount_of_substance", true, false, 1], + ["morgen", "Morgen", null, "area", false, true, 2500], + ["n.u. of action", "?", null, "action", false, false, 1.05457168181818e-34], + ["n.u. of mass", "m?", null, "mass", false, false, 9.10938261616162e-31], + ["n.u. of speed", "c?", null, "speed", false, false, 299792458], + ["n.u. of time", "?/(me?c??)", null, "time", false, false, 1.28808866778687e-21], + ["nautical mile", "M", ["Nmi"], "length", false, true, 1852], + ["newton", "N", null, "force", true, true, 1], + ["œrsted", "Oe ", null, "magnetic_field_intensity", false, false, 79.5774715459477], + ["ohm", "Ω", null, "electric_resistance", true, false, 1], + ["ounce mass", "ozm", null, "mass", false, true, 0.028349523125], + ["pascal", "Pa", null, "pressure", true, false, 1], + ["pascal second", "Pa?s", null, "dynamic_viscosity", true, false, 1], + ["pferdestärke", "PS", null, "power", false, true, 735.49875], + ["phot", "ph", null, "illuminance", false, false, 0.0001], + ["pica (1/6 inch)", "pica", null, "length", false, true, 0.00035277777777778], + ["pica (1/72 inch)", "Pica", ["Picapt"], "length", false, true, 0.00423333333333333], + ["poise", "P", null, "dynamic_viscosity", false, false, 0.1], + ["pond", "pond", null, "force", false, true, 0.00980665], + ["pound force", "lbf", null, "force", false, true, 4.4482216152605], + ["pound mass", "lbm", null, "mass", false, true, 0.45359237], + ["quart", "qt", null, "volume", false, true, 0.000946352946], + ["radian", "rad", null, "angle", true, false, 1], + ["second", "?", null, "angle", false, false, 0.00000484813681109536], + ["second", "s", ["sec"], "time", true, true, 1], + ["short hundredweight", "cwt", ["shweight"], "mass", false, true, 45.359237], + ["siemens", "S", null, "electrical_conductance", true, false, 1], + ["sievert", "Sv", null, "equivalent_dose", true, false, 1], + ["slug", "sg", null, "mass", false, true, 14.59390294], + ["square ångström", "ang2", ["ang^2"], "area", false, true, 1e-20], + ["square foot", "ft2", ["ft^2"], "area", false, true, 0.09290304], + ["square inch", "in2", ["in^2"], "area", false, true, 0.00064516], + ["square light-year", "ly2", ["ly^2"], "area", false, true, 8.95054210748189e+31], + ["square meter", "m?", null, "area", true, true, 1], + ["square mile", "mi2", ["mi^2"], "area", false, true, 2589988.110336], + ["square nautical mile", "Nmi2", ["Nmi^2"], "area", false, true, 3429904], + ["square Pica", "Pica2", ["Picapt2", "Pica^2", "Picapt^2"], "area", false, true, 0.00001792111111111], + ["square yard", "yd2", ["yd^2"], "area", false, true, 0.83612736], + ["statute mile", "mi", null, "length", false, true, 1609.344], + ["steradian", "sr", null, "solid_angle", true, false, 1], + ["stilb", "sb", null, "luminance", false, false, 0.0001], + ["stokes", "St", null, "kinematic_viscosity", false, false, 0.0001], + ["stone", "stone", null, "mass", false, true, 6.35029318], + ["tablespoon", "tbs", null, "volume", false, true, 0.0000147868], + ["teaspoon", "tsp", null, "volume", false, true, 0.00000492892], + ["tesla", "T", null, "magnetic_flux_density", true, true, 1], + ["thermodynamic calorie", "c", null, "energy", false, true, 4.184], + ["ton", "ton", null, "mass", false, true, 907.18474], + ["tonne", "t", null, "mass", false, false, 1000], + ["U.K. pint", "uk_pt", null, "volume", false, true, 0.00056826125], + ["U.S. bushel", "bushel", null, "volume", false, true, 0.03523907], + ["U.S. oil barrel", "barrel", null, "volume", false, true, 0.158987295], + ["U.S. pint", "pt", ["us_pt"], "volume", false, true, 0.000473176473], + ["U.S. survey mile", "survey_mi", null, "length", false, true, 1609.347219], + ["U.S. survey/statute acre", "us_acre", null, "area", false, true, 4046.87261], + ["volt", "V", null, "voltage", true, false, 1], + ["watt", "W", null, "power", true, true, 1], + ["watt-hour", "Wh", ["wh"], "energy", false, true, 3600], + ["weber", "Wb", null, "magnetic_flux", true, false, 1], + ["yard", "yd", null, "length", false, true, 0.9144], + ["year", "yr", null, "time", false, true, 31557600] + ]; + + // Binary prefixes + // [Name, Prefix power of 2 value, Previx value, Abbreviation, Derived from] + var binary_prefixes = { + Yi: ["yobi", 80, 1208925819614629174706176, "Yi", "yotta"], + Zi: ["zebi", 70, 1180591620717411303424, "Zi", "zetta"], + Ei: ["exbi", 60, 1152921504606846976, "Ei", "exa"], + Pi: ["pebi", 50, 1125899906842624, "Pi", "peta"], + Ti: ["tebi", 40, 1099511627776, "Ti", "tera"], + Gi: ["gibi", 30, 1073741824, "Gi", "giga"], + Mi: ["mebi", 20, 1048576, "Mi", "mega"], + ki: ["kibi", 10, 1024, "ki", "kilo"] + }; + + // Unit prefixes + // [Name, Multiplier, Abbreviation] + var unit_prefixes = { + Y: ["yotta", 1e+24, "Y"], + Z: ["zetta", 1e+21, "Z"], + E: ["exa", 1e+18, "E"], + P: ["peta", 1e+15, "P"], + T: ["tera", 1e+12, "T"], + G: ["giga", 1e+09, "G"], + M: ["mega", 1e+06, "M"], + k: ["kilo", 1e+03, "k"], + h: ["hecto", 1e+02, "h"], + e: ["dekao", 1e+01, "e"], + d: ["deci", 1e-01, "d"], + c: ["centi", 1e-02, "c"], + m: ["milli", 1e-03, "m"], + u: ["micro", 1e-06, "u"], + n: ["nano", 1e-09, "n"], + p: ["pico", 1e-12, "p"], + f: ["femto", 1e-15, "f"], + a: ["atto", 1e-18, "a"], + z: ["zepto", 1e-21, "z"], + y: ["yocto", 1e-24, "y"] + }; - // Return error if period is greater than life - if (period > life) { - return error.num; - } + // Initialize units and multipliers + var from = null; + var to = null; + var base_from_unit = from_unit; + var base_to_unit = to_unit; + var from_multiplier = 1; + var to_multiplier = 1; + var alt; - // Return 0 (zero) if salvage is greater than or equal to cost - if (salvage >= cost) { - return 0; + // Lookup from and to units + for (var i = 0; i < units.length; i++) { + alt = (units[i][2] === null) ? [] : units[i][2]; + if (units[i][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) { + from = units[i]; + } + if (units[i][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) { + to = units[i]; + } } - // Rate is rounded to three decimals places - var rate = (1 - Math.pow(salvage / cost, 1 / life)).toFixed(3); + // Lookup from prefix + if (from === null) { + var from_binary_prefix = binary_prefixes[from_unit.substring(0, 2)]; + var from_unit_prefix = unit_prefixes[from_unit.substring(0, 1)]; - // Compute initial depreciation - var initial = cost * rate * month / 12; + // Handle dekao unit prefix (only unit prefix with two characters) + if (from_unit.substring(0, 2) === 'da') { + from_unit_prefix = ["dekao", 1e+01, "da"]; + } - // Compute total depreciation - var total = initial; - var current = 0; - var ceiling = (period === life) ? life - 1 : period; - for (var i = 2; i <= ceiling; i++) { - current = (cost - total) * rate; - total += current; - } + // Handle binary prefixes first (so that 'Yi' is processed before 'Y') + if (from_binary_prefix) { + from_multiplier = from_binary_prefix[2]; + base_from_unit = from_unit.substring(2); + } else if (from_unit_prefix) { + from_multiplier = from_unit_prefix[1]; + base_from_unit = from_unit.substring(from_unit_prefix[2].length); + } - // Depreciation for the first and last periods are special cases - if (period === 1) { - // First period - return initial; - } else if (period === life) { - // Last period - return (cost - total) * rate; - } else { - return current; + // Lookup from unit + for (var j = 0; j < units.length; j++) { + alt = (units[j][2] === null) ? [] : units[j][2]; + if (units[j][1] === base_from_unit || alt.indexOf(base_from_unit) >= 0) { + from = units[j]; + } + } } - }; - exports.DDB = function(cost, salvage, life, period, factor) { - // Initialize factor - factor = (factor === undefined) ? 2 : factor; + // Lookup to prefix + if (to === null) { + var to_binary_prefix = binary_prefixes[to_unit.substring(0, 2)]; + var to_unit_prefix = unit_prefixes[to_unit.substring(0, 1)]; - cost = utils.parseNumber(cost); - salvage = utils.parseNumber(salvage); - life = utils.parseNumber(life); - period = utils.parseNumber(period); - factor = utils.parseNumber(factor); - if (utils.anyIsError(cost, salvage, life, period, factor)) { - return error.value; - } + // Handle dekao unit prefix (only unit prefix with two characters) + if (to_unit.substring(0, 2) === 'da') { + to_unit_prefix = ["dekao", 1e+01, "da"]; + } - // Return error if any of the parameters is negative or if factor is null - if (cost < 0 || salvage < 0 || life < 0 || period < 0 || factor <= 0) { - return error.num; - } + // Handle binary prefixes first (so that 'Yi' is processed before 'Y') + if (to_binary_prefix) { + to_multiplier = to_binary_prefix[2]; + base_to_unit = to_unit.substring(2); + } else if (to_unit_prefix) { + to_multiplier = to_unit_prefix[1]; + base_to_unit = to_unit.substring(to_unit_prefix[2].length); + } - // Return error if period is greater than life - if (period > life) { - return error.num; + // Lookup to unit + for (var k = 0; k < units.length; k++) { + alt = (units[k][2] === null) ? [] : units[k][2]; + if (units[k][1] === base_to_unit || alt.indexOf(base_to_unit) >= 0) { + to = units[k]; + } + } } - // Return 0 (zero) if salvage is greater than or equal to cost - if (salvage >= cost) { - return 0; + // Return error if a unit does not exist + if (from === null || to === null) { + return error.na; } - // Compute depreciation - var total = 0; - var current = 0; - for (var i = 1; i <= period; i++) { - current = Math.min((cost - total) * (factor / life), (cost - salvage - total)); - total += current; + // Return error if units represent different quantities + if (from[3] !== to[3]) { + return error.na; } - // Return depreciation - return current; - }; - - // TODO - exports.DISC = function() { - throw new Error('DISC is not implemented'); + // Return converted number + return number * from[6] * from_multiplier / (to[6] * to_multiplier); }; - exports.DOLLARDE = function(dollar, fraction) { - // Credits: algorithm inspired by Apache OpenOffice - - dollar = utils.parseNumber(dollar); - fraction = utils.parseNumber(fraction); - if (utils.anyIsError(dollar, fraction)) { - return error.value; + exports.DEC2BIN = function(number, places) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - // Return error if fraction is negative - if (fraction < 0) { + // Return error if number is not decimal, is lower than -512, or is greater than 511 + if (!/^-?[0-9]{1,3}$/.test(number) || number < -512 || number > 511) { return error.num; } - // Return error if fraction is greater than or equal to 0 and less than 1 - if (fraction >= 0 && fraction < 1) { - return error.div0; + // Ignore places and return a 10-character binary number if number is negative + if (number < 0) { + return '1' + text.REPT('0', 9 - (512 + number).toString(2).length) + (512 + number).toString(2); } - // Truncate fraction if it is not an integer - fraction = parseInt(fraction, 10); + // Convert decimal number to binary + var result = parseInt(number, 10).toString(2); - // Compute integer part - var result = parseInt(dollar, 10); + // Return binary number using the minimum number of characters necessary if places is undefined + if (typeof places === 'undefined') { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } - // Add decimal part - result += (dollar % 1) * Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN10)) / fraction; + // Return error if places is negative + if (places < 0) { + return error.num; + } - // Round result - var power = Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN2) + 1); - result = Math.round(result * power) / power; + // Truncate places in case it is not an integer + places = Math.floor(places); - // Return converted dollar price - return result; + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + } }; - exports.DOLLARFR = function(dollar, fraction) { - // Credits: algorithm inspired by Apache OpenOffice - - dollar = utils.parseNumber(dollar); - fraction = utils.parseNumber(fraction); - if (utils.anyIsError(dollar, fraction)) { - return error.value; + exports.DEC2HEX = function(number, places) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - // Return error if fraction is negative - if (fraction < 0) { + // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887 + if (!/^-?[0-9]{1,12}$/.test(number) || number < -549755813888 || number > 549755813887) { return error.num; } - // Return error if fraction is greater than or equal to 0 and less than 1 - if (fraction >= 0 && fraction < 1) { - return error.div0; + // Ignore places and return a 10-character hexadecimal number if number is negative + if (number < 0) { + return (1099511627776 + number).toString(16); } - // Truncate fraction if it is not an integer - fraction = parseInt(fraction, 10); + // Convert decimal number to hexadecimal + var result = parseInt(number, 10).toString(16); - // Compute integer part - var result = parseInt(dollar, 10); + // Return hexadecimal number using the minimum number of characters necessary if places is undefined + if (typeof places === 'undefined') { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } - // Add decimal part - result += (dollar % 1) * Math.pow(10, -Math.ceil(Math.log(fraction) / Math.LN10)) * fraction; + // Return error if places is negative + if (places < 0) { + return error.num; + } - // Return converted dollar price - return result; - }; + // Truncate places in case it is not an integer + places = Math.floor(places); - // TODO - exports.DURATION = function() { - throw new Error('DURATION is not implemented'); + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + } }; - exports.EFFECT = function(rate, periods) { - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - if (utils.anyIsError(rate, periods)) { - return error.value; + exports.DEC2OCT = function(number, places) { + number = utils.parseNumber(number); + if (number instanceof Error) { + return number; } - // Return error if rate <=0 or periods < 1 - if (rate <= 0 || periods < 1) { + // Return error if number is not decimal, is lower than -549755813888, or is greater than 549755813887 + if (!/^-?[0-9]{1,9}$/.test(number) || number < -536870912 || number > 536870911) { return error.num; } - // Truncate periods if it is not an integer - periods = parseInt(periods, 10); + // Ignore places and return a 10-character octal number if number is negative + if (number < 0) { + return (1073741824 + number).toString(8); + } - // Return effective annual interest rate - return Math.pow(1 + rate / periods, periods) - 1; - }; + // Convert decimal number to octal + var result = parseInt(number, 10).toString(8); - exports.FV = function(rate, periods, payment, value, type) { - // Credits: algorithm inspired by Apache OpenOffice + // Return octal number using the minimum number of characters necessary if places is undefined + if (typeof places === 'undefined') { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } - value = value || 0; - type = type || 0; + // Return error if places is negative + if (places < 0) { + return error.num; + } - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - payment = utils.parseNumber(payment); - value = utils.parseNumber(value); - type = utils.parseNumber(type); - if (utils.anyIsError(rate, periods, payment, value, type)) { - return error.value; - } + // Truncate places in case it is not an integer + places = Math.floor(places); - // Return future value - var result; - if (rate === 0) { - result = value + payment * periods; - } else { - var term = Math.pow(1 + rate, periods); - if (type === 1) { - result = value * term + payment * (1 + rate) * (term - 1) / rate; - } else { - result = value * term + payment * (term - 1) / rate; - } + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; } - return -result; }; - exports.FVSCHEDULE = function(principal, schedule) { - principal = utils.parseNumber(principal); - schedule = utils.parseNumberArray(utils.flatten(schedule)); - if (utils.anyIsError(principal, schedule)) { + exports.DELTA = function(number1, number2) { + // Set number2 to zero if undefined + number2 = (number2 === undefined) ? 0 : number2; + number1 = utils.parseNumber(number1); + number2 = utils.parseNumber(number2); + if (utils.anyIsError(number1, number2)) { return error.value; } - var n = schedule.length; - var future = principal; + // Return delta + return (number1 === number2) ? 1 : 0; + }; - // Apply all interests in schedule - for (var i = 0; i < n; i++) { - // Apply scheduled interest - future *= 1 + schedule[i]; + // TODO: why is upper_bound not used ? The excel documentation has no examples with upper_bound + exports.ERF = function(lower_bound, upper_bound) { + // Set number2 to zero if undefined + upper_bound = (upper_bound === undefined) ? 0 : upper_bound; + + lower_bound = utils.parseNumber(lower_bound); + upper_bound = utils.parseNumber(upper_bound); + if (utils.anyIsError(lower_bound, upper_bound)) { + return error.value; } - // Return future value - return future; + return jStat.erf(lower_bound); }; // TODO - exports.INTRATE = function() { - throw new Error('INTRATE is not implemented'); + exports.ERF.PRECISE = function() { + throw new Error('ERF.PRECISE is not implemented'); }; - exports.IPMT = function(rate, period, periods, present, future, type) { - // Credits: algorithm inspired by Apache OpenOffice - - future = future || 0; - type = type || 0; - - rate = utils.parseNumber(rate); - period = utils.parseNumber(period); - periods = utils.parseNumber(periods); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - type = utils.parseNumber(type); - if (utils.anyIsError(rate, period, periods, present, future, type)) { + exports.ERFC = function(x) { + // Return error if x is not a number + if (isNaN(x)) { return error.value; } - // Compute payment - var payment = exports.PMT(rate, periods, present, future, type); - - // Compute interest - var interest; - if (period === 1) { - if (type === 1) { - interest = 0; - } else { - interest = -present; - } - } else { - if (type === 1) { - interest = exports.FV(rate, period - 2, payment, present, 1) - payment; - } else { - interest = exports.FV(rate, period - 1, payment, present, 0); - } - } + return jStat.erfc(x); + }; - // Return interest - return interest * rate; + // TODO + exports.ERFC.PRECISE = function() { + throw new Error('ERFC.PRECISE is not implemented'); }; - exports.IRR = function(values, guess) { - // Credits: algorithm inspired by Apache OpenOffice + exports.GESTEP = function(number, step) { + step = step || 0; + number = utils.parseNumber(number); + if (utils.anyIsError(step, number)) { + return number; + } - guess = guess || 0; + // Return delta + return (number >= step) ? 1 : 0; + }; - values = utils.parseNumberArray(utils.flatten(values)); - guess = utils.parseNumber(guess); - if (utils.anyIsError(values, guess)) { - return error.value; + exports.HEX2BIN = function(number, places) { + // Return error if number is not hexadecimal or contains more than ten characters (10 digits) + if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) { + return error.num; } - // Calculates the resulting amount - var irrResult = function(values, dates, rate) { - var r = rate + 1; - var result = values[0]; - for (var i = 1; i < values.length; i++) { - result += values[i] / Math.pow(r, (dates[i] - dates[0]) / 365); - } - return result; - }; + // Check if number is negative + var negative = (number.length === 10 && number.substring(0, 1).toLowerCase() === 'f') ? true : false; - // Calculates the first derivation - var irrResultDeriv = function(values, dates, rate) { - var r = rate + 1; - var result = 0; - for (var i = 1; i < values.length; i++) { - var frac = (dates[i] - dates[0]) / 365; - result -= frac * values[i] / Math.pow(r, frac + 1); - } - return result; - }; + // Convert hexadecimal number to decimal + var decimal = (negative) ? parseInt(number, 16) - 1099511627776 : parseInt(number, 16); - // Initialize dates and check that values contains at least one positive value and one negative value - var dates = []; - var positive = false; - var negative = false; - for (var i = 0; i < values.length; i++) { - dates[i] = (i === 0) ? 0 : dates[i - 1] + 365; - if (values[i] > 0) { - positive = true; - } - if (values[i] < 0) { - negative = true; - } + // Return error if number is lower than -512 or greater than 511 + if (decimal < -512 || decimal > 511) { + return error.num; } - // Return error if values does not contain at least one positive value and one negative value - if (!positive || !negative) { - return error.num; + // Ignore places and return a 10-character binary number if number is negative + if (negative) { + return '1' + text.REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2); } - // Initialize guess and resultRate - guess = (guess === undefined) ? 0.1 : guess; - var resultRate = guess; + // Convert decimal number to binary + var result = decimal.toString(2); - // Set maximum epsilon for end of iteration - var epsMax = 1e-10; + // Return binary number using the minimum number of characters necessary if places is undefined + if (places === undefined) { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } - // Implement Newton's method - var newRate, epsRate, resultValue; - var contLoop = true; - do { - resultValue = irrResult(values, dates, resultRate); - newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate); - epsRate = Math.abs(newRate - resultRate); - resultRate = newRate; - contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax); - } while (contLoop); + // Return error if places is negative + if (places < 0) { + return error.num; + } + + // Truncate places in case it is not an integer + places = Math.floor(places); - // Return internal rate of return - return resultRate; + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + } }; - exports.ISPMT = function(rate, period, periods, value) { - rate = utils.parseNumber(rate); - period = utils.parseNumber(period); - periods = utils.parseNumber(periods); - value = utils.parseNumber(value); - if (utils.anyIsError(rate, period, periods, value)) { - return error.value; + exports.HEX2DEC = function(number) { + // Return error if number is not hexadecimal or contains more than ten characters (10 digits) + if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) { + return error.num; } - // Return interest - return value * rate * (period / periods - 1); - }; + // Convert hexadecimal number to decimal + var decimal = parseInt(number, 16); - // TODO - exports.MDURATION = function() { - throw new Error('MDURATION is not implemented'); + // Return decimal number + return (decimal >= 549755813888) ? decimal - 1099511627776 : decimal; }; - exports.MIRR = function(values, finance_rate, reinvest_rate) { - values = utils.parseNumberArray(utils.flatten(values)); - finance_rate = utils.parseNumber(finance_rate); - reinvest_rate = utils.parseNumber(reinvest_rate); - if (utils.anyIsError(values, finance_rate, reinvest_rate)) { - return error.value; + exports.HEX2OCT = function(number, places) { + // Return error if number is not hexadecimal or contains more than ten characters (10 digits) + if (!/^[0-9A-Fa-f]{1,10}$/.test(number)) { + return error.num; } - // Initialize number of values - var n = values.length; + // Convert hexadecimal number to decimal + var decimal = parseInt(number, 16); - // Lookup payments (negative values) and incomes (positive values) - var payments = []; - var incomes = []; - for (var i = 0; i < n; i++) { - if (values[i] < 0) { - payments.push(values[i]); - } else { - incomes.push(values[i]); - } + // Return error if number is positive and greater than 0x1fffffff (536870911) + if (decimal > 536870911 && decimal < 1098974756864) { + return error.num; } - // Return modified internal rate of return - var num = -exports.NPV(reinvest_rate, incomes) * Math.pow(1 + reinvest_rate, n - 1); - var den = exports.NPV(finance_rate, payments) * (1 + finance_rate); - return Math.pow(num / den, 1 / (n - 1)) - 1; - }; - - exports.NOMINAL = function(rate, periods) { - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - if (utils.anyIsError(rate, periods)) { - return error.value; + // Ignore places and return a 10-character octal number if number is negative + if (decimal >= 1098974756864) { + return (decimal - 1098437885952).toString(8); } - // Return error if rate <=0 or periods < 1 - if (rate <= 0 || periods < 1) { - return error.num; - } + // Convert decimal number to octal + var result = decimal.toString(8); - // Truncate periods if it is not an integer - periods = parseInt(periods, 10); + // Return octal number using the minimum number of characters necessary if places is undefined + if (places === undefined) { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } - // Return nominal annual interest rate - return (Math.pow(rate + 1, 1 / periods) - 1) * periods; + // Return error if places is negative + if (places < 0) { + return error.num; + } + + // Truncate places in case it is not an integer + places = Math.floor(places); + + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; + } }; - exports.NPER = function(rate, payment, present, future, type) { - type = (type === undefined) ? 0 : type; - future = (future === undefined) ? 0 : future; + exports.IMABS = function(inumber) { + // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - rate = utils.parseNumber(rate); - payment = utils.parseNumber(payment); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - type = utils.parseNumber(type); - if (utils.anyIsError(rate, payment, present, future, type)) { + // Return error if either coefficient is not a number + if (utils.anyIsError(x, y)) { return error.value; } - // Return number of periods - var num = payment * (1 + rate * type) - future * rate; - var den = (present * rate + payment * (1 + rate * type)); - return Math.log(num / den) / Math.log(1 + rate); + // Return absolute value of complex number + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); }; - exports.NPV = function() { - var args = utils.parseNumberArray(utils.flatten(arguments)); - if (args instanceof Error) { - return args; + exports.IMAGINARY = function(inumber) { + if (inumber === undefined || inumber === true || inumber === false) { + return error.value; } - // Lookup rate - var rate = args[0]; + // Return 0 if inumber is equal to 0 + if (inumber === 0 || inumber === '0') { + return 0; + } - // Initialize net present value - var value = 0; + // Handle special cases + if (['i', 'j'].indexOf(inumber) >= 0) { + return 1; + } - // Loop on all values - for (var j = 1; j < args.length; j++) { - value += args[j] / Math.pow(1 + rate, j); + // Normalize imaginary coefficient + inumber = inumber.replace('+i', '+1i').replace('-i', '-1i').replace('+j', '+1j').replace('-j', '-1j'); + + // Lookup sign + var plus = inumber.indexOf('+'); + var minus = inumber.indexOf('-'); + if (plus === 0) { + plus = inumber.indexOf('+', 1); } - // Return net present value - return value; - }; + if (minus === 0) { + minus = inumber.indexOf('-', 1); + } - // TODO - exports.ODDFPRICE = function() { - throw new Error('ODDFPRICE is not implemented'); - }; + // Lookup imaginary unit + var last = inumber.substring(inumber.length - 1, inumber.length); + var unit = (last === 'i' || last === 'j'); - // TODO - exports.ODDFYIELD = function() { - throw new Error('ODDFYIELD is not implemented'); - }; + if (plus >= 0 || minus >= 0) { + // Return error if imaginary unit is neither i nor j + if (!unit) { + return error.num; + } - // TODO - exports.ODDLPRICE = function() { - throw new Error('ODDLPRICE is not implemented'); + // Return imaginary coefficient of complex number + if (plus >= 0) { + return (isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))) ? + error.num : + Number(inumber.substring(plus + 1, inumber.length - 1)); + } else { + return (isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))) ? + error.num : + -Number(inumber.substring(minus + 1, inumber.length - 1)); + } + } else { + if (unit) { + return (isNaN(inumber.substring(0, inumber.length - 1))) ? error.num : inumber.substring(0, inumber.length - 1); + } else { + return (isNaN(inumber)) ? error.num : 0; + } + } }; - // TODO - exports.ODDLYIELD = function() { - throw new Error('ODDLYIELD is not implemented'); - }; + exports.IMARGUMENT = function(inumber) { + // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - exports.PDURATION = function(rate, present, future) { - rate = utils.parseNumber(rate); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - if (utils.anyIsError(rate, present, future)) { + // Return error if either coefficient is not a number + if (utils.anyIsError(x, y)) { return error.value; } - // Return error if rate <=0 - if (rate <= 0) { - return error.num; + // Return error if inumber is equal to zero + if (x === 0 && y === 0) { + return error.div0; } - // Return number of periods - return (Math.log(future) - Math.log(present)) / Math.log(1 + rate); - }; + // Return PI/2 if x is equal to zero and y is positive + if (x === 0 && y > 0) { + return Math.PI / 2; + } - exports.PMT = function(rate, periods, present, future, type) { - // Credits: algorithm inspired by Apache OpenOffice + // Return -PI/2 if x is equal to zero and y is negative + if (x === 0 && y < 0) { + return -Math.PI / 2; + } - future = future || 0; - type = type || 0; + // Return zero if x is negative and y is equal to zero + if (y === 0 && x > 0) { + return 0; + } - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - type = utils.parseNumber(type); - if (utils.anyIsError(rate, periods, present, future, type)) { - return error.value; + // Return zero if x is negative and y is equal to zero + if (y === 0 && x < 0) { + return -Math.PI; } - // Return payment - var result; - if (rate === 0) { - result = (present + future) / periods; + // Return argument of complex number + if (x > 0) { + return Math.atan(y / x); + } else if (x < 0 && y >= 0) { + return Math.atan(y / x) + Math.PI; } else { - var term = Math.pow(1 + rate, periods); - if (type === 1) { - result = (future * rate / (term - 1) + present * rate / (1 - 1 / term)) / (1 + rate); - } else { - result = future * rate / (term - 1) + present * rate / (1 - 1 / term); - } + return Math.atan(y / x) - Math.PI; } - return -result; }; - exports.PPMT = function(rate, period, periods, present, future, type) { - future = future || 0; - type = type || 0; + exports.IMCONJUGATE = function(inumber) { + // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - type = utils.parseNumber(type); - if (utils.anyIsError(rate, periods, present, future, type)) { + if (utils.anyIsError(x, y)) { return error.value; } - return exports.PMT(rate, periods, present, future, type) - exports.IPMT(rate, period, periods, present, future, type); - }; - - // TODO - exports.PRICE = function() { - throw new Error('PRICE is not implemented'); - }; - - // TODO - exports.PRICEDISC = function() { - throw new Error('PRICEDISC is not implemented'); - }; + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - // TODO - exports.PRICEMAT = function() { - throw new Error('PRICEMAT is not implemented'); + // Return conjugate of complex number + return (y !== 0) ? exports.COMPLEX(x, -y, unit) : inumber; }; - exports.PV = function(rate, periods, payment, future, type) { - future = future || 0; - type = type || 0; + exports.IMCOS = function(inumber) { + // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - rate = utils.parseNumber(rate); - periods = utils.parseNumber(periods); - payment = utils.parseNumber(payment); - future = utils.parseNumber(future); - type = utils.parseNumber(type); - if (utils.anyIsError(rate, periods, payment, future, type)) { + if (utils.anyIsError(x, y)) { return error.value; } - // Return present value - if (rate === 0) { - return -payment * periods - future; - } else { - return (((1 - Math.pow(1 + rate, periods)) / rate) * payment * (1 + rate * type) - future) / Math.pow(1 + rate, periods); - } - }; + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - exports.RATE = function(periods, payment, present, future, type, guess) { - // Credits: rabugento + // Return cosine of complex number + return exports.COMPLEX(Math.cos(x) * (Math.exp(y) + Math.exp(-y)) / 2, -Math.sin(x) * (Math.exp(y) - Math.exp(-y)) / 2, unit); + }; - guess = (guess === undefined) ? 0.01 : guess; - future = (future === undefined) ? 0 : future; - type = (type === undefined) ? 0 : type; + exports.IMCOSH = function(inumber) { + // Lookup real and imaginary coefficients using exports.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - periods = utils.parseNumber(periods); - payment = utils.parseNumber(payment); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - type = utils.parseNumber(type); - guess = utils.parseNumber(guess); - if (utils.anyIsError(periods, payment, present, future, type, guess)) { + if (utils.anyIsError(x, y)) { return error.value; } - // Set maximum epsilon for end of iteration - var epsMax = 1e-6; - - // Set maximum number of iterations - var iterMax = 100; - var iter = 0; - var close = false; - var rate = guess; - - while (iter < iterMax && !close) { - var t1 = Math.pow(rate + 1, periods); - var t2 = Math.pow(rate + 1, periods - 1); + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - var f1 = future + t1 * present + payment * (t1 - 1) * (rate * type + 1) / rate; - var f2 = periods * t2 * present - payment * (t1 - 1) *(rate * type + 1) / Math.pow(rate,2); - var f3 = periods * payment * t2 * (rate * type + 1) / rate + payment * (t1 - 1) * type / rate; + // Return hyperbolic cosine of complex number + return exports.COMPLEX(Math.cos(y) * (Math.exp(x) + Math.exp(-x)) / 2, Math.sin(y) * (Math.exp(x) - Math.exp(-x)) / 2, unit); + }; - var newRate = rate - f1 / (f2 + f3); + exports.IMCOT = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - if (Math.abs(newRate - rate) < epsMax) close = true; - iter++ - rate = newRate; + if (utils.anyIsError(x, y)) { + return error.value; } - if (!close) return Number.NaN + rate; - return rate; + // Return cotangent of complex number + return exports.IMDIV(exports.IMCOS(inumber), exports.IMSIN(inumber)); }; - // TODO - exports.RECEIVED = function() { - throw new Error('RECEIVED is not implemented'); - }; + exports.IMDIV = function(inumber1, inumber2) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var a = exports.IMREAL(inumber1); + var b = exports.IMAGINARY(inumber1); + var c = exports.IMREAL(inumber2); + var d = exports.IMAGINARY(inumber2); - exports.RRI = function(periods, present, future) { - periods = utils.parseNumber(periods); - present = utils.parseNumber(present); - future = utils.parseNumber(future); - if (utils.anyIsError(periods, present, future)) { + if (utils.anyIsError(a, b, c, d)) { return error.value; } - // Return error if periods or present is equal to 0 (zero) - if (periods === 0 || present === 0) { + // Lookup imaginary unit + var unit1 = inumber1.substring(inumber1.length - 1); + var unit2 = inumber2.substring(inumber2.length - 1); + var unit = 'i'; + if (unit1 === 'j') { + unit = 'j'; + } else if (unit2 === 'j') { + unit = 'j'; + } + + // Return error if inumber2 is null + if (c === 0 && d === 0) { return error.num; } - // Return equivalent interest rate - return Math.pow(future / present, 1 / periods) - 1; + // Return exponential of complex number + var den = c * c + d * d; + return exports.COMPLEX((a * c + b * d) / den, (b * c - a * d) / den, unit); }; - exports.SLN = function(cost, salvage, life) { - cost = utils.parseNumber(cost); - salvage = utils.parseNumber(salvage); - life = utils.parseNumber(life); - if (utils.anyIsError(cost, salvage, life)) { + exports.IMEXP = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + + if (utils.anyIsError(x, y)) { return error.value; } - // Return error if life equal to 0 (zero) - if (life === 0) { - return error.num; - } + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - // Return straight-line depreciation - return (cost - salvage) / life; + // Return exponential of complex number + var e = Math.exp(x); + return exports.COMPLEX(e * Math.cos(y), e * Math.sin(y), unit); }; - exports.SYD = function(cost, salvage, life, period) { - // Return error if any of the parameters is not a number - cost = utils.parseNumber(cost); - salvage = utils.parseNumber(salvage); - life = utils.parseNumber(life); - period = utils.parseNumber(period); - if (utils.anyIsError(cost, salvage, life, period)) { - return error.value; - } - - // Return error if life equal to 0 (zero) - if (life === 0) { - return error.num; - } + exports.IMLN = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - // Return error if period is lower than 1 or greater than life - if (period < 1 || period > life) { - return error.num; + if (utils.anyIsError(x, y)) { + return error.value; } - // Truncate period if it is not an integer - period = parseInt(period, 10); + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - // Return straight-line depreciation - return ((cost - salvage) * (life - period + 1) * 2) / (life * (life + 1)); + // Return exponential of complex number + return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)), Math.atan(y / x), unit); }; - exports.TBILLEQ = function(settlement, maturity, discount) { - settlement = utils.parseDate(settlement); - maturity = utils.parseDate(maturity); - discount = utils.parseNumber(discount); - if (utils.anyIsError(settlement, maturity, discount)) { + exports.IMLOG10 = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + + if (utils.anyIsError(x, y)) { return error.value; } - // Return error if discount is lower than or equal to zero - if (discount <= 0) { - return error.num; - } + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - // Return error if settlement is greater than maturity - if (settlement > maturity) { - return error.num; - } + // Return exponential of complex number + return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(10), Math.atan(y / x) / Math.log(10), unit); + }; - // Return error if maturity is more than one year after settlement - if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) { - return error.num; + exports.IMLOG2 = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + + if (utils.anyIsError(x, y)) { + return error.value; } - // Return bond-equivalent yield - return (365 * discount) / (360 - discount * dateTime.DAYS360(settlement, maturity, false)); + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; + + // Return exponential of complex number + return exports.COMPLEX(Math.log(Math.sqrt(x * x + y * y)) / Math.log(2), Math.atan(y / x) / Math.log(2), unit); }; - exports.TBILLPRICE = function(settlement, maturity, discount) { - settlement = utils.parseDate(settlement); - maturity = utils.parseDate(maturity); - discount = utils.parseNumber(discount); - if (utils.anyIsError(settlement, maturity, discount)) { + exports.IMPOWER = function(inumber, number) { + number = utils.parseNumber(number); + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + if (utils.anyIsError(number, x, y)) { return error.value; } - // Return error if discount is lower than or equal to zero - if (discount <= 0) { - return error.num; - } + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - // Return error if settlement is greater than maturity - if (settlement > maturity) { - return error.num; - } + // Calculate power of modulus + var p = Math.pow(exports.IMABS(inumber), number); - // Return error if maturity is more than one year after settlement - if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) { - return error.num; - } + // Calculate argument + var t = exports.IMARGUMENT(inumber); - // Return bond-equivalent yield - return 100 * (1 - discount * dateTime.DAYS360(settlement, maturity, false) / 360); + // Return exponential of complex number + return exports.COMPLEX(p * Math.cos(number * t), p * Math.sin(number * t), unit); }; - exports.TBILLYIELD = function(settlement, maturity, price) { - settlement = utils.parseDate(settlement); - maturity = utils.parseDate(maturity); - price = utils.parseNumber(price); - if (utils.anyIsError(settlement, maturity, price)) { - return error.value; - } + exports.IMPRODUCT = function() { + // Initialize result + var result = arguments[0]; - // Return error if price is lower than or equal to zero - if (price <= 0) { - return error.num; - } + // Loop on all numbers + for (var i = 1; i < arguments.length; i++) { + // Lookup coefficients of two complex numbers + var a = exports.IMREAL(result); + var b = exports.IMAGINARY(result); + var c = exports.IMREAL(arguments[i]); + var d = exports.IMAGINARY(arguments[i]); - // Return error if settlement is greater than maturity - if (settlement > maturity) { - return error.num; - } + if (utils.anyIsError(a, b, c, d)) { + return error.value; + } - // Return error if maturity is more than one year after settlement - if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) { - return error.num; + // Complute product of two complex numbers + result = exports.COMPLEX(a * c - b * d, a * d + b * c); } - // Return bond-equivalent yield - return (100 - price) * 360 / (price * dateTime.DAYS360(settlement, maturity, false)); + // Return product of complex numbers + return result; }; - // TODO - exports.VDB = function() { - throw new Error('VDB is not implemented'); - }; + exports.IMREAL = function(inumber) { + if (inumber === undefined || inumber === true || inumber === false) { + return error.value; + } + // Return 0 if inumber is equal to 0 + if (inumber === 0 || inumber === '0') { + return 0; + } - exports.XIRR = function(values, dates, guess) { - // Credits: algorithm inspired by Apache OpenOffice + // Handle special cases + if (['i', '+i', '1i', '+1i', '-i', '-1i', 'j', '+j', '1j', '+1j', '-j', '-1j'].indexOf(inumber) >= 0) { + return 0; + } - values = utils.parseNumberArray(utils.flatten(values)); - dates = utils.parseDateArray(utils.flatten(dates)); - guess = utils.parseNumber(guess); - if (utils.anyIsError(values, dates, guess)) { - return error.value; + // Lookup sign + var plus = inumber.indexOf('+'); + var minus = inumber.indexOf('-'); + if (plus === 0) { + plus = inumber.indexOf('+', 1); + } + if (minus === 0) { + minus = inumber.indexOf('-', 1); } - // Calculates the resulting amount - var irrResult = function(values, dates, rate) { - var r = rate + 1; - var result = values[0]; - for (var i = 1; i < values.length; i++) { - result += values[i] / Math.pow(r, dateTime.DAYS(dates[i], dates[0]) / 365); - } - return result; - }; + // Lookup imaginary unit + var last = inumber.substring(inumber.length - 1, inumber.length); + var unit = (last === 'i' || last === 'j'); - // Calculates the first derivation - var irrResultDeriv = function(values, dates, rate) { - var r = rate + 1; - var result = 0; - for (var i = 1; i < values.length; i++) { - var frac = dateTime.DAYS(dates[i], dates[0]) / 365; - result -= frac * values[i] / Math.pow(r, frac + 1); + if (plus >= 0 || minus >= 0) { + // Return error if imaginary unit is neither i nor j + if (!unit) { + return error.num; } - return result; - }; - // Check that values contains at least one positive value and one negative value - var positive = false; - var negative = false; - for (var i = 0; i < values.length; i++) { - if (values[i] > 0) { - positive = true; + // Return real coefficient of complex number + if (plus >= 0) { + return (isNaN(inumber.substring(0, plus)) || isNaN(inumber.substring(plus + 1, inumber.length - 1))) ? + error.num : + Number(inumber.substring(0, plus)); + } else { + return (isNaN(inumber.substring(0, minus)) || isNaN(inumber.substring(minus + 1, inumber.length - 1))) ? + error.num : + Number(inumber.substring(0, minus)); } - if (values[i] < 0) { - negative = true; + } else { + if (unit) { + return (isNaN(inumber.substring(0, inumber.length - 1))) ? error.num : 0; + } else { + return (isNaN(inumber)) ? error.num : inumber; } } + }; - // Return error if values does not contain at least one positive value and one negative value - if (!positive || !negative) { - return error.num; + exports.IMSEC = function(inumber) { + // Return error if inumber is a logical value + if (inumber === true || inumber === false) { + return error.value; } - // Initialize guess and resultRate - guess = guess || 0.1; - var resultRate = guess; - - // Set maximum epsilon for end of iteration - var epsMax = 1e-10; + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - // Implement Newton's method - var newRate, epsRate, resultValue; - var contLoop = true; - do { - resultValue = irrResult(values, dates, resultRate); - newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate); - epsRate = Math.abs(newRate - resultRate); - resultRate = newRate; - contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax); - } while (contLoop); + if (utils.anyIsError(x, y)) { + return error.value; + } - // Return internal rate of return - return resultRate; + // Return secant of complex number + return exports.IMDIV('1', exports.IMCOS(inumber)); }; - exports.XNPV = function(rate, values, dates) { - rate = utils.parseNumber(rate); - values = utils.parseNumberArray(utils.flatten(values)); - dates = utils.parseDateArray(utils.flatten(dates)); - if (utils.anyIsError(rate, values, dates)) { + exports.IMSECH = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + + if (utils.anyIsError(x, y)) { return error.value; } - var result = 0; - for (var i = 0; i < values.length; i++) { - result += values[i] / Math.pow(1 + rate, dateTime.DAYS(dates[i], dates[0]) / 365); - } - return result; + // Return hyperbolic secant of complex number + return exports.IMDIV('1', exports.IMCOSH(inumber)); }; - // TODO - exports.YIELD = function() { - throw new Error('YIELD is not implemented'); - }; + exports.IMSIN = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - // TODO - exports.YIELDDISC = function() { - throw new Error('YIELDDISC is not implemented'); - }; + if (utils.anyIsError(x, y)) { + return error.value; + } - // TODO - exports.YIELDMAT = function() { - throw new Error('YIELDMAT is not implemented'); + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; + + // Return sine of complex number + return exports.COMPLEX(Math.sin(x) * (Math.exp(y) + Math.exp(-y)) / 2, Math.cos(x) * (Math.exp(y) - Math.exp(-y)) / 2, unit); }; -/***/ }, -/* 9 */ -/***/ function(module, exports, __webpack_require__) { + exports.IMSINH = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - var error = __webpack_require__(16); + if (utils.anyIsError(x, y)) { + return error.value; + } - // TODO - exports.CELL = function() { - throw new Error('CELL is not implemented'); - }; + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - exports.ERROR = {}; - exports.ERROR.TYPE = function(error_val) { - switch (error_val) { - case error.nil: return 1; - case error.div0: return 2; - case error.value: return 3; - case error.ref: return 4; - case error.name: return 5; - case error.num: return 6; - case error.na: return 7; - case error.data: return 8; - } - return error.na; + // Return hyperbolic sine of complex number + return exports.COMPLEX(Math.cos(y) * (Math.exp(x) - Math.exp(-x)) / 2, Math.sin(y) * (Math.exp(x) + Math.exp(-x)) / 2, unit); }; - // TODO - exports.INFO = function() { - throw new Error('INFO is not implemented'); - }; + exports.IMSQRT = function(inumber) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + + if (utils.anyIsError(x, y)) { + return error.value; + } - exports.ISBLANK = function(value) { - return value === null; - }; + // Lookup imaginary unit + var unit = inumber.substring(inumber.length - 1); + unit = (unit === 'i' || unit === 'j') ? unit : 'i'; - exports.ISBINARY = function (number) { - return (/^[01]{1,10}$/).test(number); - }; + // Calculate power of modulus + var s = Math.sqrt(exports.IMABS(inumber)); - exports.ISERR = function(value) { - return ([error.value, error.ref, error.div0, error.num, error.name, error.nil]).indexOf(value) >= 0 || - (typeof value === 'number' && (isNaN(value) || !isFinite(value))); - }; + // Calculate argument + var t = exports.IMARGUMENT(inumber); - exports.ISERROR = function(value) { - return exports.ISERR(value) || value === error.na; + // Return exponential of complex number + return exports.COMPLEX(s * Math.cos(t / 2), s * Math.sin(t / 2), unit); }; - exports.ISEVEN = function(number) { - return (Math.floor(Math.abs(number)) & 1) ? false : true; - }; + exports.IMCSC = function (inumber) { + // Return error if inumber is a logical value + if (inumber === true || inumber === false) { + return error.value; + } - // TODO - exports.ISFORMULA = function() { - throw new Error('ISFORMULA is not implemented'); - }; + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - exports.ISLOGICAL = function(value) { - return value === true || value === false; - }; + // Return error if either coefficient is not a number + if (utils.anyIsError(x, y)) { + return error.num; + } - exports.ISNA = function(value) { - return value === error.na; + // Return cosecant of complex number + return exports.IMDIV('1', exports.IMSIN(inumber)); }; - exports.ISNONTEXT = function(value) { - return typeof(value) !== 'string'; - }; + exports.IMCSCH = function (inumber) { + // Return error if inumber is a logical value + if (inumber === true || inumber === false) { + return error.value; + } - exports.ISNUMBER = function(value) { - return typeof(value) === 'number' && !isNaN(value) && isFinite(value); - }; + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); - exports.ISODD = function(number) { - return (Math.floor(Math.abs(number)) & 1) ? true : false; - }; + // Return error if either coefficient is not a number + if (utils.anyIsError(x, y)) { + return error.num; + } - // TODO - exports.ISREF = function() { - throw new Error('ISREF is not implemented'); + // Return hyperbolic cosecant of complex number + return exports.IMDIV('1', exports.IMSINH(inumber)); }; - exports.ISTEXT = function(value) { - return typeof(value) === 'string'; - }; + exports.IMSUB = function(inumber1, inumber2) { + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var a = this.IMREAL(inumber1); + var b = this.IMAGINARY(inumber1); + var c = this.IMREAL(inumber2); + var d = this.IMAGINARY(inumber2); - exports.N = function(value) { - if (this.ISNUMBER(value)) { - return value; - } - if (value instanceof Date) { - return value.getTime(); - } - if (value === true) { - return 1; - } - if (value === false) { - return 0; + if (utils.anyIsError(a, b, c, d)) { + return error.value; } - if (this.ISERROR(value)) { - return value; + + // Lookup imaginary unit + var unit1 = inumber1.substring(inumber1.length - 1); + var unit2 = inumber2.substring(inumber2.length - 1); + var unit = 'i'; + if (unit1 === 'j') { + unit = 'j'; + } else if (unit2 === 'j') { + unit = 'j'; } - return 0; - }; - exports.NA = function() { - return error.na; + // Return _ of two complex numbers + return this.COMPLEX(a - c, b - d, unit); }; + exports.IMSUM = function() { + var args = utils.flatten(arguments); - // TODO - exports.SHEET = function() { - throw new Error('SHEET is not implemented'); - }; + // Initialize result + var result = args[0]; - // TODO - exports.SHEETS = function() { - throw new Error('SHEETS is not implemented'); - }; + // Loop on all numbers + for (var i = 1; i < args.length; i++) { + // Lookup coefficients of two complex numbers + var a = this.IMREAL(result); + var b = this.IMAGINARY(result); + var c = this.IMREAL(args[i]); + var d = this.IMAGINARY(args[i]); - exports.TYPE = function(value) { - if (this.ISNUMBER(value)) { - return 1; - } - if (this.ISTEXT(value)) { - return 2; - } - if (this.ISLOGICAL(value)) { - return 4; + if (utils.anyIsError(a, b, c, d)) { + return error.value; + } + + // Complute product of two complex numbers + result = this.COMPLEX(a + c, b + d); } - if (this.ISERROR(value)) { - return 16; + + // Return sum of complex numbers + return result; + }; + + exports.IMTAN = function(inumber) { + // Return error if inumber is a logical value + if (inumber === true || inumber === false) { + return error.value; } - if (Array.isArray(value)) { - return 64; + + // Lookup real and imaginary coefficients using Formula.js [http://formulajs.org] + var x = exports.IMREAL(inumber); + var y = exports.IMAGINARY(inumber); + + if (utils.anyIsError(x, y)) { + return error.value; } + + // Return tangent of complex number + return this.IMDIV(this.IMSIN(inumber), this.IMCOS(inumber)); }; + exports.OCT2BIN = function(number, places) { + // Return error if number is not hexadecimal or contains more than ten characters (10 digits) + if (!/^[0-7]{1,10}$/.test(number)) { + return error.num; + } -/***/ }, -/* 10 */ -/***/ function(module, exports, __webpack_require__) { + // Check if number is negative + var negative = (number.length === 10 && number.substring(0, 1) === '7') ? true : false; - var error = __webpack_require__(16); + // Convert octal number to decimal + var decimal = (negative) ? parseInt(number, 8) - 1073741824 : parseInt(number, 8); - exports.MATCH = function(lookupValue, lookupArray, matchType) { - if (!lookupValue && !lookupArray) { - return error.na; + // Return error if number is lower than -512 or greater than 511 + if (decimal < -512 || decimal > 511) { + return error.num; } - if (arguments.length === 2) { - matchType = 1; - } - if (!(lookupArray instanceof Array)) { - return error.na; + // Ignore places and return a 10-character binary number if number is negative + if (negative) { + return '1' + text.REPT('0', 9 - (512 + decimal).toString(2).length) + (512 + decimal).toString(2); } - if (matchType !== -1 && matchType !== 0 && matchType !== 1) { - return error.na; - } - var index; - var indexValue; - for (var idx = 0; idx < lookupArray.length; idx++) { - if (matchType === 1) { - if (lookupArray[idx] === lookupValue) { - return idx + 1; - } else if (lookupArray[idx] < lookupValue) { - if (!indexValue) { - index = idx + 1; - indexValue = lookupArray[idx]; - } else if (lookupArray[idx] > indexValue) { - index = idx + 1; - indexValue = lookupArray[idx]; - } - } - } else if (matchType === 0) { - if (typeof lookupValue === 'string') { - lookupValue = lookupValue.replace(/\?/g, '.'); - if (lookupArray[idx].toLowerCase().match(lookupValue.toLowerCase())) { - return idx + 1; - } - } else { - if (lookupArray[idx] === lookupValue) { - return idx + 1; - } - } - } else if (matchType === -1) { - if (lookupArray[idx] === lookupValue) { - return idx + 1; - } else if (lookupArray[idx] > lookupValue) { - if (!indexValue) { - index = idx + 1; - indexValue = lookupArray[idx]; - } else if (lookupArray[idx] < indexValue) { - index = idx + 1; - indexValue = lookupArray[idx]; - } - } + // Convert decimal number to binary + var result = decimal.toString(2); + + // Return binary number using the minimum number of characters necessary if places is undefined + if (typeof places === 'undefined') { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } + + // Return error if places is negative + if (places < 0) { + return error.num; } + + // Truncate places in case it is not an integer + places = Math.floor(places); + + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; } + }; - return index ? index : error.na; + exports.OCT2DEC = function(number) { + // Return error if number is not octal or contains more than ten characters (10 digits) + if (!/^[0-7]{1,10}$/.test(number)) { + return error.num; + } + + // Convert octal number to decimal + var decimal = parseInt(number, 8); + + // Return decimal number + return (decimal >= 536870912) ? decimal - 1073741824 : decimal; }; -/***/ }, -/* 11 */ -/***/ function(module, exports, __webpack_require__) { + exports.OCT2HEX = function(number, places) { + // Return error if number is not octal or contains more than ten characters (10 digits) + if (!/^[0-7]{1,10}$/.test(number)) { + return error.num; + } - var mathTrig = __webpack_require__(5); - var text = __webpack_require__(6); - var jStat = __webpack_require__(13).jStat; - var utils = __webpack_require__(17); - var error = __webpack_require__(16); - var misc = __webpack_require__(12); + // Convert octal number to decimal + var decimal = parseInt(number, 8); - var SQRT2PI = 2.5066282746310002; + // Ignore places and return a 10-character octal number if number is negative + if (decimal >= 536870912) { + return 'ff' + (decimal + 3221225472).toString(16); + } - exports.AVEDEV = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; + // Convert decimal number to hexadecimal + var result = decimal.toString(16); + + // Return hexadecimal number using the minimum number of characters necessary if places is undefined + if (places === undefined) { + return result; + } else { + // Return error if places is nonnumeric + if (isNaN(places)) { + return error.value; + } + + // Return error if places is negative + if (places < 0) { + return error.num; + } + + // Truncate places in case it is not an integer + places = Math.floor(places); + + // Pad return value with leading 0s (zeros) if necessary (using Underscore.string) + return (places >= result.length) ? text.REPT('0', places - result.length) + result : error.num; } - return jStat.sum(jStat(range).subtract(jStat.mean(range)).abs()[0]) / range.length; }; - exports.AVERAGE = function() { - var range = utils.numbers(utils.flatten(arguments)); - var n = range.length; - var sum = 0; - var count = 0; - for (var i = 0; i < n; i++) { - sum += range[i]; - count += 1; +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + + var M = Math; + function _horner(arr, v) { return arr.reduce(function(z,w){return v * z + w;},0); }; + function _bessel_iter(x, n, f0, f1, sign) { + if(!sign) sign = -1; + var tdx = 2 / x, f2; + if(n === 0) return f0; + if(n === 1) return f1; + for(var o = 1; o != n; ++o) { + f2 = f1 * o * tdx + sign * f0; + f0 = f1; f1 = f2; } - return sum / count; - }; + return f1; + } + function _bessel_wrap(bessel0, bessel1, name, nonzero, sign) { + return function bessel(x,n) { + if(n === 0) return bessel0(x); + if(n === 1) return bessel1(x); + if(n < 0) throw name + ': Order (' + n + ') must be nonnegative'; + if(nonzero == 1 && x === 0) throw name + ': Undefined when x == 0'; + if(nonzero == 2 && x <= 0) throw name + ': Undefined when x <= 0'; + var b0 = bessel0(x), b1 = bessel1(x); + return _bessel_iter(x, n, b0, b1, sign); + }; + } + var besselj = (function() { + var b0_a1a = [57568490574.0,-13362590354.0,651619640.7,-11214424.18,77392.33017,-184.9052456].reverse(); + var b0_a2a = [57568490411.0,1029532985.0,9494680.718,59272.64853,267.8532712,1.0].reverse(); + var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse(); + var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934935152e-7].reverse(); + var W = 0.636619772; // 2 / Math.PI - exports.AVERAGEA = function() { - var range = utils.flatten(arguments); - var n = range.length; - var sum = 0; - var count = 0; - for (var i = 0; i < n; i++) { - var el = range[i]; - if (typeof el === 'number') { - sum += el; + function bessel0(x) { + var a, a1, a2, y = x * x, xx = M.abs(x) - 0.785398164; + if(M.abs(x) < 8) { + a1 = _horner(b0_a1a, y); + a2 = _horner(b0_a2a, y); + a = a1/a2; } - if (el === true) { - sum++; + else { + y = 64 / y; + a1 = _horner(b0_a1b, y); + a2 = _horner(b0_a2b, y); + a = M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x)); } - if (el !== null) { - count++; + return a; + } + var b1_a1a = [72362614232.0,-7895059235.0,242396853.1,-2972611.439, 15704.48260, -30.16036606].reverse(); + var b1_a2a = [144725228442.0, 2300535178.0, 18583304.74, 99447.43394, 376.9991397, 1.0].reverse(); + var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse(); + var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse(); + function bessel1(x) { + var a, a1, a2, y = x*x, xx = M.abs(x) - 2.356194491; + if(Math.abs(x)< 8) { + a1 = x*_horner(b1_a1a, y); + a2 = _horner(b1_a2a, y); + a = a1 / a2; + } else { + y = 64 / y; + a1=_horner(b1_a1b, y); + a2=_horner(b1_a2b, y); + a=M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x)); + if(x < 0) a = -a; } + return a; } - return sum / count; - }; + return function besselj(x, n) { + n = Math.round(n); + if(n === 0) return bessel0(M.abs(x)); + if(n === 1) return bessel1(M.abs(x)); + if(n < 0) throw 'BESSELJ: Order (' + n + ') must be nonnegative'; + if(M.abs(x) === 0) return 0; - exports.AVERAGEIF = function(range, criteria, average_range) { - average_range = average_range || range; - range = utils.flatten(range); - average_range = utils.parseNumberArray(utils.flatten(average_range)); - if (average_range instanceof Error) { - return average_range; + var ret, j, tox = 2 / M.abs(x), m, jsum, sum, bjp, bj, bjm; + if(M.abs(x) > n) { + ret = _bessel_iter(x, n, bessel0(M.abs(x)), bessel1(M.abs(x)),-1); + } else { + m=2*M.floor((n+M.floor(M.sqrt(40*n)))/2); + jsum=0; + bjp=ret=sum=0.0; + bj=1.0; + for (j=m;j>0;j--) { + bjm=j*tox*bj-bjp; + bjp=bj; + bj=bjm; + if (M.abs(bj) > 1E10) { + bj *= 1E-10; + bjp *= 1E-10; + ret *= 1E-10; + sum *= 1E-10; + } + if (jsum) sum += bj; + jsum=!jsum; + if (j == n) ret=bjp; + } + sum=2.0*sum-bj; + ret /= sum; + } + return x < 0 && (n%2) ? -ret : ret; + }; + })(); + var bessely = (function() { + var b0_a1a = [-2957821389.0, 7062834065.0, -512359803.6, 10879881.29, -86327.92757, 228.4622733].reverse(); + var b0_a2a = [40076544269.0, 745249964.8, 7189466.438, 47447.26470, 226.1030244, 1.0].reverse(); + var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse(); + var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934945152e-7].reverse(); + + var W = 0.636619772; + function bessel0(x) { + var a, a1, a2, y = x * x, xx = x - 0.785398164; + if(x < 8) { + a1 = _horner(b0_a1a, y); + a2 = _horner(b0_a2a, y); + a = a1/a2 + W * besselj(x,0) * M.log(x); + } else { + y = 64 / y; + a1 = _horner(b0_a1b, y); + a2 = _horner(b0_a2b, y); + a = M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x); + } + return a; } - var average_count = 0; - var result = 0; - for (var i = 0; i < range.length; i++) { - if (eval(range[i] + criteria)) { // jshint ignore:line - result += average_range[i]; - average_count++; + + var b1_a1a = [-0.4900604943e13, 0.1275274390e13, -0.5153438139e11, 0.7349264551e9, -0.4237922726e7, 0.8511937935e4].reverse(); + var b1_a2a = [0.2499580570e14, 0.4244419664e12, 0.3733650367e10, 0.2245904002e8, 0.1020426050e6, 0.3549632885e3, 1].reverse(); + var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse(); + var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse(); + function bessel1(x) { + var a, a1, a2, y = x*x, xx = x - 2.356194491; + if(x < 8) { + a1 = x*_horner(b1_a1a, y); + a2 = _horner(b1_a2a, y); + a = a1/a2 + W * (besselj(x,1) * M.log(x) - 1 / x); + } else { + y = 64 / y; + a1=_horner(b1_a1b, y); + a2=_horner(b1_a2b, y); + a=M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x); } + return a; } - return result / average_count; - }; - exports.AVERAGEIFS = function() { - // Does not work with multi dimensional ranges yet! - //http://office.microsoft.com/en-001/excel-help/averageifs-function-HA010047493.aspx - var args = utils.argsToArray(arguments); - var criteria = (args.length - 1) / 2; - var range = utils.flatten(args[0]); - var count = 0; - var result = 0; - for (var i = 0; i < range.length; i++) { - var condition = ''; - for (var j = 0; j < criteria; j++) { - condition += args[2 * j + 1][i] + args[2 * j + 2]; - if (j !== criteria - 1) { - condition += '&&'; + return _bessel_wrap(bessel0, bessel1, 'BESSELY', 1, -1); + })(); + var besseli = (function() { + var b0_a = [1.0, 3.5156229, 3.0899424, 1.2067492, 0.2659732, 0.360768e-1, 0.45813e-2].reverse(); + var b0_b = [0.39894228, 0.1328592e-1, 0.225319e-2, -0.157565e-2, 0.916281e-2, -0.2057706e-1, 0.2635537e-1, -0.1647633e-1, 0.392377e-2].reverse(); + function bessel0(x) { + if(x <= 3.75) return _horner(b0_a, x*x/(3.75*3.75)); + return M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b0_b, 3.75/M.abs(x)); + } + + var b1_a = [0.5, 0.87890594, 0.51498869, 0.15084934, 0.2658733e-1, 0.301532e-2, 0.32411e-3].reverse(); + var b1_b = [0.39894228, -0.3988024e-1, -0.362018e-2, 0.163801e-2, -0.1031555e-1, 0.2282967e-1, -0.2895312e-1, 0.1787654e-1, -0.420059e-2].reverse(); + function bessel1(x) { + if(x < 3.75) return x * _horner(b1_a, x*x/(3.75*3.75)); + return (x < 0 ? -1 : 1) * M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b1_b, 3.75/M.abs(x)); + } + + return function besseli(x, n) { + n = Math.round(n); + if(n === 0) return bessel0(x); + if(n == 1) return bessel1(x); + if(n < 0) throw 'BESSELI Order (' + n + ') must be nonnegative'; + if(M.abs(x) === 0) return 0; + + var ret, j, tox = 2 / M.abs(x), m, bip, bi, bim; + m=2*M.round((n+M.round(M.sqrt(40*n)))/2); + bip=ret=0.0; + bi=1.0; + for (j=m;j>0;j--) { + bim=j*tox*bi + bip; + bip=bi; bi=bim; + if (M.abs(bi) > 1E10) { + bi *= 1E-10; + bip *= 1E-10; + ret *= 1E-10; } + if(j == n) ret = bip; } - if (eval(condition)) { // jshint ignore:line - result += range[i]; - count++; - } + ret *= besseli(x, 0) / bi; + return x < 0 && (n%2) ? -ret : ret; + }; + + })(); + + var besselk = (function() { + var b0_a = [-0.57721566, 0.42278420, 0.23069756, 0.3488590e-1, 0.262698e-2, 0.10750e-3, 0.74e-5].reverse(); + var b0_b = [1.25331414, -0.7832358e-1, 0.2189568e-1, -0.1062446e-1, 0.587872e-2, -0.251540e-2, 0.53208e-3].reverse(); + function bessel0(x) { + if(x <= 2) return -M.log(x/2)*besseli(x,0) + _horner(b0_a, x*x/4); + return M.exp(-x)/M.sqrt(x)*_horner(b0_b, 2/x); } - var average = result / count; - if (isNaN(average)) { - return 0; - } else { - return average; + var b1_a = [1.0, 0.15443144, -0.67278579, -0.18156897, -0.1919402e-1, -0.110404e-2, -0.4686e-4].reverse(); + var b1_b = [1.25331414, 0.23498619, -0.3655620e-1, 0.1504268e-1, -0.780353e-2, 0.325614e-2, -0.68245e-3].reverse(); + function bessel1(x) { + if(x <= 2) return M.log(x/2)*besseli(x,1) + (1/x)*_horner(b1_a, x*x/4); + return M.exp(-x)/M.sqrt(x)*_horner(b1_b, 2/x); } - }; - exports.BETA = {}; + return _bessel_wrap(bessel0, bessel1, 'BESSELK', 2, 1); + })(); + if(true) { + exports.besselj = besselj; + exports.bessely = bessely; + exports.besseli = besseli; + exports.besselk = besselk; + } - exports.BETA.DIST = function(x, alpha, beta, cumulative, A, B) { - if (arguments.length < 4) { - return error.value; - } - A = (A === undefined) ? 0 : A; - B = (B === undefined) ? 1 : B; - x = utils.parseNumber(x); - alpha = utils.parseNumber(alpha); - beta = utils.parseNumber(beta); - A = utils.parseNumber(A); - B = utils.parseNumber(B); - if (utils.anyIsError(x, alpha, beta, A, B)) { - return error.value; - } +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { - x = (x - A) / (B - A); - return (cumulative) ? jStat.beta.cdf(x, alpha, beta) : jStat.beta.pdf(x, alpha, beta); - }; + var error = __webpack_require__(5); + var utils = __webpack_require__(4); - exports.BETA.INV = function(probability, alpha, beta, A, B) { - A = (A === undefined) ? 0 : A; - B = (B === undefined) ? 1 : B; + var d1900 = new Date(1900, 0, 1); + var WEEK_STARTS = [ + undefined, + 0, + 1, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + 1, + 2, + 3, + 4, + 5, + 6, + 0 + ]; + var WEEK_TYPES = [ + [], + [1, 2, 3, 4, 5, 6, 7], + [7, 1, 2, 3, 4, 5, 6], + [6, 0, 1, 2, 3, 4, 5], + [], + [], + [], + [], + [], + [], + [], + [7, 1, 2, 3, 4, 5, 6], + [6, 7, 1, 2, 3, 4, 5], + [5, 6, 7, 1, 2, 3, 4], + [4, 5, 6, 7, 1, 2, 3], + [3, 4, 5, 6, 7, 1, 2], + [2, 3, 4, 5, 6, 7, 1], + [1, 2, 3, 4, 5, 6, 7] + ]; + var WEEKEND_TYPES = [ + [], + [6, 0], + [0, 1], + [1, 2], + [2, 3], + [3, 4], + [4, 5], + [5, 6], + undefined, + undefined, + undefined, [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6] + ]; - probability = utils.parseNumber(probability); - alpha = utils.parseNumber(alpha); - beta = utils.parseNumber(beta); - A = utils.parseNumber(A); - B = utils.parseNumber(B); - if (utils.anyIsError(probability, alpha, beta, A, B)) { + exports.DATE = function(year, month, day) { + year = utils.parseNumber(year); + month = utils.parseNumber(month); + day = utils.parseNumber(day); + if (utils.anyIsError(year, month, day)) { return error.value; } - - return jStat.beta.inv(probability, alpha, beta) * (B - A) + A; + if (year < 0 || month < 0 || day < 0) { + return error.num; + } + var date = new Date(year, month - 1, day); + return date; }; - exports.BINOM = {}; - - exports.BINOM.DIST = function(successes, trials, probability, cumulative) { - successes = utils.parseNumber(successes); - trials = utils.parseNumber(trials); - probability = utils.parseNumber(probability); - cumulative = utils.parseNumber(cumulative); - if (utils.anyIsError(successes, trials, probability, cumulative)) { + exports.DATEVALUE = function(date_text) { + if (typeof date_text !== 'string') { return error.value; } - return (cumulative) ? jStat.binomial.cdf(successes, trials, probability) : jStat.binomial.pdf(successes, trials, probability); - }; - - exports.BINOM.DIST.RANGE = function(trials, probability, successes, successes2) { - successes2 = (successes2 === undefined) ? successes : successes2; - - trials = utils.parseNumber(trials); - probability = utils.parseNumber(probability); - successes = utils.parseNumber(successes); - successes2 = utils.parseNumber(successes2); - if (utils.anyIsError(trials, probability, successes, successes2)) { + var date = Date.parse(date_text); + if (isNaN(date)) { return error.value; } + if (date <= -2203891200000) { + return (date - d1900) / 86400000 + 1; + } + return (date - d1900) / 86400000 + 2; + }; - var result = 0; - for (var i = successes; i <= successes2; i++) { - result += mathTrig.COMBIN(trials, i) * Math.pow(probability, i) * Math.pow(1 - probability, trials - i); + exports.DAY = function(serial_number) { + var date = utils.parseDate(serial_number); + if (date instanceof Error) { + return date; } - return result; + return date.getDate(); }; - exports.BINOM.INV = function(trials, probability, alpha) { - trials = utils.parseNumber(trials); - probability = utils.parseNumber(probability); - alpha = utils.parseNumber(alpha); - if (utils.anyIsError(trials, probability, alpha)) { - return error.value; + exports.DAYS = function(end_date, start_date) { + end_date = utils.parseDate(end_date); + start_date = utils.parseDate(start_date); + if (end_date instanceof Error) { + return end_date; + } + if (start_date instanceof Error) { + return start_date; } + return serial(end_date) - serial(start_date); + }; - var x = 0; - while (x <= trials) { - if (jStat.binomial.cdf(x, trials, probability) >= alpha) { - return x; + exports.DAYS360 = function(start_date, end_date, method) { + method = utils.parseBool(method); + start_date = utils.parseDate(start_date); + end_date = utils.parseDate(end_date); + if (start_date instanceof Error) { + return start_date; + } + if (end_date instanceof Error) { + return end_date; + } + if (method instanceof Error) { + return method; + } + var sm = start_date.getMonth(); + var em = end_date.getMonth(); + var sd, ed; + if (method) { + sd = start_date.getDate() === 31 ? 30 : start_date.getDate(); + ed = end_date.getDate() === 31 ? 30 : end_date.getDate(); + } else { + var smd = new Date(start_date.getFullYear(), sm + 1, 0).getDate(); + var emd = new Date(end_date.getFullYear(), em + 1, 0).getDate(); + sd = start_date.getDate() === smd ? 30 : start_date.getDate(); + if (end_date.getDate() === emd) { + if (sd < 30) { + em++; + ed = 1; + } else { + ed = 30; + } + } else { + ed = end_date.getDate(); } - x++; } + return 360 * (end_date.getFullYear() - start_date.getFullYear()) + + 30 * (em - sm) + (ed - sd); + }; + + exports.EDATE = function(start_date, months) { + start_date = utils.parseDate(start_date); + if (start_date instanceof Error) { + return start_date; + } + if (isNaN(months)) { + return error.value; + } + months = parseInt(months, 10); + start_date.setMonth(start_date.getMonth() + months); + return serial(start_date); }; - exports.CHISQ = {}; - - exports.CHISQ.DIST = function(x, k, cumulative) { - x = utils.parseNumber(x); - k = utils.parseNumber(k); - if (utils.anyIsError(x, k)) { + exports.EOMONTH = function(start_date, months) { + start_date = utils.parseDate(start_date); + if (start_date instanceof Error) { + return start_date; + } + if (isNaN(months)) { return error.value; } - - return (cumulative) ? jStat.chisquare.cdf(x, k) : jStat.chisquare.pdf(x, k); + months = parseInt(months, 10); + return serial(new Date(start_date.getFullYear(), start_date.getMonth() + months + 1, 0)); }; - exports.CHISQ.DIST.RT = function(x, k) { - if (!x | !k) { - return error.na; - } - - if (x < 1 || k > Math.pow(10, 10)) { - return error.num; + exports.HOUR = function(serial_number) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; } + return serial_number.getHours(); + }; - if ((typeof x !== 'number') || (typeof k !== 'number')) { + exports.INTERVAL = function (second) { + if (typeof second !== 'number' && typeof second !== 'string') { return error.value; + } else { + second = parseInt(second, 10); } - return 1 - jStat.chisquare.cdf(x, k); - }; + var year = Math.floor(second/946080000); + second = second%946080000; + var month = Math.floor(second/2592000); + second = second%2592000; + var day = Math.floor(second/86400); + second = second%86400; - exports.CHISQ.INV = function(probability, k) { - probability = utils.parseNumber(probability); - k = utils.parseNumber(k); - if (utils.anyIsError(probability, k)) { - return error.value; - } - return jStat.chisquare.inv(probability, k); + var hour = Math.floor(second/3600); + second = second%3600; + var min = Math.floor(second/60); + second = second%60; + var sec = second; + + year = (year > 0) ? year + 'Y' : ''; + month = (month > 0) ? month + 'M' : ''; + day = (day > 0) ? day + 'D' : ''; + hour = (hour > 0) ? hour + 'H' : ''; + min = (min > 0) ? min + 'M' : ''; + sec = (sec > 0) ? sec + 'S' : ''; + + return 'P' + year + month + day + + 'T' + hour + min + sec; }; - exports.CHISQ.INV.RT = function(p, k) { - if (!p | !k) { - return error.na; + exports.ISOWEEKNUM = function(date) { + date = utils.parseDate(date); + if (date instanceof Error) { + return date; } - if (p < 0 || p > 1 || k < 1 || k > Math.pow(10, 10)) { - return error.num; + date.setHours(0, 0, 0); + date.setDate(date.getDate() + 4 - (date.getDay() || 7)); + var yearStart = new Date(date.getFullYear(), 0, 1); + return Math.ceil((((date - yearStart) / 86400000) + 1) / 7); + }; + + exports.MINUTE = function(serial_number) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; } + return serial_number.getMinutes(); + }; - if ((typeof p !== 'number') || (typeof k !== 'number')) { - return error.value; + exports.MONTH = function(serial_number) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; } + return serial_number.getMonth() + 1; + }; - return jStat.chisquare.inv(1.0 - p, k); + exports.NETWORKDAYS = function(start_date, end_date, holidays) { + return this.NETWORKDAYS.INTL(start_date, end_date, 1, holidays); }; - exports.CHISQ.TEST = function(observed, expected) { - if (arguments.length !== 2) { - return error.na; + exports.NETWORKDAYS.INTL = function(start_date, end_date, weekend, holidays) { + start_date = utils.parseDate(start_date); + if (start_date instanceof Error) { + return start_date; } - - if ((!(observed instanceof Array)) || (!(expected instanceof Array))) { - return error.value; + end_date = utils.parseDate(end_date); + if (end_date instanceof Error) { + return end_date; } - - if (observed.length !== expected.length) { - return error.value; + if (weekend === undefined) { + weekend = WEEKEND_TYPES[1]; + } else { + weekend = WEEKEND_TYPES[weekend]; } - - if (observed[0] && expected[0] && - observed[0].length !== expected[0].length) { + if (!(weekend instanceof Array)) { return error.value; } - - var row = observed.length; - var tmp, i, j; - - // Convert single-dimension array into two-dimension array - for (i = 0; i < row; i ++) { - if (!(observed[i] instanceof Array)) { - tmp = observed[i]; - observed[i] = []; - observed[i].push(tmp); - } - if (!(expected[i] instanceof Array)) { - tmp = expected[i]; - expected[i] = []; - expected[i].push(tmp); - } + if (holidays === undefined) { + holidays = []; + } else if (!(holidays instanceof Array)) { + holidays = [holidays]; } - - var col = observed[0].length; - var dof = (col === 1) ? row-1 : (row-1)*(col-1); - var xsqr = 0; - var Pi =Math.PI; - - for (i = 0; i < row; i ++) { - for (j = 0; j < col; j ++) { - xsqr += Math.pow((observed[i][j] - expected[i][j]), 2) / expected[i][j]; + for (var i = 0; i < holidays.length; i++) { + var h = utils.parseDate(holidays[i]); + if (h instanceof Error) { + return h; } + holidays[i] = h; } - - // Get independency by X square and its degree of freedom - function ChiSq(xsqr, dof) { - var p = Math.exp(-0.5 * xsqr); - if((dof%2) === 1) { - p = p * Math.sqrt(2 * xsqr/Pi); + var days = (end_date - start_date) / (1000 * 60 * 60 * 24) + 1; + var total = days; + var day = start_date; + for (i = 0; i < days; i++) { + var d = (new Date().getTimezoneOffset() > 0) ? day.getUTCDay() : day.getDay(); + var dec = false; + if (d === weekend[0] || d === weekend[1]) { + dec = true; } - var k = dof; - while(k >= 2) { - p = p * xsqr/k; - k = k - 2; + for (var j = 0; j < holidays.length; j++) { + var holiday = holidays[j]; + if (holiday.getDate() === day.getDate() && + holiday.getMonth() === day.getMonth() && + holiday.getFullYear() === day.getFullYear()) { + dec = true; + break; + } } - var t = p; - var a = dof; - while (t > 0.0000000001*p) { - a = a + 2; - t = t * xsqr/a; - p = p + t; + if (dec) { + total--; } - return 1-p; + day.setDate(day.getDate() + 1); } - - return Math.round(ChiSq(xsqr, dof) * 1000000) / 1000000; + return total; }; - exports.COLUMN = function(matrix, index) { - if (arguments.length !== 2) { - return error.na; - } - - if (index < 0) { - return error.num; - } - - if (!(matrix instanceof Array) || (typeof index !== 'number')) { - return error.value; - } - - if (matrix.length === 0) { - return undefined; - } - - return jStat.col(matrix, index); + exports.NOW = function() { + return new Date(); }; - exports.COLUMNS = function(matrix) { - if (arguments.length !== 1) { - return error.na; - } - - if (!(matrix instanceof Array)) { - return error.value; - } - - if (matrix.length === 0) { - return 0; + exports.SECOND = function(serial_number) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; } - - return jStat.cols(matrix); + return serial_number.getSeconds(); }; - exports.CONFIDENCE = {}; - - exports.CONFIDENCE.NORM = function(alpha, sd, n) { - alpha = utils.parseNumber(alpha); - sd = utils.parseNumber(sd); - n = utils.parseNumber(n); - if (utils.anyIsError(alpha, sd, n)) { + exports.TIME = function(hour, minute, second) { + hour = utils.parseNumber(hour); + minute = utils.parseNumber(minute); + second = utils.parseNumber(second); + if (utils.anyIsError(hour, minute, second)) { return error.value; } - return jStat.normalci(1, alpha, sd, n)[1] - 1; - }; - - exports.CONFIDENCE.T = function(alpha, sd, n) { - alpha = utils.parseNumber(alpha); - sd = utils.parseNumber(sd); - n = utils.parseNumber(n); - if (utils.anyIsError(alpha, sd, n)) { - return error.value; + if (hour < 0 || minute < 0 || second < 0) { + return error.num; } - return jStat.tci(1, alpha, sd, n)[1] - 1; + return (3600 * hour + 60 * minute + second) / 86400; }; - exports.CORREL = function(array1, array2) { - array1 = utils.parseNumberArray(utils.flatten(array1)); - array2 = utils.parseNumberArray(utils.flatten(array2)); - if (utils.anyIsError(array1, array2)) { - return error.value; + exports.TIMEVALUE = function(time_text) { + time_text = utils.parseDate(time_text); + if (time_text instanceof Error) { + return time_text; } - return jStat.corrcoeff(array1, array2); + return (3600 * time_text.getHours() + + 60 * time_text.getMinutes() + + time_text.getSeconds()) / 86400; }; - exports.COUNT = function() { - return utils.numbers(utils.flatten(arguments)).length; + exports.TODAY = function() { + return new Date(); }; - exports.COUNTA = function() { - var range = utils.flatten(arguments); - return range.length - exports.COUNTBLANK(range); + exports.WEEKDAY = function(serial_number, return_type) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; + } + if (return_type === undefined) { + return_type = 1; + } + var day = serial_number.getDay(); + return WEEK_TYPES[return_type][day]; }; - exports.COUNTIN = function (range, value) { - var result = 0; - for (var i = 0; i < range.length; i++) { - if (range[i] === value) { - result++; - } + exports.WEEKNUM = function(serial_number, return_type) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; } - return result; + if (return_type === undefined) { + return_type = 1; + } + if (return_type === 21) { + return this.ISOWEEKNUM(serial_number); + } + var week_start = WEEK_STARTS[return_type]; + var jan = new Date(serial_number.getFullYear(), 0, 1); + var inc = jan.getDay() < week_start ? 1 : 0; + jan -= Math.abs(jan.getDay() - week_start) * 24 * 60 * 60 * 1000; + return Math.floor(((serial_number - jan) / (1000 * 60 * 60 * 24)) / 7 + 1) + inc; }; - - exports.COUNTBLANK = function() { - var range = utils.flatten(arguments); - var blanks = 0; - var element; - for (var i = 0; i < range.length; i++) { - element = range[i]; - if (element === null || element === '') { - blanks++; - } - } - return blanks; + exports.WORKDAY = function(start_date, days, holidays) { + return this.WORKDAY.INTL(start_date, days, 1, holidays); }; - exports.COUNTIF = function(range, criteria) { - range = utils.flatten(range); - if (!/[<>=!]/.test(criteria)) { - criteria = '=="' + criteria + '"'; + exports.WORKDAY.INTL = function(start_date, days, weekend, holidays) { + start_date = utils.parseDate(start_date); + if (start_date instanceof Error) { + return start_date; } - var matches = 0; - for (var i = 0; i < range.length; i++) { - if (typeof range[i] !== 'string') { - if (eval(range[i] + criteria)) { // jshint ignore:line - matches++; - } - } else { - if (eval('"' + range[i] + '"' + criteria)) { // jshint ignore:line - matches++; - } - } + days = utils.parseNumber(days); + if (days instanceof Error) { + return days; } - return matches; - }; - - exports.COUNTIFS = function() { - var args = utils.argsToArray(arguments); - var results = new Array(utils.flatten(args[0]).length); - for (var i = 0; i < results.length; i++) { - results[i] = true; + if (days < 0) { + return error.num; } - for (i = 0; i < args.length; i += 2) { - var range = utils.flatten(args[i]); - var criteria = args[i + 1]; - if (!/[<>=!]/.test(criteria)) { - criteria = '=="' + criteria + '"'; - } - for (var j = 0; j < range.length; j++) { - if (typeof range[j] !== 'string') { - results[j] = results[j] && eval(range[j] + criteria); // jshint ignore:line - } else { - results[j] = results[j] && eval('"' + range[j] + '"' + criteria); // jshint ignore:line - } + if (weekend === undefined) { + weekend = WEEKEND_TYPES[1]; + } else { + weekend = WEEKEND_TYPES[weekend]; + } + if (!(weekend instanceof Array)) { + return error.value; + } + if (holidays === undefined) { + holidays = []; + } else if (!(holidays instanceof Array)) { + holidays = [holidays]; + } + for (var i = 0; i < holidays.length; i++) { + var h = utils.parseDate(holidays[i]); + if (h instanceof Error) { + return h; } + holidays[i] = h; } - var result = 0; - for (i = 0; i < results.length; i++) { - if (results[i]) { - result++; + var d = 0; + while (d < days) { + start_date.setDate(start_date.getDate() + 1); + var day = start_date.getDay(); + if (day === weekend[0] || day === weekend[1]) { + continue; + } + for (var j = 0; j < holidays.length; j++) { + var holiday = holidays[j]; + if (holiday.getDate() === start_date.getDate() && + holiday.getMonth() === start_date.getMonth() && + holiday.getFullYear() === start_date.getFullYear()) { + d--; + break; + } } + d++; } - return result; + return start_date; }; - exports.COUNTUNIQUE = function () { - return misc.UNIQUE.apply(null, utils.flatten(arguments)).length; + exports.YEAR = function(serial_number) { + serial_number = utils.parseDate(serial_number); + if (serial_number instanceof Error) { + return serial_number; + } + return serial_number.getFullYear(); }; - exports.COVARIANCE = {}; + function isLeapYear(year) { + return new Date(year, 1, 29).getMonth() === 1; + } - exports.COVARIANCE.P = function(array1, array2) { - array1 = utils.parseNumberArray(utils.flatten(array1)); - array2 = utils.parseNumberArray(utils.flatten(array2)); - if (utils.anyIsError(array1, array2)) { - return error.value; + // TODO : Use DAYS ? + function daysBetween(start_date, end_date) { + return Math.ceil((end_date - start_date) / 1000 / 60 / 60 / 24); + } + + exports.YEARFRAC = function(start_date, end_date, basis) { + start_date = utils.parseDate(start_date); + if (start_date instanceof Error) { + return start_date; } - var mean1 = jStat.mean(array1); - var mean2 = jStat.mean(array2); - var result = 0; - var n = array1.length; - for (var i = 0; i < n; i++) { - result += (array1[i] - mean1) * (array2[i] - mean2); + end_date = utils.parseDate(end_date); + if (end_date instanceof Error) { + return end_date; } - return result / n; - }; - exports.COVARIANCE.S = function(array1, array2) { - array1 = utils.parseNumberArray(utils.flatten(array1)); - array2 = utils.parseNumberArray(utils.flatten(array2)); - if (utils.anyIsError(array1, array2)) { - return error.value; - } - return jStat.covariance(array1, array2); - }; + basis = basis || 0; + var sd = start_date.getDate(); + var sm = start_date.getMonth() + 1; + var sy = start_date.getFullYear(); + var ed = end_date.getDate(); + var em = end_date.getMonth() + 1; + var ey = end_date.getFullYear(); - exports.DEVSQ = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; - } - var mean = jStat.mean(range); - var result = 0; - for (var i = 0; i < range.length; i++) { - result += Math.pow((range[i] - mean), 2); + switch (basis) { + case 0: + // US (NASD) 30/360 + if (sd === 31 && ed === 31) { + sd = 30; + ed = 30; + } else if (sd === 31) { + sd = 30; + } else if (sd === 30 && ed === 31) { + ed = 30; + } + return ((ed + em * 30 + ey * 360) - (sd + sm * 30 + sy * 360)) / 360; + case 1: + // Actual/actual + var feb29Between = function(date1, date2) { + var year1 = date1.getFullYear(); + var mar1year1 = new Date(year1, 2, 1); + if (isLeapYear(year1) && date1 < mar1year1 && date2 >= mar1year1) { + return true; + } + var year2 = date2.getFullYear(); + var mar1year2 = new Date(year2, 2, 1); + return (isLeapYear(year2) && date2 >= mar1year2 && date1 < mar1year2); + }; + var ylength = 365; + if (sy === ey || ((sy + 1) === ey) && ((sm > em) || ((sm === em) && (sd >= ed)))) { + if ((sy === ey && isLeapYear(sy)) || + feb29Between(start_date, end_date) || + (em === 1 && ed === 29)) { + ylength = 366; + } + return daysBetween(start_date, end_date) / ylength; + } + var years = (ey - sy) + 1; + var days = (new Date(ey + 1, 0, 1) - new Date(sy, 0, 1)) / 1000 / 60 / 60 / 24; + var average = days / years; + return daysBetween(start_date, end_date) / average; + case 2: + // Actual/360 + return daysBetween(start_date, end_date) / 360; + case 3: + // Actual/365 + return daysBetween(start_date, end_date) / 365; + case 4: + // European 30/360 + return ((ed + em * 30 + ey * 360) - (sd + sm * 30 + sy * 360)) / 360; } - return result; }; - exports.EXPON = {}; - - exports.EXPON.DIST = function(x, lambda, cumulative) { - x = utils.parseNumber(x); - lambda = utils.parseNumber(lambda); - if (utils.anyIsError(x, lambda)) { - return error.value; - } - return (cumulative) ? jStat.exponential.cdf(x, lambda) : jStat.exponential.pdf(x, lambda); - }; + function serial(date) { + var addOn = (date > -2203891200000)?2:1; + return (date - d1900) / 86400000 + addOn; + } - exports.F = {}; +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { - exports.F.DIST = function(x, d1, d2, cumulative) { - x = utils.parseNumber(x); - d1 = utils.parseNumber(d1); - d2 = utils.parseNumber(d2); - if (utils.anyIsError(x, d1, d2)) { - return error.value; - } - return (cumulative) ? jStat.centralF.cdf(x, d1, d2) : jStat.centralF.pdf(x, d1, d2); - }; + var error = __webpack_require__(5); + var stats = __webpack_require__(6); + var maths = __webpack_require__(2); + var utils = __webpack_require__(4); - exports.F.DIST.RT = function(x, d1, d2) { - if (arguments.length !== 3) { - return error.na; + function compact(array) { + if (!array) { return array; } + var result = []; + for (var i = 0; i < array.length; ++i) { + if (!array[i]) { continue; } + result.push(array[i]); } + return result; + } - if (x < 0 || d1 < 1 || d2 < 1) { - return error.num; + exports.FINDFIELD = function(database, title) { + var index = null; + for (var i = 0; i < database.length; i++) { + if (database[i][0] === title) { + index = i; + break; + } } - if ((typeof x !== 'number') || (typeof d1 !== 'number') || (typeof d2 !== 'number')) { + // Return error if the input field title is incorrect + if (index == null) { return error.value; } - - return 1 - jStat.centralF.cdf(x, d1, d2); + return index; }; - exports.F.INV = function(probability, d1, d2) { - probability = utils.parseNumber(probability); - d1 = utils.parseNumber(d1); - d2 = utils.parseNumber(d2); - if (utils.anyIsError(probability, d1, d2)) { - return error.value; + function findResultIndex(database, criterias) { + var matches = {}; + for (var i = 1; i < database[0].length; ++i) { + matches[i] = true; } - if (probability <= 0.0 || probability > 1.0) { - return error.num; + var maxCriteriaLength = criterias[0].length; + for (i = 1; i < criterias.length; ++i) { + if (criterias[i].length > maxCriteriaLength) { + maxCriteriaLength = criterias[i].length; + } } - return jStat.centralF.inv(probability, d1, d2); - }; + for (var k = 1; k < database.length; ++k) { + for (var l = 1; l < database[k].length; ++l) { + var currentCriteriaResult = false; + var hasMatchingCriteria = false; + for (var j = 0; j < criterias.length; ++j) { + var criteria = criterias[j]; + if (criteria.length < maxCriteriaLength) { + continue; + } - exports.F.INV.RT = function(p, d1, d2) { - if (arguments.length !== 3) { - return error.na; + var criteriaField = criteria[0]; + if (database[k][0] !== criteriaField) { + continue; + } + hasMatchingCriteria = true; + for (var p = 1; p < criteria.length; ++p) { + currentCriteriaResult = currentCriteriaResult || eval(database[k][l] + criteria[p]); // jshint ignore:line + } + } + if (hasMatchingCriteria) { + matches[l] = matches[l] && currentCriteriaResult; + } + } } - if (p < 0 || p > 1 || d1 < 1 || d1 > Math.pow(10, 10) || d2 < 1 || d2 > Math.pow(10, 10)) { - return error.num; + var result = []; + for (var n = 0; n < database[0].length; ++n) { + if (matches[n]) { + result.push(n - 1); + } } + return result; + } - if ((typeof p !== 'number') || (typeof d1 !== 'number') || (typeof d2 !== 'number')) { + // Database functions + exports.DAVERAGE = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { return error.value; } - - return jStat.centralF.inv(1.0 - p, d1, d2); - }; - - exports.F.TEST = function(array1, array2) { - if (!array1 || !array2) { - return error.na; - } - - if (!(array1 instanceof Array) || !(array2 instanceof Array)) { - return error.na; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - - if (array1.length < 2 || array2.length < 2) { - return error.div0; + var sum = 0; + for (var i = 0; i < resultIndexes.length; i++) { + sum += targetFields[resultIndexes[i]]; } - - var sumOfSquares = function(values, x1) { - var sum = 0; - for (var i = 0; i < values.length; i++) { - sum +=Math.pow((values[i] - x1), 2); - } - return sum; - }; - - var x1 = mathTrig.SUM(array1) / array1.length; - var x2 = mathTrig.SUM(array2) / array2.length; - var sum1 = sumOfSquares(array1, x1) / (array1.length - 1); - var sum2 = sumOfSquares(array2, x2) / (array2.length - 1); - - return sum1 / sum2; + return resultIndexes.length === 0 ? error.div0 : sum / resultIndexes.length; }; - exports.FISHER = function(x) { - x = utils.parseNumber(x); - if (x instanceof Error) { - return x; + exports.DCOUNT = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; } - return Math.log((1 + x) / (1 - x)) / 2; - }; - - exports.FISHERINV = function(y) { - y = utils.parseNumber(y); - if (y instanceof Error) { - return y; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - var e2y = Math.exp(2 * y); - return (e2y - 1) / (e2y + 1); + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; + } + return stats.COUNT(targetValues); }; - exports.FORECAST = function(x, data_y, data_x) { - x = utils.parseNumber(x); - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - if (utils.anyIsError(x, data_y, data_x)) { + exports.DCOUNTA = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { return error.value; } - var xmean = jStat.mean(data_x); - var ymean = jStat.mean(data_y); - var n = data_x.length; - var num = 0; - var den = 0; - for (var i = 0; i < n; i++) { - num += (data_x[i] - xmean) * (data_y[i] - ymean); - den += Math.pow(data_x[i] - xmean, 2); + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - var b = num / den; - var a = ymean - b * xmean; - return a + b * x; + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; + } + return stats.COUNTA(targetValues); }; - exports.FREQUENCY = function(data, bins) { - data = utils.parseNumberArray(utils.flatten(data)); - bins = utils.parseNumberArray(utils.flatten(bins)); - if (utils.anyIsError(data, bins)) { + exports.DGET = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { return error.value; } - var n = data.length; - var b = bins.length; - var r = []; - for (var i = 0; i <= b; i++) { - r[i] = 0; - for (var j = 0; j < n; j++) { - if (i === 0) { - if (data[j] <= bins[0]) { - r[0] += 1; - } - } else if (i < b) { - if (data[j] > bins[i - 1] && data[j] <= bins[i]) { - r[i] += 1; - } - } else if (i === b) { - if (data[j] > bins[b - 1]) { - r[b] += 1; - } - } - } - } - return r; - }; - - - exports.GAMMA = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - - if (number === 0) { - return error.num; + // Return error if no record meets the criteria + if (resultIndexes.length === 0) { + return error.value; } - - if (parseInt(number, 10) === number && number < 0) { + // Returns the #NUM! error value because more than one record meets the + // criteria + if (resultIndexes.length > 1) { return error.num; } - return jStat.gammafn(number); + return targetFields[resultIndexes[0]]; }; - exports.GAMMA.DIST = function(value, alpha, beta, cumulative) { - if (arguments.length !== 4) { - return error.na; - } - - if (value < 0 || alpha <= 0 || beta <= 0) { + exports.DMAX = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { return error.value; } - - if ((typeof value !== 'number') || (typeof alpha !== 'number') || (typeof beta !== 'number')) { - return error.value; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - - return cumulative ? jStat.gamma.cdf(value, alpha, beta, true) : jStat.gamma.pdf(value, alpha, beta, false); + var maxValue = targetFields[resultIndexes[0]]; + for (var i = 1; i < resultIndexes.length; i++) { + if (maxValue < targetFields[resultIndexes[i]]) { + maxValue = targetFields[resultIndexes[i]]; + } + } + return maxValue; }; - exports.GAMMA.INV = function(probability, alpha, beta) { - if (arguments.length !== 3) { - return error.na; + exports.DMIN = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; } - - if (probability < 0 || probability > 1 || alpha <= 0 || beta <= 0) { - return error.num; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - - if ((typeof probability !== 'number') || (typeof alpha !== 'number') || (typeof beta !== 'number')) { - return error.value; + var minValue = targetFields[resultIndexes[0]]; + for (var i = 1; i < resultIndexes.length; i++) { + if (minValue > targetFields[resultIndexes[i]]) { + minValue = targetFields[resultIndexes[i]]; + } } - - return jStat.gamma.inv(probability, alpha, beta); + return minValue; }; - exports.GAMMALN = function(number) { - number = utils.parseNumber(number); - if (number instanceof Error) { - return number; + exports.DPRODUCT = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; } - return jStat.gammaln(number); - }; - - exports.GAMMALN.PRECISE = function(x) { - if (arguments.length !== 1) { - return error.na; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - - if (x <= 0) { - return error.num; + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; } - - if (typeof x !== 'number') { - return error.value; + targetValues = compact(targetValues); + var result = 1; + for (i = 0; i < targetValues.length; i++) { + result *= targetValues[i]; } - - return jStat.gammaln(x); + return result; }; - exports.GAUSS = function(z) { - z = utils.parseNumber(z); - if (z instanceof Error) { - return z; + exports.DSTDEV = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; } - return jStat.normal.cdf(z, 0, 1) - 0.5; - }; - - exports.GEOMEAN = function() { - var args = utils.parseNumberArray(utils.flatten(arguments)); - if (args instanceof Error) { - return args; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - return jStat.geomean(args); + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; + } + targetValues = compact(targetValues); + return stats.STDEV.S(targetValues); }; - exports.GROWTH = function(known_y, known_x, new_x, use_const) { - // Credits: Ilmari Karonen (http://stackoverflow.com/questions/14161990/how-to-implement-growth-function-in-javascript) - - known_y = utils.parseNumberArray(known_y); - if (known_y instanceof Error) { - return known_y; + exports.DSTDEVP = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; } - - // Default values for optional parameters: - var i; - if (known_x === undefined) { - known_x = []; - for (i = 1; i <= known_y.length; i++) { - known_x.push(i); - } + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - if (new_x === undefined) { - new_x = []; - for (i = 1; i <= known_y.length; i++) { - new_x.push(i); - } + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; } + targetValues = compact(targetValues); + return stats.STDEV.P(targetValues); + }; - known_x = utils.parseNumberArray(known_x); - new_x = utils.parseNumberArray(new_x); - if (utils.anyIsError(known_x, new_x)) { + exports.DSUM = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { return error.value; } - - - if (use_const === undefined) { - use_const = true; + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - - // Calculate sums over the data: - var n = known_y.length; - var avg_x = 0; - var avg_y = 0; - var avg_xy = 0; - var avg_xx = 0; - for (i = 0; i < n; i++) { - var x = known_x[i]; - var y = Math.log(known_y[i]); - avg_x += x; - avg_y += y; - avg_xy += x * y; - avg_xx += x * x; + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; } - avg_x /= n; - avg_y /= n; - avg_xy /= n; - avg_xx /= n; + return maths.SUM(targetValues); + }; - // Compute linear regression coefficients: - var beta; - var alpha; - if (use_const) { - beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x); - alpha = avg_y - beta * avg_x; + exports.DVAR = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; + } + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); } else { - beta = avg_xy / avg_xx; - alpha = 0; + targetFields = utils.rest(database[field]); } - - // Compute and return result array: - var new_y = []; - for (i = 0; i < new_x.length; i++) { - new_y.push(Math.exp(alpha + beta * new_x[i])); + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; } - return new_y; + return stats.VAR.S(targetValues); }; - exports.HARMEAN = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; + exports.DVARP = function(database, field, criteria) { + // Return error if field is not a number and not a string + if (isNaN(field) && (typeof field !== "string")) { + return error.value; + } + var resultIndexes = findResultIndex(database, criteria); + var targetFields = []; + if (typeof field === "string") { + var index = exports.FINDFIELD(database, field); + targetFields = utils.rest(database[index]); + } else { + targetFields = utils.rest(database[field]); } - var n = range.length; - var den = 0; - for (var i = 0; i < n; i++) { - den += 1 / range[i]; + var targetValues = []; + for (var i = 0; i < resultIndexes.length; i++) { + targetValues[i] = targetFields[resultIndexes[i]]; } - return n / den; + return stats.VAR.P(targetValues); }; - exports.HYPGEOM = {}; - exports.HYPGEOM.DIST = function(x, n, M, N, cumulative) { - x = utils.parseNumber(x); - n = utils.parseNumber(n); - M = utils.parseNumber(M); - N = utils.parseNumber(N); - if (utils.anyIsError(x, n, M, N)) { - return error.value; - } +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { - function pdf(x, n, M, N) { - return mathTrig.COMBIN(M, x) * mathTrig.COMBIN(N - M, n - x) / mathTrig.COMBIN(N, n); - } + var error = __webpack_require__(5); + var utils = __webpack_require__(4); + var information = __webpack_require__(11); - function cdf(x, n, M, N) { - var result = 0; - for (var i = 0; i <= x; i++) { - result += pdf(i, n, M, N); + exports.AND = function() { + var args = utils.flatten(arguments); + var result = true; + for (var i = 0; i < args.length; i++) { + if (!args[i]) { + result = false; } - return result; } - - return (cumulative) ? cdf(x, n, M, N) : pdf(x, n, M, N); + return result; }; - exports.INTERCEPT = function(known_y, known_x) { - known_y = utils.parseNumberArray(known_y); - known_x = utils.parseNumberArray(known_x); - if (utils.anyIsError(known_y, known_x)) { - return error.value; - } - if (known_y.length !== known_x.length) { + exports.CHOOSE = function() { + if (arguments.length < 2) { return error.na; } - return exports.FORECAST(0, known_y, known_x); - }; - exports.KURT = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; + var index = arguments[0]; + if (index < 1 || index > 254) { + return error.value; } - var mean = jStat.mean(range); - var n = range.length; - var sigma = 0; - for (var i = 0; i < n; i++) { - sigma += Math.pow(range[i] - mean, 4); + + if (arguments.length < index + 1) { + return error.value; } - sigma = sigma / Math.pow(jStat.stdev(range, true), 4); - return ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sigma - 3 * (n - 1) * (n - 1) / ((n - 2) * (n - 3)); + + return arguments[index]; }; - exports.LARGE = function(range, k) { - range = utils.parseNumberArray(utils.flatten(range)); - k = utils.parseNumber(k); - if (utils.anyIsError(range, k)) { - return range; - } - return range.sort(function(a, b) { - return b - a; - })[k - 1]; + exports.FALSE = function() { + return false; }; - exports.LINEST = function(data_y, data_x) { - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - if (utils.anyIsError(data_y, data_x)) { - return error.value; - } - var ymean = jStat.mean(data_y); - var xmean = jStat.mean(data_x); - var n = data_x.length; - var num = 0; - var den = 0; - for (var i = 0; i < n; i++) { - num += (data_x[i] - xmean) * (data_y[i] - ymean); - den += Math.pow(data_x[i] - xmean, 2); - } - var m = num / den; - var b = ymean - m * xmean; - return [m, b]; + exports.IF = function(test, then_value, otherwise_value) { + return test ? then_value : otherwise_value; }; - // According to Microsoft: - // http://office.microsoft.com/en-us/starter-help/logest-function-HP010342665.aspx - // LOGEST returns are based on the following linear model: - // ln y = x1 ln m1 + ... + xn ln mn + ln b - exports.LOGEST = function(data_y, data_x) { - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - if (utils.anyIsError(data_y, data_x)) { - return error.value; - } - for (var i = 0; i < data_y.length; i ++) { - data_y[i] = Math.log(data_y[i]); + exports.IFERROR = function(value, valueIfError) { + if (information.ISERROR(value)) { + return valueIfError; } - - var result = exports.LINEST(data_y, data_x); - result[0] = Math.round(Math.exp(result[0])*1000000)/1000000; - result[1] = Math.round(Math.exp(result[1])*1000000)/1000000; - return result; + return value; }; - exports.LOGNORM = {}; + exports.IFNA = function(value, value_if_na) { + return value === error.na ? value_if_na : value; + }; - exports.LOGNORM.DIST = function(x, mean, sd, cumulative) { - x = utils.parseNumber(x); - mean = utils.parseNumber(mean); - sd = utils.parseNumber(sd); - if (utils.anyIsError(x, mean, sd)) { - return error.value; - } - return (cumulative) ? jStat.lognormal.cdf(x, mean, sd) : jStat.lognormal.pdf(x, mean, sd); + exports.NOT = function(logical) { + return !logical; }; - exports.LOGNORM.INV = function(probability, mean, sd) { - probability = utils.parseNumber(probability); - mean = utils.parseNumber(mean); - sd = utils.parseNumber(sd); - if (utils.anyIsError(probability, mean, sd)) { - return error.value; + exports.OR = function() { + var args = utils.flatten(arguments); + var result = false; + for (var i = 0; i < args.length; i++) { + if (args[i]) { + result = true; + } } - return jStat.lognormal.inv(probability, mean, sd); + return result; }; - exports.MAX = function() { - var range = utils.numbers(utils.flatten(arguments)); - return (range.length === 0) ? 0 : Math.max.apply(Math, range); + exports.TRUE = function() { + return true; }; - exports.MAXA = function() { - var range = utils.arrayValuesToNumbers(utils.flatten(arguments)); - return (range.length === 0) ? 0 : Math.max.apply(Math, range); + exports.XOR = function() { + var args = utils.flatten(arguments); + var result = 0; + for (var i = 0; i < args.length; i++) { + if (args[i]) { + result++; + } + } + return (Math.floor(Math.abs(result)) & 1) ? true : false; }; - exports.MEDIAN = function() { - var range = utils.arrayValuesToNumbers(utils.flatten(arguments)); - return jStat.median(range); - }; + exports.SWITCH = function () { + var result; + if (arguments.length > 0) { + var targetValue = arguments[0]; + var argc = arguments.length - 1; + var switchCount = Math.floor(argc / 2); + var switchSatisfied = false; + var defaultClause = argc % 2 === 0 ? null : arguments[arguments.length - 1]; - exports.MIN = function() { - var range = utils.numbers(utils.flatten(arguments)); - return (range.length === 0) ? 0 : Math.min.apply(Math, range); - }; + if (switchCount) { + for (var index = 0; index < switchCount; index++) { + if (targetValue === arguments[index * 2 + 1]) { + result = arguments[index * 2 + 2]; + switchSatisfied = true; + break; + } + } + } - exports.MINA = function() { - var range = utils.arrayValuesToNumbers(utils.flatten(arguments)); - return (range.length === 0) ? 0 : Math.min.apply(Math, range); + if (!switchSatisfied && defaultClause) { + result = defaultClause; + } + } + + return result; }; - exports.MODE = {}; - exports.MODE.MULT = function() { - // Credits: Roönaän - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + + var error = __webpack_require__(5); + var dateTime = __webpack_require__(14); + var utils = __webpack_require__(4); + + function validDate(d) { + return d && d.getTime && !isNaN(d.getTime()); + } + + function ensureDate(d) { + return (d instanceof Date)?d:new Date(d); + } + + exports.ACCRINT = function(issue, first, settlement, rate, par, frequency, basis) { + // Return error if either date is invalid + issue = ensureDate(issue); + first = ensureDate(first); + settlement = ensureDate(settlement); + if (!validDate(issue) || !validDate(first) || !validDate(settlement)) { + return '#VALUE!'; } - var n = range.length; - var count = {}; - var maxItems = []; - var max = 0; - var currentItem; - for (var i = 0; i < n; i++) { - currentItem = range[i]; - count[currentItem] = count[currentItem] ? count[currentItem] + 1 : 1; - if (count[currentItem] > max) { - max = count[currentItem]; - maxItems = []; - } - if (count[currentItem] === max) { - maxItems[maxItems.length] = currentItem; - } + // Return error if either rate or par are lower than or equal to zero + if (rate <= 0 || par <= 0) { + return '#NUM!'; + } + + // Return error if frequency is neither 1, 2, or 4 + if ([1, 2, 4].indexOf(frequency) === -1) { + return '#NUM!'; + } + + // Return error if basis is neither 0, 1, 2, 3, or 4 + if ([0, 1, 2, 3, 4].indexOf(basis) === -1) { + return '#NUM!'; + } + + // Return error if settlement is before or equal to issue + if (settlement <= issue) { + return '#NUM!'; } - return maxItems; + + // Set default values + par = par || 0; + basis = basis || 0; + + // Compute accrued interest + return par * rate * dateTime.YEARFRAC(issue, settlement, basis); }; - exports.MODE.SNGL = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; - } - return exports.MODE.MULT(range).sort(function(a, b) { - return a - b; - })[0]; + // TODO + exports.ACCRINTM = function() { + throw new Error('ACCRINTM is not implemented'); }; - exports.NEGBINOM = {}; + // TODO + exports.AMORDEGRC = function() { + throw new Error('AMORDEGRC is not implemented'); + }; - exports.NEGBINOM.DIST = function(k, r, p, cumulative) { - k = utils.parseNumber(k); - r = utils.parseNumber(r); - p = utils.parseNumber(p); - if (utils.anyIsError(k, r, p)) { - return error.value; - } - return (cumulative) ? jStat.negbin.cdf(k, r, p) : jStat.negbin.pdf(k, r, p); + // TODO + exports.AMORLINC = function() { + throw new Error('AMORLINC is not implemented'); }; - exports.NORM = {}; + // TODO + exports.COUPDAYBS = function() { + throw new Error('COUPDAYBS is not implemented'); + }; - exports.NORM.DIST = function(x, mean, sd, cumulative) { - x = utils.parseNumber(x); - mean = utils.parseNumber(mean); - sd = utils.parseNumber(sd); - if (utils.anyIsError(x, mean, sd)) { - return error.value; - } - if (sd <= 0) { - return error.num; - } + // TODO + exports.COUPDAYS = function() { + throw new Error('COUPDAYS is not implemented'); + }; - // Return normal distribution computed by jStat [http://jstat.org] - return (cumulative) ? jStat.normal.cdf(x, mean, sd) : jStat.normal.pdf(x, mean, sd); + // TODO + exports.COUPDAYSNC = function() { + throw new Error('COUPDAYSNC is not implemented'); }; - exports.NORM.INV = function(probability, mean, sd) { - probability = utils.parseNumber(probability); - mean = utils.parseNumber(mean); - sd = utils.parseNumber(sd); - if (utils.anyIsError(probability, mean, sd)) { - return error.value; - } - return jStat.normal.inv(probability, mean, sd); + // TODO + exports.COUPNCD = function() { + throw new Error('COUPNCD is not implemented'); }; - exports.NORM.S = {}; + // TODO + exports.COUPNUM = function() { + throw new Error('COUPNUM is not implemented'); + }; - exports.NORM.S.DIST = function(z, cumulative) { - z = utils.parseNumber(z); - if (z instanceof Error) { - return error.value; - } - return (cumulative) ? jStat.normal.cdf(z, 0, 1) : jStat.normal.pdf(z, 0, 1); + // TODO + exports.COUPPCD = function() { + throw new Error('COUPPCD is not implemented'); }; - exports.NORM.S.INV = function(probability) { - probability = utils.parseNumber(probability); - if (probability instanceof Error) { + exports.CUMIPMT = function(rate, periods, value, start, end, type) { + // Credits: algorithm inspired by Apache OpenOffice + // Credits: Hannes Stiebitzhofer for the translations of function and variable names + // Requires exports.FV() and exports.PMT() from exports.js [http://stoic.com/exports/] + + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + value = utils.parseNumber(value); + if (utils.anyIsError(rate, periods, value)) { return error.value; } - return jStat.normal.inv(probability, 0, 1); - }; - exports.PEARSON = function(data_x, data_y) { - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - if (utils.anyIsError(data_y, data_x)) { - return error.value; + // Return error if either rate, periods, or value are lower than or equal to zero + if (rate <= 0 || periods <= 0 || value <= 0) { + return error.num; } - var xmean = jStat.mean(data_x); - var ymean = jStat.mean(data_y); - var n = data_x.length; - var num = 0; - var den1 = 0; - var den2 = 0; - for (var i = 0; i < n; i++) { - num += (data_x[i] - xmean) * (data_y[i] - ymean); - den1 += Math.pow(data_x[i] - xmean, 2); - den2 += Math.pow(data_y[i] - ymean, 2); + + // Return error if start < 1, end < 1, or start > end + if (start < 1 || end < 1 || start > end) { + return error.num; } - return num / Math.sqrt(den1 * den2); - }; - exports.PERCENTILE = {}; + // Return error if type is neither 0 nor 1 + if (type !== 0 && type !== 1) { + return error.num; + } - exports.PERCENTILE.EXC = function(array, k) { - array = utils.parseNumberArray(utils.flatten(array)); - k = utils.parseNumber(k); - if (utils.anyIsError(array, k)) { - return error.value; + // Compute cumulative interest + var payment = exports.PMT(rate, periods, value, 0, type); + var interest = 0; + + if (start === 1) { + if (type === 0) { + interest = -value; + start++; + } } - array = array.sort(function(a, b) { - { - return a - b; + + for (var i = start; i <= end; i++) { + if (type === 1) { + interest += exports.FV(rate, i - 2, payment, value, 1) - payment; + } else { + interest += exports.FV(rate, i - 1, payment, value, 0); } - }); - var n = array.length; - if (k < 1 / (n + 1) || k > 1 - 1 / (n + 1)) { - return error.num; } - var l = k * (n + 1) - 1; - var fl = Math.floor(l); - return utils.cleanFloat((l === fl) ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl])); + interest *= rate; + + // Return cumulative interest + return interest; }; - exports.PERCENTILE.INC = function(array, k) { - array = utils.parseNumberArray(utils.flatten(array)); - k = utils.parseNumber(k); - if (utils.anyIsError(array, k)) { + exports.CUMPRINC = function(rate, periods, value, start, end, type) { + // Credits: algorithm inspired by Apache OpenOffice + // Credits: Hannes Stiebitzhofer for the translations of function and variable names + + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + value = utils.parseNumber(value); + if (utils.anyIsError(rate, periods, value)) { return error.value; } - array = array.sort(function(a, b) { - return a - b; - }); - var n = array.length; - var l = k * (n - 1); - var fl = Math.floor(l); - return utils.cleanFloat((l === fl) ? array[l] : array[fl] + (l - fl) * (array[fl + 1] - array[fl])); - }; - exports.PERCENTRANK = {}; + // Return error if either rate, periods, or value are lower than or equal to zero + if (rate <= 0 || periods <= 0 || value <= 0) { + return error.num; + } - exports.PERCENTRANK.EXC = function(array, x, significance) { - significance = (significance === undefined) ? 3 : significance; - array = utils.parseNumberArray(utils.flatten(array)); - x = utils.parseNumber(x); - significance = utils.parseNumber(significance); - if (utils.anyIsError(array, x, significance)) { - return error.value; + // Return error if start < 1, end < 1, or start > end + if (start < 1 || end < 1 || start > end) { + return error.num; } - array = array.sort(function(a, b) { - return a - b; - }); - var uniques = misc.UNIQUE.apply(null, array); - var n = array.length; - var m = uniques.length; - var power = Math.pow(10, significance); - var result = 0; - var match = false; - var i = 0; - while (!match && i < m) { - if (x === uniques[i]) { - result = (array.indexOf(uniques[i]) + 1) / (n + 1); - match = true; - } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) { - result = (array.indexOf(uniques[i]) + 1 + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n + 1); - match = true; - } - i++; + + // Return error if type is neither 0 nor 1 + if (type !== 0 && type !== 1) { + return error.num; } - return Math.floor(result * power) / power; - }; - exports.PERCENTRANK.INC = function(array, x, significance) { - significance = (significance === undefined) ? 3 : significance; - array = utils.parseNumberArray(utils.flatten(array)); - x = utils.parseNumber(x); - significance = utils.parseNumber(significance); - if (utils.anyIsError(array, x, significance)) { - return error.value; + // Compute cumulative principal + var payment = exports.PMT(rate, periods, value, 0, type); + var principal = 0; + if (start === 1) { + if (type === 0) { + principal = payment + value * rate; + } else { + principal = payment; + } + start++; } - array = array.sort(function(a, b) { - return a - b; - }); - var uniques = misc.UNIQUE.apply(null, array); - var n = array.length; - var m = uniques.length; - var power = Math.pow(10, significance); - var result = 0; - var match = false; - var i = 0; - while (!match && i < m) { - if (x === uniques[i]) { - result = array.indexOf(uniques[i]) / (n - 1); - match = true; - } else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) { - result = (array.indexOf(uniques[i]) + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n - 1); - match = true; + for (var i = start; i <= end; i++) { + if (type > 0) { + principal += payment - (exports.FV(rate, i - 2, payment, value, 1) - payment) * rate; + } else { + principal += payment - exports.FV(rate, i - 1, payment, value, 0) * rate; } - i++; } - return Math.floor(result * power) / power; - }; - exports.PERMUT = function(number, number_chosen) { - number = utils.parseNumber(number); - number_chosen = utils.parseNumber(number_chosen); - if (utils.anyIsError(number, number_chosen)) { - return error.value; - } - return mathTrig.FACT(number) / mathTrig.FACT(number - number_chosen); + // Return cumulative principal + return principal; }; - exports.PERMUTATIONA = function(number, number_chosen) { - number = utils.parseNumber(number); - number_chosen = utils.parseNumber(number_chosen); - if (utils.anyIsError(number, number_chosen)) { + exports.DB = function(cost, salvage, life, period, month) { + // Initialize month + month = (month === undefined) ? 12 : month; + + cost = utils.parseNumber(cost); + salvage = utils.parseNumber(salvage); + life = utils.parseNumber(life); + period = utils.parseNumber(period); + month = utils.parseNumber(month); + if (utils.anyIsError(cost, salvage, life, period, month)) { return error.value; } - return Math.pow(number, number_chosen); - }; - exports.PHI = function(x) { - x = utils.parseNumber(x); - if (x instanceof Error) { - return error.value; + // Return error if any of the parameters is negative + if (cost < 0 || salvage < 0 || life < 0 || period < 0) { + return error.num; } - return Math.exp(-0.5 * x * x) / SQRT2PI; - }; - exports.POISSON = {}; + // Return error if month is not an integer between 1 and 12 + if ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].indexOf(month) === -1) { + return error.num; + } - exports.POISSON.DIST = function(x, mean, cumulative) { - x = utils.parseNumber(x); - mean = utils.parseNumber(mean); - if (utils.anyIsError(x, mean)) { - return error.value; + // Return error if period is greater than life + if (period > life) { + return error.num; } - return (cumulative) ? jStat.poisson.cdf(x, mean) : jStat.poisson.pdf(x, mean); - }; - exports.PROB = function(range, probability, lower, upper) { - if (lower === undefined) { + // Return 0 (zero) if salvage is greater than or equal to cost + if (salvage >= cost) { return 0; } - upper = (upper === undefined) ? lower : upper; - range = utils.parseNumberArray(utils.flatten(range)); - probability = utils.parseNumberArray(utils.flatten(probability)); - lower = utils.parseNumber(lower); - upper = utils.parseNumber(upper); - if (utils.anyIsError(range, probability, lower, upper)) { - return error.value; - } + // Rate is rounded to three decimals places + var rate = (1 - Math.pow(salvage / cost, 1 / life)).toFixed(3); - if (lower === upper) { - return (range.indexOf(lower) >= 0) ? probability[range.indexOf(lower)] : 0; + // Compute initial depreciation + var initial = cost * rate * month / 12; + + // Compute total depreciation + var total = initial; + var current = 0; + var ceiling = (period === life) ? life - 1 : period; + for (var i = 2; i <= ceiling; i++) { + current = (cost - total) * rate; + total += current; } - var sorted = range.sort(function(a, b) { - return a - b; - }); - var n = sorted.length; - var result = 0; - for (var i = 0; i < n; i++) { - if (sorted[i] >= lower && sorted[i] <= upper) { - result += probability[range.indexOf(sorted[i])]; - } + // Depreciation for the first and last periods are special cases + if (period === 1) { + // First period + return initial; + } else if (period === life) { + // Last period + return (cost - total) * rate; + } else { + return current; } - return result; }; - exports.QUARTILE = {}; + exports.DDB = function(cost, salvage, life, period, factor) { + // Initialize factor + factor = (factor === undefined) ? 2 : factor; - exports.QUARTILE.EXC = function(range, quart) { - range = utils.parseNumberArray(utils.flatten(range)); - quart = utils.parseNumber(quart); - if (utils.anyIsError(range, quart)) { + cost = utils.parseNumber(cost); + salvage = utils.parseNumber(salvage); + life = utils.parseNumber(life); + period = utils.parseNumber(period); + factor = utils.parseNumber(factor); + if (utils.anyIsError(cost, salvage, life, period, factor)) { return error.value; } - switch (quart) { - case 1: - return exports.PERCENTILE.EXC(range, 0.25); - case 2: - return exports.PERCENTILE.EXC(range, 0.5); - case 3: - return exports.PERCENTILE.EXC(range, 0.75); - default: - return error.num; + + // Return error if any of the parameters is negative or if factor is null + if (cost < 0 || salvage < 0 || life < 0 || period < 0 || factor <= 0) { + return error.num; } - }; - exports.QUARTILE.INC = function(range, quart) { - range = utils.parseNumberArray(utils.flatten(range)); - quart = utils.parseNumber(quart); - if (utils.anyIsError(range, quart)) { - return error.value; + // Return error if period is greater than life + if (period > life) { + return error.num; } - switch (quart) { - case 1: - return exports.PERCENTILE.INC(range, 0.25); - case 2: - return exports.PERCENTILE.INC(range, 0.5); - case 3: - return exports.PERCENTILE.INC(range, 0.75); - default: - return error.num; + + // Return 0 (zero) if salvage is greater than or equal to cost + if (salvage >= cost) { + return 0; + } + + // Compute depreciation + var total = 0; + var current = 0; + for (var i = 1; i <= period; i++) { + current = Math.min((cost - total) * (factor / life), (cost - salvage - total)); + total += current; } + + // Return depreciation + return current; }; - exports.RANK = {}; + // TODO + exports.DISC = function() { + throw new Error('DISC is not implemented'); + }; - exports.RANK.AVG = function(number, range, order) { - number = utils.parseNumber(number); - range = utils.parseNumberArray(utils.flatten(range)); - if (utils.anyIsError(number, range)) { + exports.DOLLARDE = function(dollar, fraction) { + // Credits: algorithm inspired by Apache OpenOffice + + dollar = utils.parseNumber(dollar); + fraction = utils.parseNumber(fraction); + if (utils.anyIsError(dollar, fraction)) { return error.value; } - range = utils.flatten(range); - order = order || false; - var sort = (order) ? function(a, b) { - return a - b; - } : function(a, b) { - return b - a; - }; - range = range.sort(sort); - var length = range.length; - var count = 0; - for (var i = 0; i < length; i++) { - if (range[i] === number) { - count++; - } + // Return error if fraction is negative + if (fraction < 0) { + return error.num; } - return (count > 1) ? (2 * range.indexOf(number) + count + 1) / 2 : range.indexOf(number) + 1; - }; - - exports.RANK.EQ = function(number, range, order) { - number = utils.parseNumber(number); - range = utils.parseNumberArray(utils.flatten(range)); - if (utils.anyIsError(number, range)) { - return error.value; + // Return error if fraction is greater than or equal to 0 and less than 1 + if (fraction >= 0 && fraction < 1) { + return error.div0; } - order = order || false; - var sort = (order) ? function(a, b) { - return a - b; - } : function(a, b) { - return b - a; - }; - range = range.sort(sort); - return range.indexOf(number) + 1; + + // Truncate fraction if it is not an integer + fraction = parseInt(fraction, 10); + + // Compute integer part + var result = parseInt(dollar, 10); + + // Add decimal part + result += (dollar % 1) * Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN10)) / fraction; + + // Round result + var power = Math.pow(10, Math.ceil(Math.log(fraction) / Math.LN2) + 1); + result = Math.round(result * power) / power; + + // Return converted dollar price + return result; }; - exports.ROW = function(matrix, index) { - if (arguments.length !== 2) { - return error.na; + exports.DOLLARFR = function(dollar, fraction) { + // Credits: algorithm inspired by Apache OpenOffice + + dollar = utils.parseNumber(dollar); + fraction = utils.parseNumber(fraction); + if (utils.anyIsError(dollar, fraction)) { + return error.value; } - if (index < 0) { + // Return error if fraction is negative + if (fraction < 0) { return error.num; } - if (!(matrix instanceof Array) || (typeof index !== 'number')) { - return error.value; + // Return error if fraction is greater than or equal to 0 and less than 1 + if (fraction >= 0 && fraction < 1) { + return error.div0; } - if (matrix.length === 0) { - return undefined; - } + // Truncate fraction if it is not an integer + fraction = parseInt(fraction, 10); + + // Compute integer part + var result = parseInt(dollar, 10); + + // Add decimal part + result += (dollar % 1) * Math.pow(10, -Math.ceil(Math.log(fraction) / Math.LN10)) * fraction; - return jStat.row(matrix, index); + // Return converted dollar price + return result; }; - exports.ROWS = function(matrix) { - if (arguments.length !== 1) { - return error.na; - } + // TODO + exports.DURATION = function() { + throw new Error('DURATION is not implemented'); + }; - if (!(matrix instanceof Array)) { + exports.EFFECT = function(rate, periods) { + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + if (utils.anyIsError(rate, periods)) { return error.value; } - if (matrix.length === 0) { - return 0; + // Return error if rate <=0 or periods < 1 + if (rate <= 0 || periods < 1) { + return error.num; } - return jStat.rows(matrix); - }; + // Truncate periods if it is not an integer + periods = parseInt(periods, 10); - exports.RSQ = function(data_x, data_y) { // no need to flatten here, PEARSON will take care of that - data_x = utils.parseNumberArray(utils.flatten(data_x)); - data_y = utils.parseNumberArray(utils.flatten(data_y)); - if (utils.anyIsError(data_x, data_y)) { - return error.value; - } - return Math.pow(exports.PEARSON(data_x, data_y), 2); + // Return effective annual interest rate + return Math.pow(1 + rate / periods, periods) - 1; }; - exports.SKEW = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; - } - var mean = jStat.mean(range); - var n = range.length; - var sigma = 0; - for (var i = 0; i < n; i++) { - sigma += Math.pow(range[i] - mean, 3); - } - return n * sigma / ((n - 1) * (n - 2) * Math.pow(jStat.stdev(range, true), 3)); - }; + exports.FV = function(rate, periods, payment, value, type) { + // Credits: algorithm inspired by Apache OpenOffice - exports.SKEW.P = function() { - var range = utils.parseNumberArray(utils.flatten(arguments)); - if (range instanceof Error) { - return range; - } - var mean = jStat.mean(range); - var n = range.length; - var m2 = 0; - var m3 = 0; - for (var i = 0; i < n; i++) { - m3 += Math.pow(range[i] - mean, 3); - m2 += Math.pow(range[i] - mean, 2); - } - m3 = m3 / n; - m2 = m2 / n; - return m3 / Math.pow(m2, 3 / 2); - }; + value = value || 0; + type = type || 0; - exports.SLOPE = function(data_y, data_x) { - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - if (utils.anyIsError(data_y, data_x)) { + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + payment = utils.parseNumber(payment); + value = utils.parseNumber(value); + type = utils.parseNumber(type); + if (utils.anyIsError(rate, periods, payment, value, type)) { return error.value; } - var xmean = jStat.mean(data_x); - var ymean = jStat.mean(data_y); - var n = data_x.length; - var num = 0; - var den = 0; - for (var i = 0; i < n; i++) { - num += (data_x[i] - xmean) * (data_y[i] - ymean); - den += Math.pow(data_x[i] - xmean, 2); - } - return num / den; - }; - exports.SMALL = function(range, k) { - range = utils.parseNumberArray(utils.flatten(range)); - k = utils.parseNumber(k); - if (utils.anyIsError(range, k)) { - return range; + // Return future value + var result; + if (rate === 0) { + result = value + payment * periods; + } else { + var term = Math.pow(1 + rate, periods); + if (type === 1) { + result = value * term + payment * (1 + rate) * (term - 1) / rate; + } else { + result = value * term + payment * (term - 1) / rate; + } } - return range.sort(function(a, b) { - return a - b; - })[k - 1]; + return -result; }; - exports.STANDARDIZE = function(x, mean, sd) { - x = utils.parseNumber(x); - mean = utils.parseNumber(mean); - sd = utils.parseNumber(sd); - if (utils.anyIsError(x, mean, sd)) { + exports.FVSCHEDULE = function(principal, schedule) { + principal = utils.parseNumber(principal); + schedule = utils.parseNumberArray(utils.flatten(schedule)); + if (utils.anyIsError(principal, schedule)) { return error.value; } - return (x - mean) / sd; - }; - exports.STDEV = {}; + var n = schedule.length; + var future = principal; - exports.STDEV.P = function() { - var v = exports.VAR.P.apply(this, arguments); - return Math.sqrt(v); - }; + // Apply all interests in schedule + for (var i = 0; i < n; i++) { + // Apply scheduled interest + future *= 1 + schedule[i]; + } - exports.STDEV.S = function() { - var v = exports.VAR.S.apply(this, arguments); - return Math.sqrt(v); + // Return future value + return future; }; - exports.STDEVA = function() { - var v = exports.VARA.apply(this, arguments); - return Math.sqrt(v); + // TODO + exports.INTRATE = function() { + throw new Error('INTRATE is not implemented'); }; - exports.STDEVPA = function() { - var v = exports.VARPA.apply(this, arguments); - return Math.sqrt(v); - }; + exports.IPMT = function(rate, period, periods, present, future, type) { + // Credits: algorithm inspired by Apache OpenOffice + future = future || 0; + type = type || 0; - exports.STEYX = function(data_y, data_x) { - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - if (utils.anyIsError(data_y, data_x)) { + rate = utils.parseNumber(rate); + period = utils.parseNumber(period); + periods = utils.parseNumber(periods); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + type = utils.parseNumber(type); + if (utils.anyIsError(rate, period, periods, present, future, type)) { return error.value; } - var xmean = jStat.mean(data_x); - var ymean = jStat.mean(data_y); - var n = data_x.length; - var lft = 0; - var num = 0; - var den = 0; - for (var i = 0; i < n; i++) { - lft += Math.pow(data_y[i] - ymean, 2); - num += (data_x[i] - xmean) * (data_y[i] - ymean); - den += Math.pow(data_x[i] - xmean, 2); - } - return Math.sqrt((lft - num * num / den) / (n - 2)); - }; - - exports.TRANSPOSE = function(matrix) { - if (!matrix) { - return error.na; - } - return jStat.transpose(matrix); - }; - exports.T = text.T; + // Compute payment + var payment = exports.PMT(rate, periods, present, future, type); - exports.T.DIST = function(x, df, cumulative) { - x = utils.parseNumber(x); - df = utils.parseNumber(df); - if (utils.anyIsError(x, df)) { - return error.value; + // Compute interest + var interest; + if (period === 1) { + if (type === 1) { + interest = 0; + } else { + interest = -present; + } + } else { + if (type === 1) { + interest = exports.FV(rate, period - 2, payment, present, 1) - payment; + } else { + interest = exports.FV(rate, period - 1, payment, present, 0); + } } - return (cumulative) ? jStat.studentt.cdf(x, df) : jStat.studentt.pdf(x, df); + + // Return interest + return interest * rate; }; - exports.T.DIST['2T'] = function(x, df) { - if (arguments.length !== 2) { - return error.na; - } + exports.IRR = function(values, guess) { + // Credits: algorithm inspired by Apache OpenOffice - if (x < 0 || df < 1) { - return error.num; - } + guess = guess || 0; - if ((typeof x !== 'number') || (typeof df !== 'number')) { + values = utils.parseNumberArray(utils.flatten(values)); + guess = utils.parseNumber(guess); + if (utils.anyIsError(values, guess)) { return error.value; } - return (1 - jStat.studentt.cdf(x , df)) * 2; - }; + // Calculates the resulting amount + var irrResult = function(values, dates, rate) { + var r = rate + 1; + var result = values[0]; + for (var i = 1; i < values.length; i++) { + result += values[i] / Math.pow(r, (dates[i] - dates[0]) / 365); + } + return result; + }; - exports.T.DIST.RT = function(x, df) { - if (arguments.length !== 2) { - return error.na; + // Calculates the first derivation + var irrResultDeriv = function(values, dates, rate) { + var r = rate + 1; + var result = 0; + for (var i = 1; i < values.length; i++) { + var frac = (dates[i] - dates[0]) / 365; + result -= frac * values[i] / Math.pow(r, frac + 1); + } + return result; + }; + + // Initialize dates and check that values contains at least one positive value and one negative value + var dates = []; + var positive = false; + var negative = false; + for (var i = 0; i < values.length; i++) { + dates[i] = (i === 0) ? 0 : dates[i - 1] + 365; + if (values[i] > 0) { + positive = true; + } + if (values[i] < 0) { + negative = true; + } } - if (x < 0 || df < 1) { + // Return error if values does not contain at least one positive value and one negative value + if (!positive || !negative) { return error.num; } - if ((typeof x !== 'number') || (typeof df !== 'number')) { - return error.value; - } + // Initialize guess and resultRate + guess = (guess === undefined) ? 0.1 : guess; + var resultRate = guess; - return 1 - jStat.studentt.cdf(x , df); + // Set maximum epsilon for end of iteration + var epsMax = 1e-10; + + // Implement Newton's method + var newRate, epsRate, resultValue; + var contLoop = true; + do { + resultValue = irrResult(values, dates, resultRate); + newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate); + epsRate = Math.abs(newRate - resultRate); + resultRate = newRate; + contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax); + } while (contLoop); + + // Return internal rate of return + return resultRate; }; - exports.T.INV = function(probability, df) { - probability = utils.parseNumber(probability); - df = utils.parseNumber(df); - if (utils.anyIsError(probability, df)) { + exports.ISPMT = function(rate, period, periods, value) { + rate = utils.parseNumber(rate); + period = utils.parseNumber(period); + periods = utils.parseNumber(periods); + value = utils.parseNumber(value); + if (utils.anyIsError(rate, period, periods, value)) { return error.value; } - return jStat.studentt.inv(probability, df); + + // Return interest + return value * rate * (period / periods - 1); }; - exports.T.INV['2T'] = function(probability, df) { - probability = utils.parseNumber(probability); - df = utils.parseNumber(df); - if (probability <= 0 || probability > 1 || df < 1) { - return error.num; - } - if (utils.anyIsError(probability, df)) { - return error.value; - } - return Math.abs(jStat.studentt.inv(probability/2, df)); + // TODO + exports.MDURATION = function() { + throw new Error('MDURATION is not implemented'); }; - // The algorithm can be found here: - // http://www.chem.uoa.gr/applets/AppletTtest/Appl_Ttest2.html - exports.T.TEST = function(data_x, data_y) { - data_x = utils.parseNumberArray(utils.flatten(data_x)); - data_y = utils.parseNumberArray(utils.flatten(data_y)); - if (utils.anyIsError(data_x, data_y)) { + exports.MIRR = function(values, finance_rate, reinvest_rate) { + values = utils.parseNumberArray(utils.flatten(values)); + finance_rate = utils.parseNumber(finance_rate); + reinvest_rate = utils.parseNumber(reinvest_rate); + if (utils.anyIsError(values, finance_rate, reinvest_rate)) { return error.value; } - var mean_x = jStat.mean(data_x); - var mean_y = jStat.mean(data_y); - var s_x = 0; - var s_y = 0; - var i; + // Initialize number of values + var n = values.length; - for (i = 0; i < data_x.length; i++) { - s_x += Math.pow(data_x[i] - mean_x, 2); - } - for (i = 0; i < data_y.length; i++) { - s_y += Math.pow(data_y[i] - mean_y, 2); + // Lookup payments (negative values) and incomes (positive values) + var payments = []; + var incomes = []; + for (var i = 0; i < n; i++) { + if (values[i] < 0) { + payments.push(values[i]); + } else { + incomes.push(values[i]); + } } - s_x = s_x / (data_x.length-1); - s_y = s_y / (data_y.length-1); - - var t = Math.abs(mean_x - mean_y) / Math.sqrt(s_x/data_x.length + s_y/data_y.length); - - return exports.T.DIST['2T'](t, data_x.length+data_y.length-2); + // Return modified internal rate of return + var num = -exports.NPV(reinvest_rate, incomes) * Math.pow(1 + reinvest_rate, n - 1); + var den = exports.NPV(finance_rate, payments) * (1 + finance_rate); + return Math.pow(num / den, 1 / (n - 1)) - 1; }; - exports.TREND = function(data_y, data_x, new_data_x) { - data_y = utils.parseNumberArray(utils.flatten(data_y)); - data_x = utils.parseNumberArray(utils.flatten(data_x)); - new_data_x = utils.parseNumberArray(utils.flatten(new_data_x)); - if (utils.anyIsError(data_y, data_x, new_data_x)) { + exports.NOMINAL = function(rate, periods) { + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + if (utils.anyIsError(rate, periods)) { return error.value; } - var linest = exports.LINEST(data_y, data_x); - var m = linest[0]; - var b = linest[1]; - var result = []; - new_data_x.forEach(function(x) { - result.push(m * x + b); - }); + // Return error if rate <=0 or periods < 1 + if (rate <= 0 || periods < 1) { + return error.num; + } - return result; - }; + // Truncate periods if it is not an integer + periods = parseInt(periods, 10); - exports.TRIMMEAN = function(range, percent) { - range = utils.parseNumberArray(utils.flatten(range)); - percent = utils.parseNumber(percent); - if (utils.anyIsError(range, percent)) { - return error.value; - } - var trim = mathTrig.FLOOR(range.length * percent, 2) / 2; - return jStat.mean(utils.initial(utils.rest(range.sort(function(a, b) { - return a - b; - }), trim), trim)); + // Return nominal annual interest rate + return (Math.pow(rate + 1, 1 / periods) - 1) * periods; }; - exports.VAR = {}; + exports.NPER = function(rate, payment, present, future, type) { + type = (type === undefined) ? 0 : type; + future = (future === undefined) ? 0 : future; - exports.VAR.P = function() { - var range = utils.numbers(utils.flatten(arguments)); - var n = range.length; - var sigma = 0; - var mean = exports.AVERAGE(range); - for (var i = 0; i < n; i++) { - sigma += Math.pow(range[i] - mean, 2); + rate = utils.parseNumber(rate); + payment = utils.parseNumber(payment); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + type = utils.parseNumber(type); + if (utils.anyIsError(rate, payment, present, future, type)) { + return error.value; } - return sigma / n; + + // Return number of periods + var num = payment * (1 + rate * type) - future * rate; + var den = (present * rate + payment * (1 + rate * type)); + return Math.log(num / den) / Math.log(1 + rate); }; - exports.VAR.S = function() { - var range = utils.numbers(utils.flatten(arguments)); - var n = range.length; - var sigma = 0; - var mean = exports.AVERAGE(range); - for (var i = 0; i < n; i++) { - sigma += Math.pow(range[i] - mean, 2); + exports.NPV = function() { + var args = utils.parseNumberArray(utils.flatten(arguments)); + if (args instanceof Error) { + return args; } - return sigma / (n - 1); - }; - exports.VARA = function() { - var range = utils.flatten(arguments); - var n = range.length; - var sigma = 0; - var count = 0; - var mean = exports.AVERAGEA(range); - for (var i = 0; i < n; i++) { - var el = range[i]; - if (typeof el === 'number') { - sigma += Math.pow(el - mean, 2); - } else if (el === true) { - sigma += Math.pow(1 - mean, 2); - } else { - sigma += Math.pow(0 - mean, 2); - } + // Lookup rate + var rate = args[0]; - if (el !== null) { - count++; - } + // Initialize net present value + var value = 0; + + // Loop on all values + for (var j = 1; j < args.length; j++) { + value += args[j] / Math.pow(1 + rate, j); } - return sigma / (count - 1); - }; - exports.VARPA = function() { - var range = utils.flatten(arguments); - var n = range.length; - var sigma = 0; - var count = 0; - var mean = exports.AVERAGEA(range); - for (var i = 0; i < n; i++) { - var el = range[i]; - if (typeof el === 'number') { - sigma += Math.pow(el - mean, 2); - } else if (el === true) { - sigma += Math.pow(1 - mean, 2); - } else { - sigma += Math.pow(0 - mean, 2); - } + // Return net present value + return value; + }; - if (el !== null) { - count++; - } - } - return sigma / count; + // TODO + exports.ODDFPRICE = function() { + throw new Error('ODDFPRICE is not implemented'); }; - exports.WEIBULL = {}; + // TODO + exports.ODDFYIELD = function() { + throw new Error('ODDFYIELD is not implemented'); + }; - exports.WEIBULL.DIST = function(x, alpha, beta, cumulative) { - x = utils.parseNumber(x); - alpha = utils.parseNumber(alpha); - beta = utils.parseNumber(beta); - if (utils.anyIsError(x, alpha, beta)) { - return error.value; - } - return (cumulative) ? 1 - Math.exp(-Math.pow(x / beta, alpha)) : Math.pow(x, alpha - 1) * Math.exp(-Math.pow(x / beta, alpha)) * alpha / Math.pow(beta, alpha); + // TODO + exports.ODDLPRICE = function() { + throw new Error('ODDLPRICE is not implemented'); }; - exports.Z = {}; + // TODO + exports.ODDLYIELD = function() { + throw new Error('ODDLYIELD is not implemented'); + }; - exports.Z.TEST = function(range, x, sd) { - range = utils.parseNumberArray(utils.flatten(range)); - x = utils.parseNumber(x); - if (utils.anyIsError(range, x)) { + exports.PDURATION = function(rate, present, future) { + rate = utils.parseNumber(rate); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + if (utils.anyIsError(rate, present, future)) { return error.value; } - sd = sd || exports.STDEV.S(range); - var n = range.length; - return 1 - exports.NORM.S.DIST((exports.AVERAGE(range) - x) / (sd / Math.sqrt(n)), true); - }; - + // Return error if rate <=0 + if (rate <= 0) { + return error.num; + } -/***/ }, -/* 12 */ -/***/ function(module, exports, __webpack_require__) { + // Return number of periods + return (Math.log(future) - Math.log(present)) / Math.log(1 + rate); + }; - var utils = __webpack_require__(17); - var numeral = __webpack_require__(15); + exports.PMT = function(rate, periods, present, future, type) { + // Credits: algorithm inspired by Apache OpenOffice - exports.UNIQUE = function () { - var result = []; - for (var i = 0; i < arguments.length; ++i) { - var hasElement = false; - var element = arguments[i]; + future = future || 0; + type = type || 0; - // Check if we've already seen this element. - for (var j = 0; j < result.length; ++j) { - hasElement = result[j] === element; - if (hasElement) { break; } - } + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + type = utils.parseNumber(type); + if (utils.anyIsError(rate, periods, present, future, type)) { + return error.value; + } - // If we did not find it, add it to the result. - if (!hasElement) { - result.push(element); + // Return payment + var result; + if (rate === 0) { + result = (present + future) / periods; + } else { + var term = Math.pow(1 + rate, periods); + if (type === 1) { + result = (future * rate / (term - 1) + present * rate / (1 - 1 / term)) / (1 + rate); + } else { + result = future * rate / (term - 1) + present * rate / (1 - 1 / term); } } - return result; + return -result; }; - exports.FLATTEN = utils.flatten; + exports.PPMT = function(rate, period, periods, present, future, type) { + future = future || 0; + type = type || 0; - exports.ARGS2ARRAY = function () { - return Array.prototype.slice.call(arguments, 0); - }; + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + type = utils.parseNumber(type); + if (utils.anyIsError(rate, periods, present, future, type)) { + return error.value; + } - exports.REFERENCE = function (context, reference) { - try { - var path = reference.split('.'); - var result = context; - for (var i = 0; i < path.length; ++i) { - var step = path[i]; - if (step[step.length - 1] === ']') { - var opening = step.indexOf('['); - var index = step.substring(opening + 1, step.length - 1); - result = result[step.substring(0, opening)][index]; - } else { - result = result[step]; - } - } - return result; - } catch (error) {} + return exports.PMT(rate, periods, present, future, type) - exports.IPMT(rate, period, periods, present, future, type); }; - exports.JOIN = function (array, separator) { - return array.join(separator); + // TODO + exports.PRICE = function() { + throw new Error('PRICE is not implemented'); }; - exports.NUMBERS = function () { - var possibleNumbers = utils.flatten(arguments); - return possibleNumbers.filter(function (el) { - return typeof el === 'number'; - }); + // TODO + exports.PRICEDISC = function() { + throw new Error('PRICEDISC is not implemented'); }; - exports.NUMERAL = function (number, format) { - return numeral(number).format(format); + // TODO + exports.PRICEMAT = function() { + throw new Error('PRICEMAT is not implemented'); }; -/***/ }, -/* 13 */ -/***/ function(module, exports, __webpack_require__) { - - module.exports = __WEBPACK_EXTERNAL_MODULE_13__; + exports.PV = function(rate, periods, payment, future, type) { + future = future || 0; + type = type || 0; -/***/ }, -/* 14 */ -/***/ function(module, exports, __webpack_require__) { + rate = utils.parseNumber(rate); + periods = utils.parseNumber(periods); + payment = utils.parseNumber(payment); + future = utils.parseNumber(future); + type = utils.parseNumber(type); + if (utils.anyIsError(rate, periods, payment, future, type)) { + return error.value; + } - module.exports = __WEBPACK_EXTERNAL_MODULE_14__; + // Return present value + if (rate === 0) { + return -payment * periods - future; + } else { + return (((1 - Math.pow(1 + rate, periods)) / rate) * payment * (1 + rate * type) - future) / Math.pow(1 + rate, periods); + } + }; -/***/ }, -/* 15 */ -/***/ function(module, exports, __webpack_require__) { + exports.RATE = function(periods, payment, present, future, type, guess) { + // Credits: rabugento - module.exports = __WEBPACK_EXTERNAL_MODULE_15__; + guess = (guess === undefined) ? 0.01 : guess; + future = (future === undefined) ? 0 : future; + type = (type === undefined) ? 0 : type; -/***/ }, -/* 16 */ -/***/ function(module, exports, __webpack_require__) { + periods = utils.parseNumber(periods); + payment = utils.parseNumber(payment); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + type = utils.parseNumber(type); + guess = utils.parseNumber(guess); + if (utils.anyIsError(periods, payment, present, future, type, guess)) { + return error.value; + } - exports.nil = new Error('#NULL!'); - exports.div0 = new Error('#DIV/0!'); - exports.value = new Error('#VALUE?'); - exports.ref = new Error('#REF!'); - exports.name = new Error('#NAME?'); - exports.num = new Error('#NUM!'); - exports.na = new Error('#N/A'); - exports.error = new Error('#ERROR!'); - exports.data = new Error('#GETTING_DATA'); + // Set maximum epsilon for end of iteration + var epsMax = 1e-6; + // Set maximum number of iterations + var iterMax = 100; + var iter = 0; + var close = false; + var rate = guess; -/***/ }, -/* 17 */ -/***/ function(module, exports, __webpack_require__) { + while (iter < iterMax && !close) { + var t1 = Math.pow(rate + 1, periods); + var t2 = Math.pow(rate + 1, periods - 1); - var error = __webpack_require__(16); + var f1 = future + t1 * present + payment * (t1 - 1) * (rate * type + 1) / rate; + var f2 = periods * t2 * present - payment * (t1 - 1) *(rate * type + 1) / Math.pow(rate,2); + var f3 = periods * payment * t2 * (rate * type + 1) / rate + payment * (t1 - 1) * type / rate; - function flattenShallow(array) { - if (!array || !array.reduce) { return array; } - return array.reduce(function(a, b) { - var aIsArray = Array.isArray(a); - var bIsArray = Array.isArray(b); - if (aIsArray && bIsArray ) { - return a.concat(b); - } - if (aIsArray) { - a.push(b); - return a; - } - if (bIsArray) { - return [a].concat(b); - } - return [a, b]; - }); - } + var newRate = rate - f1 / (f2 + f3); - function isFlat(array) { - if (!array) { return false; } - for (var i = 0; i < array.length; ++i) { - if (Array.isArray(array[i])) { - return false; - } + if (Math.abs(newRate - rate) < epsMax) close = true; + iter++ + rate = newRate; } - return true; - } - exports.flatten = function() { - var result = exports.argsToArray.apply(null, arguments); - while (!isFlat(result)) { - result = flattenShallow(result); - } - return result; + if (!close) return Number.NaN + rate; + return rate; }; - exports.argsToArray = function(args) { - return Array.prototype.slice.call(args, 0); + // TODO + exports.RECEIVED = function() { + throw new Error('RECEIVED is not implemented'); }; - exports.numbers = function() { - var possibleNumbers = this.flatten.apply(null, arguments); - return possibleNumbers.filter(function(el) { - return typeof el === 'number'; - }); - }; + exports.RRI = function(periods, present, future) { + periods = utils.parseNumber(periods); + present = utils.parseNumber(present); + future = utils.parseNumber(future); + if (utils.anyIsError(periods, present, future)) { + return error.value; + } - exports.cleanFloat = function(number) { - var power = 1e14; - return Math.round(number * power) / power; + // Return error if periods or present is equal to 0 (zero) + if (periods === 0 || present === 0) { + return error.num; + } + + // Return equivalent interest rate + return Math.pow(future / present, 1 / periods) - 1; }; - exports.parseBool = function(bool) { - if (typeof bool === 'boolean') { - return bool; + exports.SLN = function(cost, salvage, life) { + cost = utils.parseNumber(cost); + salvage = utils.parseNumber(salvage); + life = utils.parseNumber(life); + if (utils.anyIsError(cost, salvage, life)) { + return error.value; } - if (bool instanceof Error) { - return bool; + // Return error if life equal to 0 (zero) + if (life === 0) { + return error.num; } - if (typeof bool === 'number') { - return bool !== 0; - } + // Return straight-line depreciation + return (cost - salvage) / life; + }; - if (typeof bool === 'string') { - var up = bool.toUpperCase(); - if (up === 'TRUE') { - return true; - } + exports.SYD = function(cost, salvage, life, period) { + // Return error if any of the parameters is not a number + cost = utils.parseNumber(cost); + salvage = utils.parseNumber(salvage); + life = utils.parseNumber(life); + period = utils.parseNumber(period); + if (utils.anyIsError(cost, salvage, life, period)) { + return error.value; + } - if (up === 'FALSE') { - return false; - } + // Return error if life equal to 0 (zero) + if (life === 0) { + return error.num; } - if (bool instanceof Date && !isNaN(bool)) { - return true; + // Return error if period is lower than 1 or greater than life + if (period < 1 || period > life) { + return error.num; } - return error.value; + // Truncate period if it is not an integer + period = parseInt(period, 10); + + // Return straight-line depreciation + return ((cost - salvage) * (life - period + 1) * 2) / (life * (life + 1)); }; - exports.parseNumber = function(string) { - if (string === undefined || string === '') { + exports.TBILLEQ = function(settlement, maturity, discount) { + settlement = utils.parseDate(settlement); + maturity = utils.parseDate(maturity); + discount = utils.parseNumber(discount); + if (utils.anyIsError(settlement, maturity, discount)) { return error.value; } - if (!isNaN(string)) { - return parseFloat(string); + + // Return error if discount is lower than or equal to zero + if (discount <= 0) { + return error.num; } - return error.value; - }; - exports.parseNumberArray = function(arr) { - var len; - if (!arr || (len = arr.length) === 0) { - return error.value; + // Return error if settlement is greater than maturity + if (settlement > maturity) { + return error.num; } - var parsed; - while (len--) { - parsed = exports.parseNumber(arr[len]); - if (parsed === error.value) { - return parsed; - } - arr[len] = parsed; + + // Return error if maturity is more than one year after settlement + if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) { + return error.num; } - return arr; + + // Return bond-equivalent yield + return (365 * discount) / (360 - discount * dateTime.DAYS360(settlement, maturity, false)); }; - exports.parseMatrix = function(matrix) { - var n; - if (!matrix || (n = matrix.length) === 0) { + exports.TBILLPRICE = function(settlement, maturity, discount) { + settlement = utils.parseDate(settlement); + maturity = utils.parseDate(maturity); + discount = utils.parseNumber(discount); + if (utils.anyIsError(settlement, maturity, discount)) { return error.value; } - var pnarr; - for (var i = 0; i < matrix.length; i++) { - pnarr = exports.parseNumberArray(matrix[i]); - matrix[i] = pnarr; - if (pnarr instanceof Error) { - return pnarr; - } + + // Return error if discount is lower than or equal to zero + if (discount <= 0) { + return error.num; } - return matrix; - }; - var d1900 = new Date(1900, 0, 1); - exports.parseDate = function(date) { - if (!isNaN(date)) { - if (date instanceof Date) { - return new Date(date); - } - var d = parseInt(date, 10); - if (d < 0) { - return error.num; - } - if (d <= 60) { - return new Date(d1900.getTime() + (d - 1) * 86400000); - } - return new Date(d1900.getTime() + (d - 2) * 86400000); + // Return error if settlement is greater than maturity + if (settlement > maturity) { + return error.num; } - if (typeof date === 'string') { - date = new Date(date); - if (!isNaN(date)) { - return date; - } + + // Return error if maturity is more than one year after settlement + if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) { + return error.num; } - return error.value; + + // Return bond-equivalent yield + return 100 * (1 - discount * dateTime.DAYS360(settlement, maturity, false) / 360); }; - exports.parseDateArray = function(arr) { - var len = arr.length; - var parsed; - while (len--) { - parsed = this.parseDate(arr[len]); - if (parsed === error.value) { - return parsed; - } - arr[len] = parsed; + exports.TBILLYIELD = function(settlement, maturity, price) { + settlement = utils.parseDate(settlement); + maturity = utils.parseDate(maturity); + price = utils.parseNumber(price); + if (utils.anyIsError(settlement, maturity, price)) { + return error.value; } - return arr; - }; - exports.anyIsError = function() { - var n = arguments.length; - while (n--) { - if (arguments[n] instanceof Error) { - return true; - } + // Return error if price is lower than or equal to zero + if (price <= 0) { + return error.num; } - return false; - }; - exports.arrayValuesToNumbers = function(arr) { - var n = arr.length; - var el; - while (n--) { - el = arr[n]; - if (typeof el === 'number') { - continue; - } - if (el === true) { - arr[n] = 1; - continue; - } - if (el === false) { - arr[n] = 0; - continue; - } - if (typeof el === 'string') { - var number = this.parseNumber(el); - if (number instanceof Error) { - arr[n] = 0; - } else { - arr[n] = number; - } - } + // Return error if settlement is greater than maturity + if (settlement > maturity) { + return error.num; } - return arr; - }; - exports.rest = function(array, idx) { - idx = idx || 1; - if (!array || typeof array.slice !== 'function') { - return array; + // Return error if maturity is more than one year after settlement + if (maturity - settlement > 365 * 24 * 60 * 60 * 1000) { + return error.num; } - return array.slice(idx); + + // Return bond-equivalent yield + return (100 - price) * 360 / (price * dateTime.DAYS360(settlement, maturity, false)); }; - exports.initial = function(array, idx) { - idx = idx || 1; - if (!array || typeof array.slice !== 'function') { - return array; - } - return array.slice(0, array.length - idx); + // TODO + exports.VDB = function() { + throw new Error('VDB is not implemented'); }; -/***/ }, -/* 18 */ -/***/ function(module, exports, __webpack_require__) { - var M = Math; - function _horner(arr, v) { return arr.reduce(function(z,w){return v * z + w;},0); }; - function _bessel_iter(x, n, f0, f1, sign) { - if(!sign) sign = -1; - var tdx = 2 / x, f2; - if(n === 0) return f0; - if(n === 1) return f1; - for(var o = 1; o != n; ++o) { - f2 = f1 * o * tdx + sign * f0; - f0 = f1; f1 = f2; - } - return f1; - } - function _bessel_wrap(bessel0, bessel1, name, nonzero, sign) { - return function bessel(x,n) { - if(n === 0) return bessel0(x); - if(n === 1) return bessel1(x); - if(n < 0) throw name + ': Order (' + n + ') must be nonnegative'; - if(nonzero == 1 && x === 0) throw name + ': Undefined when x == 0'; - if(nonzero == 2 && x <= 0) throw name + ': Undefined when x <= 0'; - var b0 = bessel0(x), b1 = bessel1(x); - return _bessel_iter(x, n, b0, b1, sign); - }; - } - var besselj = (function() { - var b0_a1a = [57568490574.0,-13362590354.0,651619640.7,-11214424.18,77392.33017,-184.9052456].reverse(); - var b0_a2a = [57568490411.0,1029532985.0,9494680.718,59272.64853,267.8532712,1.0].reverse(); - var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse(); - var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934935152e-7].reverse(); - var W = 0.636619772; // 2 / Math.PI + exports.XIRR = function(values, dates, guess) { + // Credits: algorithm inspired by Apache OpenOffice - function bessel0(x) { - var a, a1, a2, y = x * x, xx = M.abs(x) - 0.785398164; - if(M.abs(x) < 8) { - a1 = _horner(b0_a1a, y); - a2 = _horner(b0_a2a, y); - a = a1/a2; - } - else { - y = 64 / y; - a1 = _horner(b0_a1b, y); - a2 = _horner(b0_a2b, y); - a = M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x)); - } - return a; - } - var b1_a1a = [72362614232.0,-7895059235.0,242396853.1,-2972611.439, 15704.48260, -30.16036606].reverse(); - var b1_a2a = [144725228442.0, 2300535178.0, 18583304.74, 99447.43394, 376.9991397, 1.0].reverse(); - var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse(); - var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse(); - function bessel1(x) { - var a, a1, a2, y = x*x, xx = M.abs(x) - 2.356194491; - if(Math.abs(x)< 8) { - a1 = x*_horner(b1_a1a, y); - a2 = _horner(b1_a2a, y); - a = a1 / a2; - } else { - y = 64 / y; - a1=_horner(b1_a1b, y); - a2=_horner(b1_a2b, y); - a=M.sqrt(W/M.abs(x))*(M.cos(xx)*a1-M.sin(xx)*a2*8/M.abs(x)); - if(x < 0) a = -a; - } - return a; + values = utils.parseNumberArray(utils.flatten(values)); + dates = utils.parseDateArray(utils.flatten(dates)); + guess = utils.parseNumber(guess); + if (utils.anyIsError(values, dates, guess)) { + return error.value; } - return function besselj(x, n) { - n = Math.round(n); - if(n === 0) return bessel0(M.abs(x)); - if(n === 1) return bessel1(M.abs(x)); - if(n < 0) throw 'BESSELJ: Order (' + n + ') must be nonnegative'; - if(M.abs(x) === 0) return 0; - var ret, j, tox = 2 / M.abs(x), m, jsum, sum, bjp, bj, bjm; - if(M.abs(x) > n) { - ret = _bessel_iter(x, n, bessel0(M.abs(x)), bessel1(M.abs(x)),-1); - } else { - m=2*M.floor((n+M.floor(M.sqrt(40*n)))/2); - jsum=0; - bjp=ret=sum=0.0; - bj=1.0; - for (j=m;j>0;j--) { - bjm=j*tox*bj-bjp; - bjp=bj; - bj=bjm; - if (M.abs(bj) > 1E10) { - bj *= 1E-10; - bjp *= 1E-10; - ret *= 1E-10; - sum *= 1E-10; - } - if (jsum) sum += bj; - jsum=!jsum; - if (j == n) ret=bjp; - } - sum=2.0*sum-bj; - ret /= sum; + // Calculates the resulting amount + var irrResult = function(values, dates, rate) { + var r = rate + 1; + var result = values[0]; + for (var i = 1; i < values.length; i++) { + result += values[i] / Math.pow(r, dateTime.DAYS(dates[i], dates[0]) / 365); } - return x < 0 && (n%2) ? -ret : ret; + return result; }; - })(); - var bessely = (function() { - var b0_a1a = [-2957821389.0, 7062834065.0, -512359803.6, 10879881.29, -86327.92757, 228.4622733].reverse(); - var b0_a2a = [40076544269.0, 745249964.8, 7189466.438, 47447.26470, 226.1030244, 1.0].reverse(); - var b0_a1b = [1.0, -0.1098628627e-2, 0.2734510407e-4, -0.2073370639e-5, 0.2093887211e-6].reverse(); - var b0_a2b = [-0.1562499995e-1, 0.1430488765e-3, -0.6911147651e-5, 0.7621095161e-6, -0.934945152e-7].reverse(); - var W = 0.636619772; - function bessel0(x) { - var a, a1, a2, y = x * x, xx = x - 0.785398164; - if(x < 8) { - a1 = _horner(b0_a1a, y); - a2 = _horner(b0_a2a, y); - a = a1/a2 + W * besselj(x,0) * M.log(x); - } else { - y = 64 / y; - a1 = _horner(b0_a1b, y); - a2 = _horner(b0_a2b, y); - a = M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x); + // Calculates the first derivation + var irrResultDeriv = function(values, dates, rate) { + var r = rate + 1; + var result = 0; + for (var i = 1; i < values.length; i++) { + var frac = dateTime.DAYS(dates[i], dates[0]) / 365; + result -= frac * values[i] / Math.pow(r, frac + 1); } - return a; - } + return result; + }; - var b1_a1a = [-0.4900604943e13, 0.1275274390e13, -0.5153438139e11, 0.7349264551e9, -0.4237922726e7, 0.8511937935e4].reverse(); - var b1_a2a = [0.2499580570e14, 0.4244419664e12, 0.3733650367e10, 0.2245904002e8, 0.1020426050e6, 0.3549632885e3, 1].reverse(); - var b1_a1b = [1.0, 0.183105e-2, -0.3516396496e-4, 0.2457520174e-5, -0.240337019e-6].reverse(); - var b1_a2b = [0.04687499995, -0.2002690873e-3, 0.8449199096e-5, -0.88228987e-6, 0.105787412e-6].reverse(); - function bessel1(x) { - var a, a1, a2, y = x*x, xx = x - 2.356194491; - if(x < 8) { - a1 = x*_horner(b1_a1a, y); - a2 = _horner(b1_a2a, y); - a = a1/a2 + W * (besselj(x,1) * M.log(x) - 1 / x); - } else { - y = 64 / y; - a1=_horner(b1_a1b, y); - a2=_horner(b1_a2b, y); - a=M.sqrt(W/x)*(M.sin(xx)*a1+M.cos(xx)*a2*8/x); + // Check that values contains at least one positive value and one negative value + var positive = false; + var negative = false; + for (var i = 0; i < values.length; i++) { + if (values[i] > 0) { + positive = true; + } + if (values[i] < 0) { + negative = true; } - return a; } - return _bessel_wrap(bessel0, bessel1, 'BESSELY', 1, -1); - })(); - var besseli = (function() { - var b0_a = [1.0, 3.5156229, 3.0899424, 1.2067492, 0.2659732, 0.360768e-1, 0.45813e-2].reverse(); - var b0_b = [0.39894228, 0.1328592e-1, 0.225319e-2, -0.157565e-2, 0.916281e-2, -0.2057706e-1, 0.2635537e-1, -0.1647633e-1, 0.392377e-2].reverse(); - function bessel0(x) { - if(x <= 3.75) return _horner(b0_a, x*x/(3.75*3.75)); - return M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b0_b, 3.75/M.abs(x)); + // Return error if values does not contain at least one positive value and one negative value + if (!positive || !negative) { + return error.num; } - var b1_a = [0.5, 0.87890594, 0.51498869, 0.15084934, 0.2658733e-1, 0.301532e-2, 0.32411e-3].reverse(); - var b1_b = [0.39894228, -0.3988024e-1, -0.362018e-2, 0.163801e-2, -0.1031555e-1, 0.2282967e-1, -0.2895312e-1, 0.1787654e-1, -0.420059e-2].reverse(); - function bessel1(x) { - if(x < 3.75) return x * _horner(b1_a, x*x/(3.75*3.75)); - return (x < 0 ? -1 : 1) * M.exp(M.abs(x))/M.sqrt(M.abs(x))*_horner(b1_b, 3.75/M.abs(x)); - } + // Initialize guess and resultRate + guess = guess || 0.1; + var resultRate = guess; - return function besseli(x, n) { - n = Math.round(n); - if(n === 0) return bessel0(x); - if(n == 1) return bessel1(x); - if(n < 0) throw 'BESSELI Order (' + n + ') must be nonnegative'; - if(M.abs(x) === 0) return 0; + // Set maximum epsilon for end of iteration + var epsMax = 1e-10; - var ret, j, tox = 2 / M.abs(x), m, bip, bi, bim; - m=2*M.round((n+M.round(M.sqrt(40*n)))/2); - bip=ret=0.0; - bi=1.0; - for (j=m;j>0;j--) { - bim=j*tox*bi + bip; - bip=bi; bi=bim; - if (M.abs(bi) > 1E10) { - bi *= 1E-10; - bip *= 1E-10; - ret *= 1E-10; - } - if(j == n) ret = bip; - } - ret *= besseli(x, 0) / bi; - return x < 0 && (n%2) ? -ret : ret; - }; + // Implement Newton's method + var newRate, epsRate, resultValue; + var contLoop = true; + do { + resultValue = irrResult(values, dates, resultRate); + newRate = resultRate - resultValue / irrResultDeriv(values, dates, resultRate); + epsRate = Math.abs(newRate - resultRate); + resultRate = newRate; + contLoop = (epsRate > epsMax) && (Math.abs(resultValue) > epsMax); + } while (contLoop); - })(); + // Return internal rate of return + return resultRate; + }; - var besselk = (function() { - var b0_a = [-0.57721566, 0.42278420, 0.23069756, 0.3488590e-1, 0.262698e-2, 0.10750e-3, 0.74e-5].reverse(); - var b0_b = [1.25331414, -0.7832358e-1, 0.2189568e-1, -0.1062446e-1, 0.587872e-2, -0.251540e-2, 0.53208e-3].reverse(); - function bessel0(x) { - if(x <= 2) return -M.log(x/2)*besseli(x,0) + _horner(b0_a, x*x/4); - return M.exp(-x)/M.sqrt(x)*_horner(b0_b, 2/x); + exports.XNPV = function(rate, values, dates) { + rate = utils.parseNumber(rate); + values = utils.parseNumberArray(utils.flatten(values)); + dates = utils.parseDateArray(utils.flatten(dates)); + if (utils.anyIsError(rate, values, dates)) { + return error.value; } - var b1_a = [1.0, 0.15443144, -0.67278579, -0.18156897, -0.1919402e-1, -0.110404e-2, -0.4686e-4].reverse(); - var b1_b = [1.25331414, 0.23498619, -0.3655620e-1, 0.1504268e-1, -0.780353e-2, 0.325614e-2, -0.68245e-3].reverse(); - function bessel1(x) { - if(x <= 2) return M.log(x/2)*besseli(x,1) + (1/x)*_horner(b1_a, x*x/4); - return M.exp(-x)/M.sqrt(x)*_horner(b1_b, 2/x); + var result = 0; + for (var i = 0; i < values.length; i++) { + result += values[i] / Math.pow(1 + rate, dateTime.DAYS(dates[i], dates[0]) / 365); } + return result; + }; - return _bessel_wrap(bessel0, bessel1, 'BESSELK', 2, 1); - })(); - if(true) { - exports.besselj = besselj; - exports.bessely = bessely; - exports.besseli = besseli; - exports.besselk = besselk; - } + // TODO + exports.YIELD = function() { + throw new Error('YIELD is not implemented'); + }; + + // TODO + exports.YIELDDISC = function() { + throw new Error('YIELDDISC is not implemented'); + }; + + // TODO + exports.YIELDMAT = function() { + throw new Error('YIELDMAT is not implemented'); + }; + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + + var error = __webpack_require__(5); + + exports.MATCH = function(lookupValue, lookupArray, matchType) { + if (!lookupValue && !lookupArray) { + return error.na; + } + + if (arguments.length === 2) { + matchType = 1; + } + if (!(lookupArray instanceof Array)) { + return error.na; + } + if (matchType !== -1 && matchType !== 0 && matchType !== 1) { + return error.na; + } + var index; + var indexValue; + for (var idx = 0; idx < lookupArray.length; idx++) { + if (matchType === 1) { + if (lookupArray[idx] === lookupValue) { + return idx + 1; + } else if (lookupArray[idx] < lookupValue) { + if (!indexValue) { + index = idx + 1; + indexValue = lookupArray[idx]; + } else if (lookupArray[idx] > indexValue) { + index = idx + 1; + indexValue = lookupArray[idx]; + } + } + } else if (matchType === 0) { + if (typeof lookupValue === 'string') { + lookupValue = lookupValue.replace(/\?/g, '.'); + if (lookupArray[idx].toLowerCase().match(lookupValue.toLowerCase())) { + return idx + 1; + } + } else { + if (lookupArray[idx] === lookupValue) { + return idx + 1; + } + } + } else if (matchType === -1) { + if (lookupArray[idx] === lookupValue) { + return idx + 1; + } else if (lookupArray[idx] > lookupValue) { + if (!indexValue) { + index = idx + 1; + indexValue = lookupArray[idx]; + } else if (lookupArray[idx] < indexValue) { + index = idx + 1; + indexValue = lookupArray[idx]; + } + } + } + } + return index ? index : error.na; + }; -/***/ } +/***/ }) /******/ ]) }); +; \ No newline at end of file diff --git a/dist/formula.min.js b/dist/formula.min.js index c113da31..79b4b5c8 100644 --- a/dist/formula.min.js +++ b/dist/formula.min.js @@ -1,4 +1,4 @@ -!function(r,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("jStat"),require("numeric"),require("numeral")):"function"==typeof define&&define.amd?define(["jStat","numeric","numeral"],e):"object"==typeof exports?exports.formulajs=e(require("jStat"),require("numeric"),require("numeral")):r.formulajs=e(r.jStat,r.numeric,r.numeral)}(this,function(__WEBPACK_EXTERNAL_MODULE_13__,__WEBPACK_EXTERNAL_MODULE_14__,__WEBPACK_EXTERNAL_MODULE_15__){return function(r){function e(n){if(t[n])return t[n].exports;var a=t[n]={exports:{},id:n,loaded:!1};return r[n].call(a.exports,a,a.exports,e),a.loaded=!0,a.exports}var t={};return e.m=r,e.c=t,e.p="",e(0)}([function(r,e,t){var n=[t(1),t(2),t(3),t(4),t(5),t(6),t(7),t(8),t(9),t(10),t(11),t(12)];for(var a in n){var u=n[a];for(var s in u)e[s]=e[s]||u[s]}},function(r,e,t){function n(r,e){if(e)for(var t in e)r[t]=e[t];return r}var a=t(5),u=t(11),s=t(3),i=t(7);e.BETADIST=u.BETA.DIST,e.BETAINV=u.BETA.INV,e.BINOMDIST=u.BINOM.DIST,e.CEILING=e.ISOCEILING=n(a.CEILING.MATH,a.CEILING),e.CEILINGMATH=a.CEILING.MATH,e.CEILINGPRECISE=a.CEILING.PRECISE,e.CHIDIST=u.CHISQ.DIST,e.CHIDISTRT=u.CHISQ.DIST.RT,e.CHIINV=u.CHISQ.INV,e.CHIINVRT=u.CHISQ.INV.RT,e.CHITEST=u.CHISQ.TEST,e.CONFIDENCE=n(u.CONFIDENCE.NORM,u.CONFIDENCE),e.COVAR=u.COVARIANCE.P,e.COVARIANCEP=u.COVARIANCE.P,e.COVARIANCES=u.COVARIANCE.S,e.CRITBINOM=u.BINOM.INV,e.EXPONDIST=u.EXPON.DIST,e.ERFCPRECISE=s.ERFC.PRECISE,e.ERFPRECISE=s.ERF.PRECISE,e.FDIST=u.F.DIST,e.FDISTRT=u.F.DIST.RT,e.FINVRT=u.F.INV.RT,e.FINV=u.F.INV,e.FLOOR=n(a.FLOOR.MATH,a.FLOOR),e.FLOORMATH=a.FLOOR.MATH,e.FLOORPRECISE=a.FLOOR.PRECISE,e.FTEST=u.F.TEST,e.GAMMADIST=u.GAMMA.DIST,e.GAMMAINV=u.GAMMA.INV,e.GAMMALNPRECISE=u.GAMMALN.PRECISE,e.HYPGEOMDIST=u.HYPGEOM.DIST,e.LOGINV=u.LOGNORM.INV,e.LOGNORMINV=u.LOGNORM.INV,e.LOGNORMDIST=u.LOGNORM.DIST,e.MODE=n(u.MODE.SNGL,u.MODE),e.MODEMULT=u.MODE.MULT,e.MODESNGL=u.MODE.SNGL,e.NEGBINOMDIST=u.NEGBINOM.DIST,e.NETWORKDAYSINTL=i.NETWORKDAYS.INTL,e.NORMDIST=u.NORM.DIST,e.NORMINV=u.NORM.INV,e.NORMSDIST=u.NORM.S.DIST,e.NORMSINV=u.NORM.S.INV,e.PERCENTILE=n(u.PERCENTILE.EXC,u.PERCENTILE),e.PERCENTILEEXC=u.PERCENTILE.EXC,e.PERCENTILEINC=u.PERCENTILE.INC,e.PERCENTRANK=n(u.PERCENTRANK.INC,u.PERCENTRANK),e.PERCENTRANKEXC=u.PERCENTRANK.EXC,e.PERCENTRANKINC=u.PERCENTRANK.INC,e.POISSON=n(u.POISSON.DIST,u.POISSON),e.POISSONDIST=u.POISSON.DIST,e.QUARTILE=n(u.QUARTILE.INC,u.QUARTILE),e.QUARTILEEXC=u.QUARTILE.EXC,e.QUARTILEINC=u.QUARTILE.INC,e.RANK=n(u.RANK.EQ,u.RANK),e.RANKAVG=u.RANK.AVG,e.RANKEQ=u.RANK.EQ,e.SKEWP=u.SKEW.P,e.STDEV=n(u.STDEV.S,u.STDEV),e.STDEVP=u.STDEV.P,e.STDEVS=u.STDEV.S,e.TDIST=u.T.DIST,e.TDISTRT=u.T.DIST.RT,e.TINV=u.T.INV,e.TTEST=u.T.TEST,e.VAR=n(u.VAR.S,u.VAR),e.VARP=u.VAR.P,e.VARS=u.VAR.S,e.WEIBULL=n(u.WEIBULL.DIST,u.WEIBULL),e.WEIBULLDIST=u.WEIBULL.DIST,e.WORKDAYINTL=i.WORKDAY.INTL,e.ZTEST=u.Z.TEST},function(module,exports,__webpack_require__){function compact(r){if(!r)return r;for(var e=[],t=0;tmaxCriteriaLength&&(maxCriteriaLength=criterias[i].length);for(var k=1;k1?error.num:a[n[0]]},exports.DMAX=function(r,e,t){if(isNaN(e)&&"string"!=typeof e)return error.value;var n=findResultIndex(r,t),a=[];if("string"==typeof e){var u=exports.FINDFIELD(r,e);a=utils.rest(r[u])}else a=utils.rest(r[e]);for(var s=a[n[0]],i=1;ia[n[i]]&&(s=a[n[i]]);return s},exports.DPRODUCT=function(r,e,t){if(isNaN(e)&&"string"!=typeof e)return error.value;var n=findResultIndex(r,t),a=[];if("string"==typeof e){var u=exports.FINDFIELD(r,e);a=utils.rest(r[u])}else a=utils.rest(r[e]);for(var s=[],i=0;ie?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.BIN2OCT=function(r,e){if(!n(r))return a.num;var t=r.toString();if(10===t.length&&"1"===t.substring(0,1))return(1073741312+parseInt(t.substring(1),2)).toString(8);var u=parseInt(r,2).toString(8);return void 0===e?u:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.BITAND=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:0>r||0>e?a.num:Math.floor(r)!==r||Math.floor(e)!==e?a.num:r>0xffffffffffff||e>0xffffffffffff?a.num:r&e},e.BITLSHIFT=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:0>r?a.num:Math.floor(r)!==r?a.num:r>0xffffffffffff?a.num:Math.abs(e)>53?a.num:e>=0?r<>-e},e.BITOR=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:0>r||0>e?a.num:Math.floor(r)!==r||Math.floor(e)!==e?a.num:r>0xffffffffffff||e>0xffffffffffff?a.num:r|e},e.BITRSHIFT=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:0>r?a.num:Math.floor(r)!==r?a.num:r>0xffffffffffff?a.num:Math.abs(e)>53?a.num:e>=0?r>>e:r<<-e},e.BITXOR=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:0>r||0>e?a.num:Math.floor(r)!==r||Math.floor(e)!==e?a.num:r>0xffffffffffff||e>0xffffffffffff?a.num:r^e},e.COMPLEX=function(r,e,t){if(r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e))return r;if(t=void 0===t?"i":t,"i"!==t&&"j"!==t)return a.value;if(0===r&&0===e)return 0;if(0===r)return 1===e?t:e.toString()+t;if(0===e)return r.toString();var n=e>0?"+":"";return r.toString()+n+(1===e?t:e.toString()+t)},e.CONVERT=function(r,e,t){if(r=i.parseNumber(r),r instanceof Error)return r;for(var n,u=[["a.u. of action","?",null,"action",!1,!1,1.05457168181818e-34],["a.u. of charge","e",null,"electric_charge",!1,!1,1.60217653141414e-19],["a.u. of energy","Eh",null,"energy",!1,!1,4.35974417757576e-18],["a.u. of length","a?",null,"length",!1,!1,5.29177210818182e-11],["a.u. of mass","m?",null,"mass",!1,!1,9.10938261616162e-31],["a.u. of time","?/Eh",null,"time",!1,!1,2.41888432650516e-17],["admiralty knot","admkn",null,"speed",!1,!0,.514773333],["ampere","A",null,"electric_current",!0,!1,1],["ampere per meter","A/m",null,"magnetic_field_intensity",!0,!1,1],["ångström","Å",["ang"],"length",!1,!0,1e-10],["are","ar",null,"area",!1,!0,100],["astronomical unit","ua",null,"length",!1,!1,1.49597870691667e-11],["bar","bar",null,"pressure",!1,!1,1e5],["barn","b",null,"area",!1,!1,1e-28],["becquerel","Bq",null,"radioactivity",!0,!1,1],["bit","bit",["b"],"information",!1,!0,1],["btu","BTU",["btu"],"energy",!1,!0,1055.05585262],["byte","byte",null,"information",!1,!0,8],["candela","cd",null,"luminous_intensity",!0,!1,1],["candela per square metre","cd/m?",null,"luminance",!0,!1,1],["coulomb","C",null,"electric_charge",!0,!1,1],["cubic ångström","ang3",["ang^3"],"volume",!1,!0,1e-30],["cubic foot","ft3",["ft^3"],"volume",!1,!0,.028316846592],["cubic inch","in3",["in^3"],"volume",!1,!0,16387064e-12],["cubic light-year","ly3",["ly^3"],"volume",!1,!0,8.46786664623715e-47],["cubic metre","m?",null,"volume",!0,!0,1],["cubic mile","mi3",["mi^3"],"volume",!1,!0,4168181825.44058],["cubic nautical mile","Nmi3",["Nmi^3"],"volume",!1,!0,6352182208],["cubic Pica","Pica3",["Picapt3","Pica^3","Picapt^3"],"volume",!1,!0,7.58660370370369e-8],["cubic yard","yd3",["yd^3"],"volume",!1,!0,.764554857984],["cup","cup",null,"volume",!1,!0,.0002365882365],["dalton","Da",["u"],"mass",!1,!1,1.66053886282828e-27],["day","d",["day"],"time",!1,!0,86400],["degree","°",null,"angle",!1,!1,.0174532925199433],["degrees Rankine","Rank",null,"temperature",!1,!0,.555555555555556],["dyne","dyn",["dy"],"force",!1,!0,1e-5],["electronvolt","eV",["ev"],"energy",!1,!0,1.60217656514141],["ell","ell",null,"length",!1,!0,1.143],["erg","erg",["e"],"energy",!1,!0,1e-7],["farad","F",null,"electric_capacitance",!0,!1,1],["fluid ounce","oz",null,"volume",!1,!0,295735295625e-16],["foot","ft",null,"length",!1,!0,.3048],["foot-pound","flb",null,"energy",!1,!0,1.3558179483314],["gal","Gal",null,"acceleration",!1,!1,.01],["gallon","gal",null,"volume",!1,!0,.003785411784],["gauss","G",["ga"],"magnetic_flux_density",!1,!0,1],["grain","grain",null,"mass",!1,!0,647989e-10],["gram","g",null,"mass",!1,!0,.001],["gray","Gy",null,"absorbed_dose",!0,!1,1],["gross registered ton","GRT",["regton"],"volume",!1,!0,2.8316846592],["hectare","ha",null,"area",!1,!0,1e4],["henry","H",null,"inductance",!0,!1,1],["hertz","Hz",null,"frequency",!0,!1,1],["horsepower","HP",["h"],"power",!1,!0,745.69987158227],["horsepower-hour","HPh",["hh","hph"],"energy",!1,!0,2684519.538],["hour","h",["hr"],"time",!1,!0,3600],["imperial gallon (U.K.)","uk_gal",null,"volume",!1,!0,.00454609],["imperial hundredweight","lcwt",["uk_cwt","hweight"],"mass",!1,!0,50.802345],["imperial quart (U.K)","uk_qt",null,"volume",!1,!0,.0011365225],["imperial ton","brton",["uk_ton","LTON"],"mass",!1,!0,1016.046909],["inch","in",null,"length",!1,!0,.0254],["international acre","uk_acre",null,"area",!1,!0,4046.8564224],["IT calorie","cal",null,"energy",!1,!0,4.1868],["joule","J",null,"energy",!0,!0,1],["katal","kat",null,"catalytic_activity",!0,!1,1],["kelvin","K",["kel"],"temperature",!0,!0,1],["kilogram","kg",null,"mass",!0,!0,1],["knot","kn",null,"speed",!1,!0,.514444444444444],["light-year","ly",null,"length",!1,!0,9460730472580800],["litre","L",["l","lt"],"volume",!1,!0,.001],["lumen","lm",null,"luminous_flux",!0,!1,1],["lux","lx",null,"illuminance",!0,!1,1],["maxwell","Mx",null,"magnetic_flux",!1,!1,1e-18],["measurement ton","MTON",null,"volume",!1,!0,1.13267386368],["meter per hour","m/h",["m/hr"],"speed",!1,!0,.00027777777777778],["meter per second","m/s",["m/sec"],"speed",!0,!0,1],["meter per second squared","m?s??",null,"acceleration",!0,!1,1],["parsec","pc",["parsec"],"length",!1,!0,0x6da012f958ee1c],["meter squared per second","m?/s",null,"kinematic_viscosity",!0,!1,1],["metre","m",null,"length",!0,!0,1],["miles per hour","mph",null,"speed",!1,!0,.44704],["millimetre of mercury","mmHg",null,"pressure",!1,!1,133.322],["minute","?",null,"angle",!1,!1,.000290888208665722],["minute","min",["mn"],"time",!1,!0,60],["modern teaspoon","tspm",null,"volume",!1,!0,5e-6],["mole","mol",null,"amount_of_substance",!0,!1,1],["morgen","Morgen",null,"area",!1,!0,2500],["n.u. of action","?",null,"action",!1,!1,1.05457168181818e-34],["n.u. of mass","m?",null,"mass",!1,!1,9.10938261616162e-31],["n.u. of speed","c?",null,"speed",!1,!1,299792458],["n.u. of time","?/(me?c??)",null,"time",!1,!1,1.28808866778687e-21],["nautical mile","M",["Nmi"],"length",!1,!0,1852],["newton","N",null,"force",!0,!0,1],["œrsted","Oe ",null,"magnetic_field_intensity",!1,!1,79.5774715459477],["ohm","Ω",null,"electric_resistance",!0,!1,1],["ounce mass","ozm",null,"mass",!1,!0,.028349523125],["pascal","Pa",null,"pressure",!0,!1,1],["pascal second","Pa?s",null,"dynamic_viscosity",!0,!1,1],["pferdestärke","PS",null,"power",!1,!0,735.49875],["phot","ph",null,"illuminance",!1,!1,1e-4],["pica (1/6 inch)","pica",null,"length",!1,!0,.00035277777777778],["pica (1/72 inch)","Pica",["Picapt"],"length",!1,!0,.00423333333333333],["poise","P",null,"dynamic_viscosity",!1,!1,.1],["pond","pond",null,"force",!1,!0,.00980665],["pound force","lbf",null,"force",!1,!0,4.4482216152605],["pound mass","lbm",null,"mass",!1,!0,.45359237],["quart","qt",null,"volume",!1,!0,.000946352946],["radian","rad",null,"angle",!0,!1,1],["second","?",null,"angle",!1,!1,484813681109536e-20],["second","s",["sec"],"time",!0,!0,1],["short hundredweight","cwt",["shweight"],"mass",!1,!0,45.359237],["siemens","S",null,"electrical_conductance",!0,!1,1],["sievert","Sv",null,"equivalent_dose",!0,!1,1],["slug","sg",null,"mass",!1,!0,14.59390294],["square ångström","ang2",["ang^2"],"area",!1,!0,1e-20],["square foot","ft2",["ft^2"],"area",!1,!0,.09290304],["square inch","in2",["in^2"],"area",!1,!0,64516e-8],["square light-year","ly2",["ly^2"],"area",!1,!0,8.95054210748189e31],["square meter","m?",null,"area",!0,!0,1],["square mile","mi2",["mi^2"],"area",!1,!0,2589988.110336],["square nautical mile","Nmi2",["Nmi^2"],"area",!1,!0,3429904],["square Pica","Pica2",["Picapt2","Pica^2","Picapt^2"],"area",!1,!0,1792111111111e-17],["square yard","yd2",["yd^2"],"area",!1,!0,.83612736],["statute mile","mi",null,"length",!1,!0,1609.344],["steradian","sr",null,"solid_angle",!0,!1,1],["stilb","sb",null,"luminance",!1,!1,1e-4],["stokes","St",null,"kinematic_viscosity",!1,!1,1e-4],["stone","stone",null,"mass",!1,!0,6.35029318],["tablespoon","tbs",null,"volume",!1,!0,147868e-10],["teaspoon","tsp",null,"volume",!1,!0,492892e-11],["tesla","T",null,"magnetic_flux_density",!0,!0,1],["thermodynamic calorie","c",null,"energy",!1,!0,4.184],["ton","ton",null,"mass",!1,!0,907.18474],["tonne","t",null,"mass",!1,!1,1e3],["U.K. pint","uk_pt",null,"volume",!1,!0,.00056826125],["U.S. bushel","bushel",null,"volume",!1,!0,.03523907],["U.S. oil barrel","barrel",null,"volume",!1,!0,.158987295],["U.S. pint","pt",["us_pt"],"volume",!1,!0,.000473176473],["U.S. survey mile","survey_mi",null,"length",!1,!0,1609.347219],["U.S. survey/statute acre","us_acre",null,"area",!1,!0,4046.87261],["volt","V",null,"voltage",!0,!1,1],["watt","W",null,"power",!0,!0,1],["watt-hour","Wh",["wh"],"energy",!1,!0,3600],["weber","Wb",null,"magnetic_flux",!0,!1,1],["yard","yd",null,"length",!1,!0,.9144],["year","yr",null,"time",!1,!0,31557600]],s={Yi:["yobi",80,1.2089258196146292e24,"Yi","yotta"],Zi:["zebi",70,0x400000000000000000,"Zi","zetta"],Ei:["exbi",60,0x1000000000000000,"Ei","exa"],Pi:["pebi",50,0x4000000000000,"Pi","peta"],Ti:["tebi",40,1099511627776,"Ti","tera"],Gi:["gibi",30,1073741824,"Gi","giga"],Mi:["mebi",20,1048576,"Mi","mega"],ki:["kibi",10,1024,"ki","kilo"]},o={Y:["yotta",1e24,"Y"],Z:["zetta",1e21,"Z"],E:["exa",1e18,"E"],P:["peta",1e15,"P"],T:["tera",1e12,"T"],G:["giga",1e9,"G"],M:["mega",1e6,"M"],k:["kilo",1e3,"k"],h:["hecto",100,"h"],e:["dekao",10,"e"],d:["deci",.1,"d"],c:["centi",.01,"c"],m:["milli",.001,"m"],u:["micro",1e-6,"u"],n:["nano",1e-9,"n"],p:["pico",1e-12,"p"],f:["femto",1e-15,"f"],a:["atto",1e-18,"a"],z:["zepto",1e-21,"z"],y:["yocto",1e-24,"y"]},l=null,f=null,p=e,c=t,m=1,N=1,E=0;E=0)&&(l=u[E]),(u[E][1]===c||n.indexOf(c)>=0)&&(f=u[E]);if(null===l){var I=s[e.substring(0,2)],g=o[e.substring(0,1)];"da"===e.substring(0,2)&&(g=["dekao",10,"da"]),I?(m=I[2],p=e.substring(2)):g&&(m=g[1],p=e.substring(g[2].length));for(var h=0;h=0)&&(l=u[h])}if(null===f){var v=s[t.substring(0,2)],M=o[t.substring(0,1)];"da"===t.substring(0,2)&&(M=["dekao",10,"da"]),v?(N=v[2],c=t.substring(2)):M&&(N=M[1],c=t.substring(M[2].length));for(var b=0;b=0)&&(f=u[b])}return null===l||null===f?a.na:l[3]!==f[3]?a.na:r*l[6]*m/(f[6]*N)},e.DEC2BIN=function(r,e){if(r=i.parseNumber(r),r instanceof Error)return r;if(!/^-?[0-9]{1,3}$/.test(r)||-512>r||r>511)return a.num;if(0>r)return"1"+s.REPT("0",9-(512+r).toString(2).length)+(512+r).toString(2);var t=parseInt(r,10).toString(2);return"undefined"==typeof e?t:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=t.length?s.REPT("0",e-t.length)+t:a.num)},e.DEC2HEX=function(r,e){if(r=i.parseNumber(r),r instanceof Error)return r;if(!/^-?[0-9]{1,12}$/.test(r)||-549755813888>r||r>549755813887)return a.num;if(0>r)return(1099511627776+r).toString(16);var t=parseInt(r,10).toString(16);return"undefined"==typeof e?t:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=t.length?s.REPT("0",e-t.length)+t:a.num)},e.DEC2OCT=function(r,e){if(r=i.parseNumber(r),r instanceof Error)return r;if(!/^-?[0-9]{1,9}$/.test(r)||-536870912>r||r>536870911)return a.num;if(0>r)return(1073741824+r).toString(8);var t=parseInt(r,10).toString(8);return"undefined"==typeof e?t:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=t.length?s.REPT("0",e-t.length)+t:a.num)},e.DELTA=function(r,e){return e=void 0===e?0:e,r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r===e?1:0},e.ERF=function(r,e){return e=void 0===e?0:e,r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:u.erf(r)},e.ERF.PRECISE=function(){throw new Error("ERF.PRECISE is not implemented")},e.ERFC=function(r){return isNaN(r)?a.value:u.erfc(r)},e.ERFC.PRECISE=function(){throw new Error("ERFC.PRECISE is not implemented")},e.GESTEP=function(r,e){return e=e||0,r=i.parseNumber(r),i.anyIsError(e,r)?r:r>=e?1:0},e.HEX2BIN=function(r,e){if(!/^[0-9A-Fa-f]{1,10}$/.test(r))return a.num;var t=10===r.length&&"f"===r.substring(0,1).toLowerCase()?!0:!1,n=t?parseInt(r,16)-1099511627776:parseInt(r,16);if(-512>n||n>511)return a.num;if(t)return"1"+s.REPT("0",9-(512+n).toString(2).length)+(512+n).toString(2);var u=n.toString(2);return void 0===e?u:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.HEX2DEC=function(r){if(!/^[0-9A-Fa-f]{1,10}$/.test(r))return a.num;var e=parseInt(r,16);return e>=549755813888?e-1099511627776:e},e.HEX2OCT=function(r,e){if(!/^[0-9A-Fa-f]{1,10}$/.test(r))return a.num;var t=parseInt(r,16);if(t>536870911&&0xffe0000000>t)return a.num;if(t>=0xffe0000000)return(t-0xffc0000000).toString(8);var n=t.toString(8);return void 0===e?n:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=n.length?s.REPT("0",e-n.length)+n:a.num)},e.IMABS=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:Math.sqrt(Math.pow(t,2)+Math.pow(n,2))},e.IMAGINARY=function(r){if(void 0===r||r===!0||r===!1)return a.value;if(0===r||"0"===r)return 0;if(["i","j"].indexOf(r)>=0)return 1;r=r.replace("+i","+1i").replace("-i","-1i").replace("+j","+1j").replace("-j","-1j");var e=r.indexOf("+"),t=r.indexOf("-");0===e&&(e=r.indexOf("+",1)),0===t&&(t=r.indexOf("-",1));var n=r.substring(r.length-1,r.length),u="i"===n||"j"===n;return e>=0||t>=0?u?e>=0?isNaN(r.substring(0,e))||isNaN(r.substring(e+1,r.length-1))?a.num:Number(r.substring(e+1,r.length-1)):isNaN(r.substring(0,t))||isNaN(r.substring(t+1,r.length-1))?a.num:-Number(r.substring(t+1,r.length-1)):a.num:u?isNaN(r.substring(0,r.length-1))?a.num:r.substring(0,r.length-1):isNaN(r)?a.num:0},e.IMARGUMENT=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:0===t&&0===n?a.div0:0===t&&n>0?Math.PI/2:0===t&&0>n?-Math.PI/2:0===n&&t>0?0:0===n&&0>t?-Math.PI:t>0?Math.atan(n/t):0>t&&n>=0?Math.atan(n/t)+Math.PI:Math.atan(n/t)-Math.PI},e.IMCONJUGATE=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",0!==n?e.COMPLEX(t,-n,u):r},e.IMCOS=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.cos(t)*(Math.exp(n)+Math.exp(-n))/2,-Math.sin(t)*(Math.exp(n)-Math.exp(-n))/2,u)},e.IMCOSH=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.cos(n)*(Math.exp(t)+Math.exp(-t))/2,Math.sin(n)*(Math.exp(t)-Math.exp(-t))/2,u)},e.IMCOT=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:e.IMDIV(e.IMCOS(r),e.IMSIN(r))},e.IMDIV=function(r,t){var n=e.IMREAL(r),u=e.IMAGINARY(r),s=e.IMREAL(t),o=e.IMAGINARY(t);if(i.anyIsError(n,u,s,o))return a.value;var l=r.substring(r.length-1),f=t.substring(t.length-1),p="i";if("j"===l?p="j":"j"===f&&(p="j"),0===s&&0===o)return a.num;var c=s*s+o*o;return e.COMPLEX((n*s+u*o)/c,(u*s-n*o)/c,p)},e.IMEXP=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);u="i"===u||"j"===u?u:"i";var s=Math.exp(t);return e.COMPLEX(s*Math.cos(n),s*Math.sin(n),u)},e.IMLN=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.log(Math.sqrt(t*t+n*n)),Math.atan(n/t),u)},e.IMLOG10=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.log(Math.sqrt(t*t+n*n))/Math.log(10),Math.atan(n/t)/Math.log(10),u)},e.IMLOG2=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.log(Math.sqrt(t*t+n*n))/Math.log(2),Math.atan(n/t)/Math.log(2),u)},e.IMPOWER=function(r,t){t=i.parseNumber(t);var n=e.IMREAL(r),u=e.IMAGINARY(r);if(i.anyIsError(t,n,u))return a.value;var s=r.substring(r.length-1);s="i"===s||"j"===s?s:"i";var o=Math.pow(e.IMABS(r),t),l=e.IMARGUMENT(r);return e.COMPLEX(o*Math.cos(t*l),o*Math.sin(t*l),s)},e.IMPRODUCT=function(){for(var r=arguments[0],t=1;t=0)return 0;var e=r.indexOf("+"),t=r.indexOf("-");0===e&&(e=r.indexOf("+",1)),0===t&&(t=r.indexOf("-",1));var n=r.substring(r.length-1,r.length),u="i"===n||"j"===n;return e>=0||t>=0?u?e>=0?isNaN(r.substring(0,e))||isNaN(r.substring(e+1,r.length-1))?a.num:Number(r.substring(0,e)):isNaN(r.substring(0,t))||isNaN(r.substring(t+1,r.length-1))?a.num:Number(r.substring(0,t)):a.num:u?isNaN(r.substring(0,r.length-1))?a.num:0:isNaN(r)?a.num:r},e.IMSEC=function(r){if(r===!0||r===!1)return a.value;var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:e.IMDIV("1",e.IMCOS(r))},e.IMSECH=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:e.IMDIV("1",e.IMCOSH(r))},e.IMSIN=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.sin(t)*(Math.exp(n)+Math.exp(-n))/2,Math.cos(t)*(Math.exp(n)-Math.exp(-n))/2,u)},e.IMSINH=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.cos(n)*(Math.exp(t)-Math.exp(-t))/2,Math.sin(n)*(Math.exp(t)+Math.exp(-t))/2,u)},e.IMSQRT=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);u="i"===u||"j"===u?u:"i";var s=Math.sqrt(e.IMABS(r)),o=e.IMARGUMENT(r);return e.COMPLEX(s*Math.cos(o/2),s*Math.sin(o/2),u)},e.IMCSC=function(r){if(r===!0||r===!1)return a.value;var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.num:e.IMDIV("1",e.IMSIN(r))},e.IMCSCH=function(r){if(r===!0||r===!1)return a.value;var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.num:e.IMDIV("1",e.IMSINH(r))},e.IMSUB=function(r,e){var t=this.IMREAL(r),n=this.IMAGINARY(r),u=this.IMREAL(e),s=this.IMAGINARY(e);if(i.anyIsError(t,n,u,s))return a.value;var o=r.substring(r.length-1),l=e.substring(e.length-1),f="i";return"j"===o?f="j":"j"===l&&(f="j"),this.COMPLEX(t-u,n-s,f)},e.IMSUM=function(){for(var r=i.flatten(arguments),e=r[0],t=1;tn||n>511)return a.num;if(t)return"1"+s.REPT("0",9-(512+n).toString(2).length)+(512+n).toString(2);var u=n.toString(2);return"undefined"==typeof e?u:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.OCT2DEC=function(r){if(!/^[0-7]{1,10}$/.test(r))return a.num;var e=parseInt(r,8);return e>=536870912?e-1073741824:e},e.OCT2HEX=function(r,e){if(!/^[0-7]{1,10}$/.test(r))return a.num;var t=parseInt(r,8);if(t>=536870912)return"ff"+(t+3221225472).toString(16);var n=t.toString(16);return void 0===e?n:isNaN(e)?a.value:0>e?a.num:(e=Math.floor(e),e>=n.length?s.REPT("0",e-n.length)+n:a.num)}},function(r,e,t){var n=t(16),a=t(17),u=t(9);e.AND=function(){for(var r=a.flatten(arguments),e=!0,t=0;tr||r>254?n.value:arguments.length0){var e=arguments[0],t=arguments.length-1,n=Math.floor(t/2),a=!1,u=t%2===0?null:arguments[arguments.length-1];if(n)for(var s=0;n>s;s++)if(e===arguments[2*s+1]){r=arguments[2*s+2],a=!0;break}!a&&u&&(r=u)}return r}},function(module,exports,__webpack_require__){var numeric=__webpack_require__(14),utils=__webpack_require__(17),error=__webpack_require__(16),statistical=__webpack_require__(11),information=__webpack_require__(9);exports.ABS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.abs(utils.parseNumber(r))},exports.ACOS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.acos(r)},exports.ACOSH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r+Math.sqrt(r*r-1))},exports.ACOT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.atan(1/r)},exports.ACOTH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:.5*Math.log((r+1)/(r-1))},exports.AGGREGATE=function(r,e,t,n){if(r=utils.parseNumber(r),e=utils.parseNumber(r),utils.anyIsError(r,e))return error.value;switch(r){case 1:return statistical.AVERAGE(t);case 2:return statistical.COUNT(t);case 3:return statistical.COUNTA(t);case 4:return statistical.MAX(t);case 5:return statistical.MIN(t);case 6:return exports.PRODUCT(t);case 7:return statistical.STDEV.S(t);case 8:return statistical.STDEV.P(t);case 9:return exports.SUM(t);case 10:return statistical.VAR.S(t);case 11:return statistical.VAR.P(t);case 12:return statistical.MEDIAN(t);case 13:return statistical.MODE.SNGL(t);case 14:return statistical.LARGE(t,n);case 15:return statistical.SMALL(t,n);case 16:return statistical.PERCENTILE.INC(t,n);case 17:return statistical.QUARTILE.INC(t,n);case 18:return statistical.PERCENTILE.EXC(t,n);case 19:return statistical.QUARTILE.EXC(t,n)}},exports.ARABIC=function(r){if(!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(r))return error.value;var e=0;return r.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,function(r){e+={M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}[r]}),e},exports.ASIN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.asin(r)},exports.ASINH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r+Math.sqrt(r*r+1))},exports.ATAN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.atan(r)},exports.ATAN2=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:Math.atan2(r,e) -},exports.ATANH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log((1+r)/(1-r))/2},exports.BASE=function(r,e,t){if(t=t||0,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;t=void 0===t?0:t;var n=r.toString(e);return new Array(Math.max(t+1-n.length,0)).join("0")+n},exports.CEILING=function(r,e,t){if(e=void 0===e?1:Math.abs(e),t=t||0,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;if(0===e)return 0;var n=-Math.floor(Math.log(e)/Math.log(10));return r>=0?exports.ROUND(Math.ceil(r/e)*e,n):0===t?-exports.ROUND(Math.floor(Math.abs(r)/e)*e,n):-exports.ROUND(Math.ceil(Math.abs(r)/e)*e,n)},exports.CEILING.MATH=exports.CEILING,exports.CEILING.PRECISE=exports.CEILING,exports.COMBIN=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:exports.FACT(r)/(exports.FACT(e)*exports.FACT(r-e))},exports.COMBINA=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:0===r&&0===e?1:exports.COMBIN(r+e-1,r-1)},exports.COS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.cos(r)},exports.COSH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:(Math.exp(r)+Math.exp(-r))/2},exports.COT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:1/Math.tan(r)},exports.COTH=function(r){if(r=utils.parseNumber(r),r instanceof Error)return r;var e=Math.exp(2*r);return(e+1)/(e-1)},exports.CSC=function(r){return r=utils.parseNumber(r),r instanceof Error?r:1/Math.sin(r)},exports.CSCH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:2/(Math.exp(r)-Math.exp(-r))},exports.DECIMAL=function(r,e){return arguments.length<1?error.value:parseInt(r,e)},exports.DEGREES=function(r){return r=utils.parseNumber(r),r instanceof Error?r:180*r/Math.PI},exports.EVEN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:exports.CEILING(r,-2,-1)},exports.EXP=Math.exp;var MEMOIZED_FACT=[];exports.FACT=function(r){if(r=utils.parseNumber(r),r instanceof Error)return r;var e=Math.floor(r);return 0===e||1===e?1:MEMOIZED_FACT[e]>0?MEMOIZED_FACT[e]:(MEMOIZED_FACT[e]=exports.FACT(e-1)*e,MEMOIZED_FACT[e])},exports.FACTDOUBLE=function(r){if(r=utils.parseNumber(r),r instanceof Error)return r;var e=Math.floor(r);return 0>=e?1:e*exports.FACTDOUBLE(e-2)},exports.FLOOR=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;if(0===e)return 0;if(!(r>0&&e>0||0>r&&0>e))return error.num;e=Math.abs(e);var t=-Math.floor(Math.log(e)/Math.log(10));return r>=0?exports.ROUND(Math.floor(r/e)*e,t):-exports.ROUND(Math.ceil(Math.abs(r)/e),t)},exports.FLOOR.MATH=function(r,e,t){if(e=void 0===e?1:e,t=void 0===t?0:t,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;if(0===e)return 0;e=e?Math.abs(e):1;var n=-Math.floor(Math.log(e)/Math.log(10));return r>=0?exports.ROUND(Math.floor(r/e)*e,n):0===t||void 0===t?-exports.ROUND(Math.ceil(Math.abs(r)/e)*e,n):-exports.ROUND(Math.floor(Math.abs(r)/e)*e,n)},exports.FLOOR.PRECISE=exports.FLOOR.MATH,exports.GCD=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=r.length,t=r[0],n=0>t?-t:t,a=1;e>a;a++){for(var u=r[a],s=0>u?-u:u;n&&s;)n>s?n%=s:s%=n;n+=s}return n},exports.INT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.floor(r)},exports.ISO={CEILING:exports.CEILING},exports.LCM=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e,t,n,a,u=1;void 0!==(n=r.pop());)for(;n>1;){if(n%2){for(e=3,t=Math.floor(Math.sqrt(n));t>=e&&n%e;e+=2);a=t>=e?e:n}else a=2;for(n/=a,u*=a,e=r.length;e;r[--e]%a===0&&1===(r[e]/=a)&&r.splice(e,1));}return u},exports.LN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r)},exports.LOG=function(r,e){return r=utils.parseNumber(r),e=void 0===e?10:utils.parseNumber(e),utils.anyIsError(r,e)?error.value:Math.log(r)/Math.log(e)},exports.LOG10=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r)/Math.log(10)},exports.MDETERM=function(r){return r=utils.parseMatrix(r),r instanceof Error?r:numeric.det(r)},exports.MINVERSE=function(r){return r=utils.parseMatrix(r),r instanceof Error?r:numeric.inv(r)},exports.MMULT=function(r,e){return r=utils.parseMatrix(r),e=utils.parseMatrix(e),utils.anyIsError(r,e)?error.value:numeric.dot(r,e)},exports.MOD=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;if(0===e)return error.div0;var t=Math.abs(r%e);return e>0?t:-t},exports.MROUND=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:0>r*e?error.num:Math.round(r/e)*e},exports.MULTINOMIAL=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=0,t=1,n=0;n0?e:-e},exports.PI=function(){return Math.PI},exports.POWER=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;var t=Math.pow(r,e);return isNaN(t)?error.num:t},exports.PRODUCT=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=1,t=0;t0?1:-1;return t*Math.floor(Math.abs(r)*Math.pow(10,e))/Math.pow(10,e)},exports.ROUNDUP=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;var t=r>0?1:-1;return t*Math.ceil(Math.abs(r)*Math.pow(10,e))/Math.pow(10,e)},exports.SEC=function(r){return r=utils.parseNumber(r),r instanceof Error?r:1/Math.cos(r)},exports.SECH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:2/(Math.exp(r)+Math.exp(-r))},exports.SERIESSUM=function(r,e,t,n){if(r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),n=utils.parseNumberArray(n),utils.anyIsError(r,e,t,n))return error.value;for(var a=n[0]*Math.pow(r,e),u=1;ur?-1:0===r?0:1},exports.SIN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.sin(r)},exports.SINH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:(Math.exp(r)-Math.exp(-r))/2},exports.SQRT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:0>r?error.num:Math.sqrt(r)},exports.SQRTPI=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.sqrt(r*Math.PI)},exports.SUBTOTAL=function(r,e){if(r=utils.parseNumber(r),r instanceof Error)return r;switch(r){case 1:return statistical.AVERAGE(e);case 2:return statistical.COUNT(e);case 3:return statistical.COUNTA(e);case 4:return statistical.MAX(e);case 5:return statistical.MIN(e);case 6:return exports.PRODUCT(e);case 7:return statistical.STDEV.S(e);case 8:return statistical.STDEV.P(e);case 9:return exports.SUM(e);case 10:return statistical.VAR.S(e);case 11:return statistical.VAR.P(e);case 101:return statistical.AVERAGE(e);case 102:return statistical.COUNT(e);case 103:return statistical.COUNTA(e);case 104:return statistical.MAX(e);case 105:return statistical.MIN(e);case 106:return exports.PRODUCT(e);case 107:return statistical.STDEV.S(e);case 108:return statistical.STDEV.P(e);case 109:return exports.SUM(e);case 110:return statistical.VAR.S(e);case 111:return statistical.VAR.P(e)}},exports.ADD=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:r+e)},exports.MINUS=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:r-e)},exports.DIVIDE=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:0===e?error.div0:r/e)},exports.MULTIPLY=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:r*e)},exports.GTE=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.error:r>=e)},exports.LT=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.error:e>r)},exports.LTE=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.error:e>=r)},exports.EQ=function(r,e){return 2!==arguments.length?error.na:r===e},exports.NE=function(r,e){return 2!==arguments.length?error.na:r!==e},exports.POW=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.error:exports.POWER(r,e))},exports.SUM=function(){for(var r=0,e=Object.keys(arguments),t=0;ti;i++){for(var el=range[i],condition="",c=0;n_criterias>c;c++)condition+=el+criteria[c],c!==n_criterias-1&&(condition+="&&");eval(condition)&&(result+=el)}return result},exports.SUMPRODUCT=function(){if(!arguments||0===arguments.length)return error.value;for(var r,e,t,n,a=arguments.length+1,u=0,s=0;se;e++){if(n=utils.parseNumber(arguments[e-1][s][i]),n instanceof Error)return n;r*=n}u+=r}else{for(r=1,e=1;a>e;e++){if(t=utils.parseNumber(arguments[e-1][s]),t instanceof Error)return t;r*=t}u+=r}return u},exports.SUMSQ=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=0,t=r.length,n=0;t>n;n++)e+=information.ISNUMBER(r[n])?r[n]*r[n]:0;return e},exports.SUMX2MY2=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;for(var t=0,n=0;n0?1:-1;return t*Math.floor(Math.abs(r)*Math.pow(10,e))/Math.pow(10,e)}},function(r,e,t){var n=t(17),a=t(16),u=t(15);e.ASC=function(){throw new Error("ASC is not implemented")},e.BAHTTEXT=function(){throw new Error("BAHTTEXT is not implemented")},e.CHAR=function(r){return r=n.parseNumber(r),r instanceof Error?r:String.fromCharCode(r)},e.CLEAN=function(r){r=r||"";var e=/[\0-\x1F]/g;return r.replace(e,"")},e.CODE=function(r){return r=r||"",r.charCodeAt(0)},e.CONCATENATE=function(){for(var r=n.flatten(arguments),e=0;(e=r.indexOf(!0))>-1;)r[e]="TRUE";for(var t=0;(t=r.indexOf(!1))>-1;)r[t]="FALSE";return r.join("")},e.DBCS=function(){throw new Error("DBCS is not implemented")},e.DOLLAR=function(r,e){if(e=void 0===e?2:e,r=n.parseNumber(r),e=n.parseNumber(e),n.anyIsError(r,e))return a.value;var t="";return 0>=e?(r=Math.round(r*Math.pow(10,e))/Math.pow(10,e),t="($0,0)"):e>0&&(t="($0,0."+new Array(e+1).join("0")+")"),u(r).format(t)},e.EXACT=function(r,e){return r===e},e.FIND=function(r,e,t){return t=void 0===t?0:t,e?e.indexOf(r,t-1)+1:null},e.FIXED=function(r,e,t){if(e=void 0===e?2:e,t=void 0===t?!1:t,r=n.parseNumber(r),e=n.parseNumber(e),n.anyIsError(r,e))return a.value;var s=t?"0":"0,0";return 0>=e?r=Math.round(r*Math.pow(10,e))/Math.pow(10,e):e>0&&(s+="."+new Array(e+1).join("0")),u(r).format(s)},e.HTML2TEXT=function(r){var e="";return r&&(r instanceof Array?r.forEach(function(r){""!==e&&(e+="\n"),e+=r.replace(/<(?:.|\n)*?>/gm,"")}):e=r.replace(/<(?:.|\n)*?>/gm,"")),e},e.LEFT=function(r,e){return e=void 0===e?1:e,e=n.parseNumber(e),e instanceof Error||"string"!=typeof r?a.value:r?r.substring(0,e):null},e.LEN=function(r){return 0===arguments.length?a.error:"string"==typeof r?r?r.length:0:r.length?r.length:a.value},e.LOWER=function(r){return"string"!=typeof r?a.value:r?r.toLowerCase():r},e.MID=function(r,e,t){if(e=n.parseNumber(e),t=n.parseNumber(t),n.anyIsError(e,t)||"string"!=typeof r)return t;var a=e-1,u=a+t;return r.substring(a,u)},e.NUMBERVALUE=function(r,e,t){return e="undefined"==typeof e?".":e,t="undefined"==typeof t?",":t,Number(r.replace(e,".").replace(t,""))},e.PRONETIC=function(){throw new Error("PRONETIC is not implemented")},e.PROPER=function(r){return void 0===r||0===r.length?a.value:(r===!0&&(r="TRUE"),r===!1&&(r="FALSE"),isNaN(r)&&"number"==typeof r?a.value:("number"==typeof r&&(r=""+r),r.replace(/\w\S*/g,function(r){return r.charAt(0).toUpperCase()+r.substr(1).toLowerCase()})))},e.REGEXEXTRACT=function(r,e){var t=r.match(new RegExp(e));return t?t[t.length>1?t.length-1:0]:null},e.REGEXMATCH=function(r,e,t){var n=r.match(new RegExp(e));return t?n:!!n},e.REGEXREPLACE=function(r,e,t){return r.replace(new RegExp(e),t)},e.REPLACE=function(r,e,t,u){return e=n.parseNumber(e),t=n.parseNumber(t),n.anyIsError(e,t)||"string"!=typeof r||"string"!=typeof u?a.value:r.substr(0,e-1)+u+r.substr(e-1+t)},e.REPT=function(r,e){return e=n.parseNumber(e),e instanceof Error?e:new Array(e+1).join(r)},e.RIGHT=function(r,e){return e=void 0===e?1:e,e=n.parseNumber(e),e instanceof Error?e:r?r.substring(r.length-e):null},e.SEARCH=function(r,e,t){var n;return"string"!=typeof r||"string"!=typeof e?a.value:(t=void 0===t?0:t,n=e.toLowerCase().indexOf(r.toLowerCase(),t-1)+1,0===n?a.value:n)},e.SPLIT=function(r,e){return r.split(e)},e.SUBSTITUTE=function(r,e,t,n){if(!(r&&e&&t))return r;if(void 0===n)return r.replace(new RegExp(e,"g"),t);for(var a=0,u=0;r.indexOf(e,a)>0;)if(a=r.indexOf(e,a+1),u++,u===n)return r.substring(0,a)+t+r.substring(a+e.length)},e.T=function(r){return"string"==typeof r?r:""},e.TEXT=function(r,e){return r=n.parseNumber(r),n.anyIsError(r)?a.na:u(r).format(e)},e.TRIM=function(r){return"string"!=typeof r?a.value:r.replace(/ +/g," ").trim()},e.UNICHAR=this.CHAR,e.UNICODE=this.CODE,e.UPPER=function(r){return"string"!=typeof r?a.value:r.toUpperCase()},e.VALUE=function(r){return"string"!=typeof r?a.value:u().unformat(r)}},function(r,e,t){function n(r){return 1===new Date(r,1,29).getMonth()}function a(r,e){return Math.ceil((e-r)/1e3/60/60/24)}function u(r){var e=r>-22038912e5?2:1;return(r-o)/864e5+e}var s=t(16),i=t(17),o=new Date(1900,0,1),l=[void 0,0,1,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,1,2,3,4,5,6,0],f=[[],[1,2,3,4,5,6,7],[7,1,2,3,4,5,6],[6,0,1,2,3,4,5],[],[],[],[],[],[],[],[7,1,2,3,4,5,6],[6,7,1,2,3,4,5],[5,6,7,1,2,3,4],[4,5,6,7,1,2,3],[3,4,5,6,7,1,2],[2,3,4,5,6,7,1],[1,2,3,4,5,6,7]],p=[[],[6,0],[0,1],[1,2],[2,3],[3,4],[4,5],[5,6],void 0,void 0,void 0,[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]];e.DATE=function(r,e,t){if(r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),i.anyIsError(r,e,t))return s.value;if(0>r||0>e||0>t)return s.num;var n=new Date(r,e-1,t);return n},e.DATEVALUE=function(r){if("string"!=typeof r)return s.value;var e=Date.parse(r);return isNaN(e)?s.value:-22038912e5>=e?(e-o)/864e5+1:(e-o)/864e5+2},e.DAY=function(r){var e=i.parseDate(r);return e instanceof Error?e:e.getDate()},e.DAYS=function(r,e){return r=i.parseDate(r),e=i.parseDate(e),r instanceof Error?r:e instanceof Error?e:u(r)-u(e)},e.DAYS360=function(r,e,t){if(t=i.parseBool(t),r=i.parseDate(r),e=i.parseDate(e),r instanceof Error)return r;if(e instanceof Error)return e;if(t instanceof Error)return t;var n,a,u=r.getMonth(),s=e.getMonth();if(t)n=31===r.getDate()?30:r.getDate(),a=31===e.getDate()?30:e.getDate();else{var o=new Date(r.getFullYear(),u+1,0).getDate(),l=new Date(e.getFullYear(),s+1,0).getDate();n=r.getDate()===o?30:r.getDate(),e.getDate()===l?30>n?(s++,a=1):a=30:a=e.getDate()}return 360*(e.getFullYear()-r.getFullYear())+30*(s-u)+(a-n)},e.EDATE=function(r,e){return r=i.parseDate(r),r instanceof Error?r:isNaN(e)?s.value:(e=parseInt(e,10),r.setMonth(r.getMonth()+e),u(r))},e.EOMONTH=function(r,e){return r=i.parseDate(r),r instanceof Error?r:isNaN(e)?s.value:(e=parseInt(e,10),u(new Date(r.getFullYear(),r.getMonth()+e+1,0)))},e.HOUR=function(r){return r=i.parseDate(r),r instanceof Error?r:r.getHours()},e.INTERVAL=function(r){if("number"!=typeof r&&"string"!=typeof r)return s.value;r=parseInt(r,10);var e=Math.floor(r/94608e4);r%=94608e4;var t=Math.floor(r/2592e3);r%=2592e3;var n=Math.floor(r/86400);r%=86400;var a=Math.floor(r/3600);r%=3600;var u=Math.floor(r/60);r%=60;var i=r;return e=e>0?e+"Y":"",t=t>0?t+"M":"",n=n>0?n+"D":"",a=a>0?a+"H":"",u=u>0?u+"M":"",i=i>0?i+"S":"","P"+e+t+n+"T"+a+u+i},e.ISOWEEKNUM=function(r){if(r=i.parseDate(r),r instanceof Error)return r;r.setHours(0,0,0),r.setDate(r.getDate()+4-(r.getDay()||7));var e=new Date(r.getFullYear(),0,1);return Math.ceil(((r-e)/864e5+1)/7)},e.MINUTE=function(r){return r=i.parseDate(r),r instanceof Error?r:r.getMinutes()},e.MONTH=function(r){return r=i.parseDate(r),r instanceof Error?r:r.getMonth()+1},e.NETWORKDAYS=function(r,e,t){return this.NETWORKDAYS.INTL(r,e,1,t)},e.NETWORKDAYS.INTL=function(r,e,t,n){if(r=i.parseDate(r),r instanceof Error)return r;if(e=i.parseDate(e),e instanceof Error)return e;if(t=void 0===t?p[1]:p[t],!(t instanceof Array))return s.value;void 0===n?n=[]:n instanceof Array||(n=[n]);for(var a=0;aa;a++){var c=(new Date).getTimezoneOffset()>0?f.getUTCDay():f.getDay(),m=!1;(c===t[0]||c===t[1])&&(m=!0);for(var N=0;Nr||0>e||0>t?s.num:(3600*r+60*e+t)/86400},e.TIMEVALUE=function(r){return r=i.parseDate(r),r instanceof Error?r:(3600*r.getHours()+60*r.getMinutes()+r.getSeconds())/86400},e.TODAY=function(){return new Date},e.WEEKDAY=function(r,e){if(r=i.parseDate(r),r instanceof Error)return r;void 0===e&&(e=1);var t=r.getDay();return f[e][t]},e.WEEKNUM=function(r,e){if(r=i.parseDate(r),r instanceof Error)return r;if(void 0===e&&(e=1),21===e)return this.ISOWEEKNUM(r);var t=l[e],n=new Date(r.getFullYear(),0,1),a=n.getDay()e)return s.num;if(t=void 0===t?p[1]:p[t],!(t instanceof Array))return s.value;void 0===n?n=[]:n instanceof Array||(n=[n]);for(var a=0;ao;){r.setDate(r.getDate()+1);var l=r.getDay();if(l!==t[0]&&l!==t[1]){for(var f=0;fr&&e>=a)return!0;var u=e.getFullYear(),s=new Date(u,2,1);return n(u)&&e>=s&&s>r},m=365;if(o===p||o+1===p&&(s>f||s===f&&u>=l))return(o===p&&n(o)||c(r,e)||1===f&&29===l)&&(m=366),a(r,e)/m;var N=p-o+1,E=(new Date(p+1,0,1)-new Date(o,0,1))/1e3/60/60/24,I=E/N;return a(r,e)/I;case 2:return a(r,e)/360;case 3:return a(r,e)/365;case 4:return(l+30*f+360*p-(u+30*s+360*o))/360}}},function(r,e,t){function n(r){return r&&r.getTime&&!isNaN(r.getTime())}function a(r){return r instanceof Date?r:new Date(r)}var u=t(16),s=t(7),i=t(17);e.ACCRINT=function(r,e,t,u,i,o,l){return r=a(r),e=a(e),t=a(t),n(r)&&n(e)&&n(t)?0>=u||0>=i?"#NUM!":-1===[1,2,4].indexOf(o)?"#NUM!":-1===[0,1,2,3,4].indexOf(l)?"#NUM!":r>=t?"#NUM!":(i=i||0,l=l||0,i*u*s.YEARFRAC(r,t,l)):"#VALUE!"},e.ACCRINTM=function(){throw new Error("ACCRINTM is not implemented")},e.AMORDEGRC=function(){throw new Error("AMORDEGRC is not implemented")},e.AMORLINC=function(){throw new Error("AMORLINC is not implemented")},e.COUPDAYBS=function(){throw new Error("COUPDAYBS is not implemented")},e.COUPDAYS=function(){throw new Error("COUPDAYS is not implemented")},e.COUPDAYSNC=function(){throw new Error("COUPDAYSNC is not implemented")},e.COUPNCD=function(){throw new Error("COUPNCD is not implemented")},e.COUPNUM=function(){throw new Error("COUPNUM is not implemented")},e.COUPPCD=function(){throw new Error("COUPPCD is not implemented")},e.CUMIPMT=function(r,t,n,a,s,o){if(r=i.parseNumber(r),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,t,n))return u.value;if(0>=r||0>=t||0>=n)return u.num;if(1>a||1>s||a>s)return u.num;if(0!==o&&1!==o)return u.num;var l=e.PMT(r,t,n,0,o),f=0;1===a&&0===o&&(f=-n,a++);for(var p=a;s>=p;p++)f+=1===o?e.FV(r,p-2,l,n,1)-l:e.FV(r,p-1,l,n,0);return f*=r},e.CUMPRINC=function(r,t,n,a,s,o){if(r=i.parseNumber(r),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,t,n))return u.value;if(0>=r||0>=t||0>=n)return u.num;if(1>a||1>s||a>s)return u.num;if(0!==o&&1!==o)return u.num;var l=e.PMT(r,t,n,0,o),f=0;1===a&&(f=0===o?l+n*r:l,a++);for(var p=a;s>=p;p++)f+=o>0?l-(e.FV(r,p-2,l,n,1)-l)*r:l-e.FV(r,p-1,l,n,0)*r;return f},e.DB=function(r,e,t,n,a){if(a=void 0===a?12:a,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;if(0>r||0>e||0>t||0>n)return u.num;if(-1===[1,2,3,4,5,6,7,8,9,10,11,12].indexOf(a))return u.num;if(n>t)return u.num;if(e>=r)return 0;for(var s=(1-Math.pow(e/r,1/t)).toFixed(3),o=r*s*a/12,l=o,f=0,p=n===t?t-1:n,c=2;p>=c;c++)f=(r-l)*s,l+=f;return 1===n?o:n===t?(r-l)*s:f},e.DDB=function(r,e,t,n,a){if(a=void 0===a?2:a,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;if(0>r||0>e||0>t||0>n||0>=a)return u.num;if(n>t)return u.num;if(e>=r)return 0;for(var s=0,o=0,l=1;n>=l;l++)o=Math.min((r-s)*(a/t),r-e-s),s+=o;return o},e.DISC=function(){throw new Error("DISC is not implemented")},e.DOLLARDE=function(r,e){if(r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e))return u.value;if(0>e)return u.num;if(e>=0&&1>e)return u.div0;e=parseInt(e,10);var t=parseInt(r,10);t+=r%1*Math.pow(10,Math.ceil(Math.log(e)/Math.LN10))/e;var n=Math.pow(10,Math.ceil(Math.log(e)/Math.LN2)+1);return t=Math.round(t*n)/n},e.DOLLARFR=function(r,e){if(r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e))return u.value;if(0>e)return u.num;if(e>=0&&1>e)return u.div0;e=parseInt(e,10);var t=parseInt(r,10);return t+=r%1*Math.pow(10,-Math.ceil(Math.log(e)/Math.LN10))*e},e.DURATION=function(){throw new Error("DURATION is not implemented")},e.EFFECT=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?u.value:0>=r||1>e?u.num:(e=parseInt(e,10),Math.pow(1+r/e,e)-1)},e.FV=function(r,e,t,n,a){if(n=n||0,a=a||0,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;var s;if(0===r)s=n+t*e;else{var o=Math.pow(1+r,e);s=1===a?n*o+t*(1+r)*(o-1)/r:n*o+t*(o-1)/r}return-s},e.FVSCHEDULE=function(r,e){if(r=i.parseNumber(r),e=i.parseNumberArray(i.flatten(e)),i.anyIsError(r,e))return u.value;for(var t=e.length,n=r,a=0;t>a;a++)n*=1+e[a];return n},e.INTRATE=function(){throw new Error("INTRATE is not implemented")},e.IPMT=function(r,t,n,a,s,o){if(s=s||0,o=o||0,r=i.parseNumber(r),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),s=i.parseNumber(s),o=i.parseNumber(o),i.anyIsError(r,t,n,a,s,o))return u.value;var l,f=e.PMT(r,n,a,s,o);return l=1===t?1===o?0:-a:1===o?e.FV(r,t-2,f,a,1)-f:e.FV(r,t-1,f,a,0),l*r},e.IRR=function(r,e){if(e=e||0,r=i.parseNumberArray(i.flatten(r)),e=i.parseNumber(e),i.anyIsError(r,e))return u.value;for(var t=function(r,e,t){for(var n=t+1,a=r[0],u=1;u0&&(s=!0),r[l]<0&&(o=!0);if(!s||!o)return u.num;e=void 0===e?.1:e;var f,p,c,m=e,N=1e-10,E=!0;do c=t(r,a,m),f=m-c/n(r,a,m),p=Math.abs(f-m),m=f,E=p>N&&Math.abs(c)>N;while(E);return m},e.ISPMT=function(r,e,t,n){return r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,e,t,n)?u.value:n*r*(e/t-1)},e.MDURATION=function(){throw new Error("MDURATION is not implemented")},e.MIRR=function(r,t,n){if(r=i.parseNumberArray(i.flatten(r)),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,t,n))return u.value;for(var a=r.length,s=[],o=[],l=0;a>l;l++)r[l]<0?s.push(r[l]):o.push(r[l]);var f=-e.NPV(n,o)*Math.pow(1+n,a-1),p=e.NPV(t,s)*(1+t);return Math.pow(f/p,1/(a-1))-1},e.NOMINAL=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?u.value:0>=r||1>e?u.num:(e=parseInt(e,10),(Math.pow(r+1,1/e)-1)*e)},e.NPER=function(r,e,t,n,a){if(a=void 0===a?0:a,n=void 0===n?0:n,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;var s=e*(1+r*a)-n*r,o=t*r+e*(1+r*a);return Math.log(s/o)/Math.log(1+r)},e.NPV=function(){var r=i.parseNumberArray(i.flatten(arguments));if(r instanceof Error)return r;for(var e=r[0],t=0,n=1;n=r?u.num:(Math.log(t)-Math.log(e))/Math.log(1+r)},e.PMT=function(r,e,t,n,a){if(n=n||0,a=a||0,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;var s;if(0===r)s=(t+n)/e;else{var o=Math.pow(1+r,e);s=1===a?(n*r/(o-1)+t*r/(1-1/o))/(1+r):n*r/(o-1)+t*r/(1-1/o)}return-s},e.PPMT=function(r,t,n,a,s,o){return s=s||0,o=o||0,r=i.parseNumber(r),n=i.parseNumber(n),a=i.parseNumber(a),s=i.parseNumber(s),o=i.parseNumber(o),i.anyIsError(r,n,a,s,o)?u.value:e.PMT(r,n,a,s,o)-e.IPMT(r,t,n,a,s,o)},e.PRICE=function(){throw new Error("PRICE is not implemented")},e.PRICEDISC=function(){throw new Error("PRICEDISC is not implemented")},e.PRICEMAT=function(){throw new Error("PRICEMAT is not implemented")},e.PV=function(r,e,t,n,a){return n=n||0,a=a||0,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a)?u.value:0===r?-t*e-n:((1-Math.pow(1+r,e))/r*t*(1+r*a)-n)/Math.pow(1+r,e)},e.RATE=function(r,e,t,n,a,s){if(s=void 0===s?.01:s,n=void 0===n?0:n,a=void 0===a?0:a,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),s=i.parseNumber(s),i.anyIsError(r,e,t,n,a,s))return u.value;for(var o=1e-6,l=100,f=0,p=!1,c=s;l>f&&!p;){var m=Math.pow(c+1,r),N=Math.pow(c+1,r-1),E=n+m*t+e*(m-1)*(c*a+1)/c,I=r*N*t-e*(m-1)*(c*a+1)/Math.pow(c,2),g=r*e*N*(c*a+1)/c+e*(m-1)*a/c,h=c-E/(I+g);Math.abs(h-c)n||n>t?u.num:(n=parseInt(n,10),(r-e)*(t-n+1)*2/(t*(t+1)))},e.TBILLEQ=function(r,e,t){return r=i.parseDate(r),e=i.parseDate(e),t=i.parseNumber(t),i.anyIsError(r,e,t)?u.value:0>=t?u.num:r>e?u.num:e-r>31536e6?u.num:365*t/(360-t*s.DAYS360(r,e,!1))},e.TBILLPRICE=function(r,e,t){return r=i.parseDate(r),e=i.parseDate(e),t=i.parseNumber(t),i.anyIsError(r,e,t)?u.value:0>=t?u.num:r>e?u.num:e-r>31536e6?u.num:100*(1-t*s.DAYS360(r,e,!1)/360)},e.TBILLYIELD=function(r,e,t){return r=i.parseDate(r),e=i.parseDate(e),t=i.parseNumber(t),i.anyIsError(r,e,t)?u.value:0>=t?u.num:r>e?u.num:e-r>31536e6?u.num:360*(100-t)/(t*s.DAYS360(r,e,!1))},e.VDB=function(){throw new Error("VDB is not implemented")},e.XIRR=function(r,e,t){if(r=i.parseNumberArray(i.flatten(r)),e=i.parseDateArray(i.flatten(e)),t=i.parseNumber(t),i.anyIsError(r,e,t))return u.value;for(var n=function(r,e,t){for(var n=t+1,a=r[0],u=1;u0&&(o=!0),r[f]<0&&(l=!0);if(!o||!l)return u.num;t=t||.1;var p,c,m,N=t,E=1e-10,I=!0;do m=n(r,e,N),p=N-m/a(r,e,N),c=Math.abs(p-N),N=p,I=c>E&&Math.abs(m)>E;while(I);return N},e.XNPV=function(r,e,t){if(r=i.parseNumber(r),e=i.parseNumberArray(i.flatten(e)),t=i.parseDateArray(i.flatten(t)),i.anyIsError(r,e,t))return u.value;for(var n=0,a=0;a=0||"number"==typeof r&&(isNaN(r)||!isFinite(r))},e.ISERROR=function(r){return e.ISERR(r)||r===n.na},e.ISEVEN=function(r){return 1&Math.floor(Math.abs(r))?!1:!0},e.ISFORMULA=function(){throw new Error("ISFORMULA is not implemented")},e.ISLOGICAL=function(r){return r===!0||r===!1},e.ISNA=function(r){return r===n.na},e.ISNONTEXT=function(r){return"string"!=typeof r},e.ISNUMBER=function(r){return"number"==typeof r&&!isNaN(r)&&isFinite(r)},e.ISODD=function(r){return 1&Math.floor(Math.abs(r))?!0:!1},e.ISREF=function(){throw new Error("ISREF is not implemented")},e.ISTEXT=function(r){return"string"==typeof r},e.N=function(r){return this.ISNUMBER(r)?r:r instanceof Date?r.getTime():r===!0?1:r===!1?0:this.ISERROR(r)?r:0},e.NA=function(){return n.na},e.SHEET=function(){throw new Error("SHEET is not implemented")},e.SHEETS=function(){throw new Error("SHEETS is not implemented")},e.TYPE=function(r){return this.ISNUMBER(r)?1:this.ISTEXT(r)?2:this.ISLOGICAL(r)?4:this.ISERROR(r)?16:Array.isArray(r)?64:void 0}},function(r,e,t){var n=t(16);e.MATCH=function(r,e,t){if(!r&&!e)return n.na;if(2===arguments.length&&(t=1),!(e instanceof Array))return n.na;if(-1!==t&&0!==t&&1!==t)return n.na;for(var a,u,s=0;su&&(a=s+1,u=e[s]):(a=s+1,u=e[s]))}else if(0===t){if("string"==typeof r){if(r=r.replace(/\?/g,"."),e[s].toLowerCase().match(r.toLowerCase()))return s+1}else if(e[s]===r)return s+1}else if(-1===t){if(e[s]===r)return s+1;e[s]>r&&(u?e[s]a;a++)t+=r[a],n+=1;return t/n},exports.AVERAGEA=function(){for(var r=utils.flatten(arguments),e=r.length,t=0,n=0,a=0;e>a;a++){var u=r[a];"number"==typeof u&&(t+=u),u===!0&&t++,null!==u&&n++}return t/n},exports.AVERAGEIF=function(range,criteria,average_range){if(average_range=average_range||range,range=utils.flatten(range),average_range=utils.parseNumberArray(utils.flatten(average_range)),average_range instanceof Error)return average_range;for(var average_count=0,result=0,i=0;ij;j++)condition+=args[2*j+1][i]+args[2*j+2],j!==criteria-1&&(condition+="&&");eval(condition)&&(result+=range[i],count++)}var average=result/count;return isNaN(average)?0:average},exports.BETA={},exports.BETA.DIST=function(r,e,t,n,a,u){return arguments.length<4?error.value:(a=void 0===a?0:a,u=void 0===u?1:u,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),a=utils.parseNumber(a),u=utils.parseNumber(u),utils.anyIsError(r,e,t,a,u)?error.value:(r=(r-a)/(u-a),n?jStat.beta.cdf(r,e,t):jStat.beta.pdf(r,e,t)))},exports.BETA.INV=function(r,e,t,n,a){return n=void 0===n?0:n,a=void 0===a?1:a,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),n=utils.parseNumber(n),a=utils.parseNumber(a),utils.anyIsError(r,e,t,n,a)?error.value:jStat.beta.inv(r,e,t)*(a-n)+n},exports.BINOM={},exports.BINOM.DIST=function(r,e,t,n){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),n=utils.parseNumber(n),utils.anyIsError(r,e,t,n)?error.value:n?jStat.binomial.cdf(r,e,t):jStat.binomial.pdf(r,e,t)},exports.BINOM.DIST.RANGE=function(r,e,t,n){if(n=void 0===n?t:n,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),n=utils.parseNumber(n),utils.anyIsError(r,e,t,n))return error.value;for(var a=0,u=t;n>=u;u++)a+=mathTrig.COMBIN(r,u)*Math.pow(e,u)*Math.pow(1-e,r-u);return a},exports.BINOM.INV=function(r,e,t){if(r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;for(var n=0;r>=n;){if(jStat.binomial.cdf(n,r,e)>=t)return n;n++}},exports.CHISQ={},exports.CHISQ.DIST=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:t?jStat.chisquare.cdf(r,e):jStat.chisquare.pdf(r,e)},exports.CHISQ.DIST.RT=function(r,e){return!r|!e?error.na:1>r||e>Math.pow(10,10)?error.num:"number"!=typeof r||"number"!=typeof e?error.value:1-jStat.chisquare.cdf(r,e)},exports.CHISQ.INV=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:jStat.chisquare.inv(r,e)},exports.CHISQ.INV.RT=function(r,e){return!r|!e?error.na:0>r||r>1||1>e||e>Math.pow(10,10)?error.num:"number"!=typeof r||"number"!=typeof e?error.value:jStat.chisquare.inv(1-r,e)},exports.CHISQ.TEST=function(r,e){function t(r,e){var t=Math.exp(-.5*r);e%2===1&&(t*=Math.sqrt(2*r/f));for(var n=e;n>=2;)t=t*r/n,n-=2;for(var a=t,u=e;a>1e-10*t;)u+=2,a=a*r/u,t+=a;return 1-t}if(2!==arguments.length)return error.na;if(!(r instanceof Array&&e instanceof Array))return error.value;if(r.length!==e.length)return error.value;if(r[0]&&e[0]&&r[0].length!==e[0].length)return error.value;var n,a,u,s=r.length;for(a=0;s>a;a++)r[a]instanceof Array||(n=r[a],r[a]=[],r[a].push(n)),e[a]instanceof Array||(n=e[a],e[a]=[],e[a].push(n));var i=r[0].length,o=1===i?s-1:(s-1)*(i-1),l=0,f=Math.PI;for(a=0;s>a;a++)for(u=0;i>u;u++)l+=Math.pow(r[a][u]-e[a][u],2)/e[a][u];return Math.round(1e6*t(l,o))/1e6},exports.COLUMN=function(r,e){return 2!==arguments.length?error.na:0>e?error.num:r instanceof Array&&"number"==typeof e?0===r.length?void 0:jStat.col(r,e):error.value},exports.COLUMNS=function(r){return 1!==arguments.length?error.na:r instanceof Array?0===r.length?0:jStat.cols(r):error.value},exports.CONFIDENCE={},exports.CONFIDENCE.NORM=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:jStat.normalci(1,r,e,t)[1]-1},exports.CONFIDENCE.T=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:jStat.tci(1,r,e,t)[1]-1},exports.CORREL=function(r,e){return r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e)?error.value:jStat.corrcoeff(r,e)},exports.COUNT=function(){return utils.numbers(utils.flatten(arguments)).length},exports.COUNTA=function(){var r=utils.flatten(arguments);return r.length-exports.COUNTBLANK(r)},exports.COUNTIN=function(r,e){for(var t=0,n=0;n=!]/.test(criteria)||(criteria='=="'+criteria+'"');for(var matches=0,i=0;i=!]/.test(criteria)||(criteria='=="'+criteria+'"');for(var j=0;js;s++)a+=(r[s]-t)*(e[s]-n);return a/u},exports.COVARIANCE.S=function(r,e){return r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e)?error.value:jStat.covariance(r,e)},exports.DEVSQ=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=jStat.mean(r),t=0,n=0;nr||1>e||1>t?error.num:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:1-jStat.centralF.cdf(r,e,t)},exports.F.INV=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:0>=r||r>1?error.num:jStat.centralF.inv(r,e,t)},exports.F.INV.RT=function(r,e,t){return 3!==arguments.length?error.na:0>r||r>1||1>e||e>Math.pow(10,10)||1>t||t>Math.pow(10,10)?error.num:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:jStat.centralF.inv(1-r,e,t)},exports.F.TEST=function(r,e){if(!r||!e)return error.na;if(!(r instanceof Array&&e instanceof Array))return error.na;if(r.length<2||e.length<2)return error.div0;var t=function(r,e){for(var t=0,n=0;no;o++)s+=(t[o]-n)*(e[o]-a),i+=Math.pow(t[o]-n,2);var l=s/i,f=a-l*n;return f+l*r},exports.FREQUENCY=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;for(var t=r.length,n=e.length,a=[],u=0;n>=u;u++){a[u]=0;for(var s=0;t>s;s++)0===u?r[s]<=e[0]&&(a[0]+=1):n>u?r[s]>e[u-1]&&r[s]<=e[u]&&(a[u]+=1):u===n&&r[s]>e[n-1]&&(a[n]+=1)}return a},exports.GAMMA=function(r){return r=utils.parseNumber(r),r instanceof Error?r:0===r?error.num:parseInt(r,10)===r&&0>r?error.num:jStat.gammafn(r)},exports.GAMMA.DIST=function(r,e,t,n){return 4!==arguments.length?error.na:0>r||0>=e||0>=t?error.value:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:n?jStat.gamma.cdf(r,e,t,!0):jStat.gamma.pdf(r,e,t,!1)},exports.GAMMA.INV=function(r,e,t){return 3!==arguments.length?error.na:0>r||r>1||0>=e||0>=t?error.num:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:jStat.gamma.inv(r,e,t)},exports.GAMMALN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:jStat.gammaln(r)},exports.GAMMALN.PRECISE=function(r){return 1!==arguments.length?error.na:0>=r?error.num:"number"!=typeof r?error.value:jStat.gammaln(r)},exports.GAUSS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:jStat.normal.cdf(r,0,1)-.5},exports.GEOMEAN=function(){var r=utils.parseNumberArray(utils.flatten(arguments));return r instanceof Error?r:jStat.geomean(r)},exports.GROWTH=function(r,e,t,n){if(r=utils.parseNumberArray(r),r instanceof Error)return r;var a;if(void 0===e)for(e=[],a=1;a<=r.length;a++)e.push(a);if(void 0===t)for(t=[],a=1;a<=r.length;a++)t.push(a);if(e=utils.parseNumberArray(e),t=utils.parseNumberArray(t),utils.anyIsError(e,t))return error.value;void 0===n&&(n=!0);var u=r.length,s=0,i=0,o=0,l=0;for(a=0;u>a;a++){var f=e[a],p=Math.log(r[a]);s+=f,i+=p,o+=f*p,l+=f*f}s/=u,i/=u,o/=u,l/=u;var c,m;n?(c=(o-s*i)/(l-s*s),m=i-c*s):(c=o/l,m=0);var N=[];for(a=0;an;n++)t+=1/r[n];return e/t},exports.HYPGEOM={},exports.HYPGEOM.DIST=function(r,e,t,n,a){function u(r,e,t,n){return mathTrig.COMBIN(t,r)*mathTrig.COMBIN(n-t,e-r)/mathTrig.COMBIN(n,e)}function s(r,e,t,n){for(var a=0,s=0;r>=s;s++)a+=u(s,e,t,n);return a}return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),n=utils.parseNumber(n),utils.anyIsError(r,e,t,n)?error.value:a?s(r,e,t,n):u(r,e,t,n)},exports.INTERCEPT=function(r,e){return r=utils.parseNumberArray(r),e=utils.parseNumberArray(e),utils.anyIsError(r,e)?error.value:r.length!==e.length?error.na:exports.FORECAST(0,r,e)},exports.KURT=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=jStat.mean(r),t=r.length,n=0,a=0;t>a;a++)n+=Math.pow(r[a]-e,4);return n/=Math.pow(jStat.stdev(r,!0),4),t*(t+1)/((t-1)*(t-2)*(t-3))*n-3*(t-1)*(t-1)/((t-2)*(t-3))},exports.LARGE=function(r,e){return r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e)?r:r.sort(function(r,e){return e-r})[e-1]},exports.LINEST=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;for(var t=jStat.mean(r),n=jStat.mean(e),a=e.length,u=0,s=0,i=0;a>i;i++)u+=(e[i]-n)*(r[i]-t),s+=Math.pow(e[i]-n,2);var o=u/s,l=t-o*n;return[o,l]},exports.LOGEST=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;for(var t=0;ts;s++)e=r[s],n[e]=n[e]?n[e]+1:1,n[e]>u&&(u=n[e],a=[]),n[e]===u&&(a[a.length]=e);return a},exports.MODE.SNGL=function(){var r=utils.parseNumberArray(utils.flatten(arguments));return r instanceof Error?r:exports.MODE.MULT(r).sort(function(r,e){return r-e})[0]},exports.NEGBINOM={},exports.NEGBINOM.DIST=function(r,e,t,n){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:n?jStat.negbin.cdf(r,e,t):jStat.negbin.pdf(r,e,t)},exports.NORM={},exports.NORM.DIST=function(r,e,t,n){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:0>=t?error.num:n?jStat.normal.cdf(r,e,t):jStat.normal.pdf(r,e,t)},exports.NORM.INV=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:jStat.normal.inv(r,e,t)},exports.NORM.S={},exports.NORM.S.DIST=function(r,e){return r=utils.parseNumber(r),r instanceof Error?error.value:e?jStat.normal.cdf(r,0,1):jStat.normal.pdf(r,0,1)},exports.NORM.S.INV=function(r){return r=utils.parseNumber(r),r instanceof Error?error.value:jStat.normal.inv(r,0,1)},exports.PEARSON=function(r,e){if(e=utils.parseNumberArray(utils.flatten(e)),r=utils.parseNumberArray(utils.flatten(r)),utils.anyIsError(e,r))return error.value;for(var t=jStat.mean(r),n=jStat.mean(e),a=r.length,u=0,s=0,i=0,o=0;a>o;o++)u+=(r[o]-t)*(e[o]-n),s+=Math.pow(r[o]-t,2),i+=Math.pow(e[o]-n,2);return u/Math.sqrt(s*i)},exports.PERCENTILE={},exports.PERCENTILE.EXC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;r=r.sort(function(r,e){return r-e});var t=r.length;if(1/(t+1)>e||e>1-1/(t+1))return error.num;var n=e*(t+1)-1,a=Math.floor(n);return utils.cleanFloat(n===a?r[n]:r[a]+(n-a)*(r[a+1]-r[a]))},exports.PERCENTILE.INC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;r=r.sort(function(r,e){return r-e});var t=r.length,n=e*(t-1),a=Math.floor(n);return utils.cleanFloat(n===a?r[n]:r[a]+(n-a)*(r[a+1]-r[a]))},exports.PERCENTRANK={},exports.PERCENTRANK.EXC=function(r,e,t){if(t=void 0===t?3:t,r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;r=r.sort(function(r,e){return r-e});for(var n=misc.UNIQUE.apply(null,r),a=r.length,u=n.length,s=Math.pow(10,t),i=0,o=!1,l=0;!o&&u>l;)e===n[l]?(i=(r.indexOf(n[l])+1)/(a+1),o=!0):e>=n[l]&&(el;)e===n[l]?(i=r.indexOf(n[l])/(a-1),o=!0):e>=n[l]&&(e=0?e[r.indexOf(t)]:0;for(var a=r.sort(function(r,e){return r-e}),u=a.length,s=0,i=0;u>i;i++)a[i]>=t&&a[i]<=n&&(s+=e[r.indexOf(a[i])]);return s},exports.QUARTILE={},exports.QUARTILE.EXC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;switch(e){case 1:return exports.PERCENTILE.EXC(r,.25);case 2:return exports.PERCENTILE.EXC(r,.5);case 3:return exports.PERCENTILE.EXC(r,.75);default:return error.num}},exports.QUARTILE.INC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;switch(e){case 1:return exports.PERCENTILE.INC(r,.25);case 2:return exports.PERCENTILE.INC(r,.5);case 3:return exports.PERCENTILE.INC(r,.75);default:return error.num}},exports.RANK={},exports.RANK.AVG=function(r,e,t){if(r=utils.parseNumber(r),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;e=utils.flatten(e),t=t||!1;var n=t?function(r,e){return r-e}:function(r,e){return e-r};e=e.sort(n);for(var a=e.length,u=0,s=0;a>s;s++)e[s]===r&&u++;return u>1?(2*e.indexOf(r)+u+1)/2:e.indexOf(r)+1},exports.RANK.EQ=function(r,e,t){if(r=utils.parseNumber(r),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;t=t||!1;var n=t?function(r,e){return r-e}:function(r,e){return e-r};return e=e.sort(n),e.indexOf(r)+1},exports.ROW=function(r,e){return 2!==arguments.length?error.na:0>e?error.num:r instanceof Array&&"number"==typeof e?0===r.length?void 0:jStat.row(r,e):error.value},exports.ROWS=function(r){return 1!==arguments.length?error.na:r instanceof Array?0===r.length?0:jStat.rows(r):error.value},exports.RSQ=function(r,e){return r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e)?error.value:Math.pow(exports.PEARSON(r,e),2)},exports.SKEW=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=jStat.mean(r),t=r.length,n=0,a=0;t>a;a++)n+=Math.pow(r[a]-e,3);return t*n/((t-1)*(t-2)*Math.pow(jStat.stdev(r,!0),3))},exports.SKEW.P=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=jStat.mean(r),t=r.length,n=0,a=0,u=0;t>u;u++)a+=Math.pow(r[u]-e,3),n+=Math.pow(r[u]-e,2);return a/=t,n/=t,a/Math.pow(n,1.5)},exports.SLOPE=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;for(var t=jStat.mean(e),n=jStat.mean(r),a=e.length,u=0,s=0,i=0;a>i;i++)u+=(e[i]-t)*(r[i]-n),s+=Math.pow(e[i]-t,2);return u/s},exports.SMALL=function(r,e){return r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e)?r:r.sort(function(r,e){return r-e})[e-1]},exports.STANDARDIZE=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:(r-e)/t},exports.STDEV={},exports.STDEV.P=function(){var r=exports.VAR.P.apply(this,arguments);return Math.sqrt(r)},exports.STDEV.S=function(){var r=exports.VAR.S.apply(this,arguments);return Math.sqrt(r)},exports.STDEVA=function(){var r=exports.VARA.apply(this,arguments);return Math.sqrt(r)},exports.STDEVPA=function(){var r=exports.VARPA.apply(this,arguments);return Math.sqrt(r)},exports.STEYX=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;for(var t=jStat.mean(e),n=jStat.mean(r),a=e.length,u=0,s=0,i=0,o=0;a>o;o++)u+=Math.pow(r[o]-n,2),s+=(e[o]-t)*(r[o]-n),i+=Math.pow(e[o]-t,2);return Math.sqrt((u-s*s/i)/(a-2))},exports.TRANSPOSE=function(r){return r?jStat.transpose(r):error.na},exports.T=text.T,exports.T.DIST=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:t?jStat.studentt.cdf(r,e):jStat.studentt.pdf(r,e)},exports.T.DIST["2T"]=function(r,e){return 2!==arguments.length?error.na:0>r||1>e?error.num:"number"!=typeof r||"number"!=typeof e?error.value:2*(1-jStat.studentt.cdf(r,e))},exports.T.DIST.RT=function(r,e){return 2!==arguments.length?error.na:0>r||1>e?error.num:"number"!=typeof r||"number"!=typeof e?error.value:1-jStat.studentt.cdf(r,e)},exports.T.INV=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:jStat.studentt.inv(r,e)},exports.T.INV["2T"]=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),0>=r||r>1||1>e?error.num:utils.anyIsError(r,e)?error.value:Math.abs(jStat.studentt.inv(r/2,e))},exports.T.TEST=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;var t,n=jStat.mean(r),a=jStat.mean(e),u=0,s=0;for(t=0;ta;a++)t+=Math.pow(r[a]-n,2);return t/e},exports.VAR.S=function(){for(var r=utils.numbers(utils.flatten(arguments)),e=r.length,t=0,n=exports.AVERAGE(r),a=0;e>a;a++)t+=Math.pow(r[a]-n,2);return t/(e-1)},exports.VARA=function(){for(var r=utils.flatten(arguments),e=r.length,t=0,n=0,a=exports.AVERAGEA(r),u=0;e>u;u++){var s=r[u];t+="number"==typeof s?Math.pow(s-a,2):s===!0?Math.pow(1-a,2):Math.pow(0-a,2),null!==s&&n++}return t/(n-1)},exports.VARPA=function(){for(var r=utils.flatten(arguments),e=r.length,t=0,n=0,a=exports.AVERAGEA(r),u=0;e>u;u++){var s=r[u];t+="number"==typeof s?Math.pow(s-a,2):s===!0?Math.pow(1-a,2):Math.pow(0-a,2),null!==s&&n++}return t/n},exports.WEIBULL={},exports.WEIBULL.DIST=function(r,e,t,n){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:n?1-Math.exp(-Math.pow(r/t,e)):Math.pow(r,e-1)*Math.exp(-Math.pow(r/t,e))*e/Math.pow(t,e)},exports.Z={},exports.Z.TEST=function(r,e,t){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;t=t||exports.STDEV.S(r);var n=r.length;return 1-exports.NORM.S.DIST((exports.AVERAGE(r)-e)/(t/Math.sqrt(n)),!0)}},function(r,e,t){var n=t(17),a=t(15);e.UNIQUE=function(){for(var r=[],e=0;ee?u.num:new Date(60>=e?s.getTime()+864e5*(e-1):s.getTime()+864e5*(e-2))}return"string"!=typeof r||(r=new Date(r),isNaN(r))?u.value:r},e.parseDateArray=function(r){for(var e,t=r.length;t--;){if(e=this.parseDate(r[t]),e===u.value)return e;r[t]=e}return r},e.anyIsError=function(){for(var r=arguments.length;r--;)if(arguments[r]instanceof Error)return!0;return!1},e.arrayValuesToNumbers=function(r){for(var e,t=r.length;t--;)if(e=r[t],"number"!=typeof e)if(e!==!0)if(e!==!1){if("string"==typeof e){var n=this.parseNumber(e);r[t]=n instanceof Error?0:n}}else r[t]=0;else r[t]=1;return r},e.rest=function(r,e){return e=e||1,r&&"function"==typeof r.slice?r.slice(e):r},e.initial=function(r,e){return e=e||1,r&&"function"==typeof r.slice?r.slice(0,r.length-e):r}},function(r,e){function t(r,e){return r.reduce(function(r,t){return e*r+t},0)}function n(r,e,t,n,a){a||(a=-1);var u,s=2/r;if(0===e)return t;if(1===e)return n;for(var i=1;i!=e;++i)u=n*i*s+a*t,t=n,n=u;return n}function a(r,e,t,a,u){return function(s,i){if(0===i)return r(s);if(1===i)return e(s);if(0>i)throw t+": Order ("+i+") must be nonnegative";if(1==a&&0===s)throw t+": Undefined when x == 0";if(2==a&&0>=s)throw t+": Undefined when x <= 0";var o=r(s),l=e(s);return n(s,i,o,l,u)}}var u=Math,s=function(){function r(r){var e,n,f,p=r*r,c=u.abs(r)-.785398164;return u.abs(r)<8?(n=t(a,p),f=t(s,p),e=n/f):(p=64/p,n=t(i,p),f=t(o,p),e=u.sqrt(l/u.abs(r))*(u.cos(c)*n-u.sin(c)*f*8/u.abs(r))),e}function e(r){var e,n,a,s=r*r,i=u.abs(r)-2.356194491;return Math.abs(r)<8?(n=r*t(f,s),a=t(p,s),e=n/a):(s=64/s,n=t(c,s),a=t(m,s),e=u.sqrt(l/u.abs(r))*(u.cos(i)*n-u.sin(i)*a*8/u.abs(r)),0>r&&(e=-e)),e}var a=[57568490574,-13362590354,651619640.7,-11214424.18,77392.33017,-184.9052456].reverse(),s=[57568490411,1029532985,9494680.718,59272.64853,267.8532712,1].reverse(),i=[1,-.001098628627,2734510407e-14,-2073370639e-15,2.093887211e-7].reverse(),o=[-.01562499995,.0001430488765,-6911147651e-15,7.621095161e-7,-9.34935152e-8].reverse(),l=.636619772,f=[72362614232,-7895059235,242396853.1,-2972611.439,15704.4826,-30.16036606].reverse(),p=[144725228442,2300535178,18583304.74,99447.43394,376.9991397,1].reverse(),c=[1,.00183105,-3516396496e-14,2457520174e-15,-2.40337019e-7].reverse(),m=[.04687499995,-.0002002690873,8449199096e-15,-8.8228987e-7,1.05787412e-7].reverse(); -return function(t,a){if(a=Math.round(a),0===a)return r(u.abs(t));if(1===a)return e(u.abs(t));if(0>a)throw"BESSELJ: Order ("+a+") must be nonnegative";if(0===u.abs(t))return 0;var s,i,o,l,f,p,c,m,N=2/u.abs(t);if(u.abs(t)>a)s=n(t,a,r(u.abs(t)),e(u.abs(t)),-1);else{for(o=2*u.floor((a+u.floor(u.sqrt(40*a)))/2),l=0,p=s=f=0,c=1,i=o;i>0;i--)m=i*N*c-p,p=c,c=m,u.abs(c)>1e10&&(c*=1e-10,p*=1e-10,s*=1e-10,f*=1e-10),l&&(f+=c),l=!l,i==a&&(s=p);f=2*f-c,s/=f}return 0>t&&a%2?-s:s}}(),i=function(){function r(r){var e,a,p,c=r*r,m=r-.785398164;return 8>r?(a=t(n,c),p=t(i,c),e=a/p+f*s(r,0)*u.log(r)):(c=64/c,a=t(o,c),p=t(l,c),e=u.sqrt(f/r)*(u.sin(m)*a+u.cos(m)*p*8/r)),e}function e(r){var e,n,a,i=r*r,o=r-2.356194491;return 8>r?(n=r*t(p,i),a=t(c,i),e=n/a+f*(s(r,1)*u.log(r)-1/r)):(i=64/i,n=t(m,i),a=t(N,i),e=u.sqrt(f/r)*(u.sin(o)*n+u.cos(o)*a*8/r)),e}var n=[-2957821389,7062834065,-512359803.6,10879881.29,-86327.92757,228.4622733].reverse(),i=[40076544269,745249964.8,7189466.438,47447.2647,226.1030244,1].reverse(),o=[1,-.001098628627,2734510407e-14,-2073370639e-15,2.093887211e-7].reverse(),l=[-.01562499995,.0001430488765,-6911147651e-15,7.621095161e-7,-9.34945152e-8].reverse(),f=.636619772,p=[-4900604943e3,127527439e4,-51534381390,734926455.1,-4237922.726,8511.937935].reverse(),c=[249958057e5,424441966400,3733650367,22459040.02,102042.605,354.9632885,1].reverse(),m=[1,.00183105,-3516396496e-14,2457520174e-15,-2.40337019e-7].reverse(),N=[.04687499995,-.0002002690873,8449199096e-15,-8.8228987e-7,1.05787412e-7].reverse();return a(r,e,"BESSELY",1,-1)}(),o=function(){function r(r){return 3.75>=r?t(n,r*r/14.0625):u.exp(u.abs(r))/u.sqrt(u.abs(r))*t(a,3.75/u.abs(r))}function e(r){return 3.75>r?r*t(s,r*r/14.0625):(0>r?-1:1)*u.exp(u.abs(r))/u.sqrt(u.abs(r))*t(i,3.75/u.abs(r))}var n=[1,3.5156229,3.0899424,1.2067492,.2659732,.0360768,.0045813].reverse(),a=[.39894228,.01328592,.00225319,-.00157565,.00916281,-.02057706,.02635537,-.01647633,.00392377].reverse(),s=[.5,.87890594,.51498869,.15084934,.02658733,.00301532,32411e-8].reverse(),i=[.39894228,-.03988024,-.00362018,.00163801,-.01031555,.02282967,-.02895312,.01787654,-.00420059].reverse();return function o(t,n){if(n=Math.round(n),0===n)return r(t);if(1==n)return e(t);if(0>n)throw"BESSELI Order ("+n+") must be nonnegative";if(0===u.abs(t))return 0;var a,s,i,l,f,p,c=2/u.abs(t);for(i=2*u.round((n+u.round(u.sqrt(40*n)))/2),l=a=0,f=1,s=i;s>0;s--)p=s*c*f+l,l=f,f=p,u.abs(f)>1e10&&(f*=1e-10,l*=1e-10,a*=1e-10),s==n&&(a=l);return a*=o(t,0)/f,0>t&&n%2?-a:a}}(),l=function(){function r(r){return 2>=r?-u.log(r/2)*o(r,0)+t(n,r*r/4):u.exp(-r)/u.sqrt(r)*t(s,2/r)}function e(r){return 2>=r?u.log(r/2)*o(r,1)+1/r*t(i,r*r/4):u.exp(-r)/u.sqrt(r)*t(l,2/r)}var n=[-.57721566,.4227842,.23069756,.0348859,.00262698,1075e-7,74e-7].reverse(),s=[1.25331414,-.07832358,.02189568,-.01062446,.00587872,-.0025154,53208e-8].reverse(),i=[1,.15443144,-.67278579,-.18156897,-.01919402,-.00110404,-4686e-8].reverse(),l=[1.25331414,.23498619,-.0365562,.01504268,-.00780353,.00325614,-68245e-8].reverse();return a(r,e,"BESSELK",2,1)}();e.besselj=s,e.bessely=i,e.besseli=o,e.besselk=l}])}); \ No newline at end of file +!function(r,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("numeric"),require("numeral"),require("jStat")):"function"==typeof define&&define.amd?define(["numeric","numeral","jStat"],e):"object"==typeof exports?exports.formulajs=e(require("numeric"),require("numeral"),require("jStat")):r.formulajs=e(r.numeric,r.numeral,r.jStat)}(this,function(__WEBPACK_EXTERNAL_MODULE_3__,__WEBPACK_EXTERNAL_MODULE_8__,__WEBPACK_EXTERNAL_MODULE_9__){return function(r){function e(n){if(t[n])return t[n].exports;var a=t[n]={exports:{},id:n,loaded:!1};return r[n].call(a.exports,a,a.exports,e),a.loaded=!0,a.exports}var t={};return e.m=r,e.c=t,e.p="",e(0)}([function(r,e,t){var n=[t(1),t(15),t(12),t(16),t(2),t(7),t(14),t(17),t(11),t(18),t(6),t(10)];for(var a in n){var u=n[a];for(var s in u)e[s]=e[s]||u[s]}},function(r,e,t){function n(r,e){if(e)for(var t in e)r[t]=e[t];return r}var a=t(2),u=t(6),s=t(12),i=t(14);e.BETADIST=u.BETA.DIST,e.BETAINV=u.BETA.INV,e.BINOMDIST=u.BINOM.DIST,e.CEILING=e.ISOCEILING=n(a.CEILING.MATH,a.CEILING),e.CEILINGMATH=a.CEILING.MATH,e.CEILINGPRECISE=a.CEILING.PRECISE,e.CHIDIST=u.CHISQ.DIST,e.CHIDISTRT=u.CHISQ.DIST.RT,e.CHIINV=u.CHISQ.INV,e.CHIINVRT=u.CHISQ.INV.RT,e.CHITEST=u.CHISQ.TEST,e.CONFIDENCE=n(u.CONFIDENCE.NORM,u.CONFIDENCE),e.COVAR=u.COVARIANCE.P,e.COVARIANCEP=u.COVARIANCE.P,e.COVARIANCES=u.COVARIANCE.S,e.CRITBINOM=u.BINOM.INV,e.EXPONDIST=u.EXPON.DIST,e.ERFCPRECISE=s.ERFC.PRECISE,e.ERFPRECISE=s.ERF.PRECISE,e.FDIST=u.F.DIST,e.FDISTRT=u.F.DIST.RT,e.FINVRT=u.F.INV.RT,e.FINV=u.F.INV,e.FLOOR=n(a.FLOOR.MATH,a.FLOOR),e.FLOORMATH=a.FLOOR.MATH,e.FLOORPRECISE=a.FLOOR.PRECISE,e.FTEST=u.F.TEST,e.GAMMADIST=u.GAMMA.DIST,e.GAMMAINV=u.GAMMA.INV,e.GAMMALNPRECISE=u.GAMMALN.PRECISE,e.HYPGEOMDIST=u.HYPGEOM.DIST,e.LOGINV=u.LOGNORM.INV,e.LOGNORMINV=u.LOGNORM.INV,e.LOGNORMDIST=u.LOGNORM.DIST,e.MODE=n(u.MODE.SNGL,u.MODE),e.MODEMULT=u.MODE.MULT,e.MODESNGL=u.MODE.SNGL,e.NEGBINOMDIST=u.NEGBINOM.DIST,e.NETWORKDAYSINTL=i.NETWORKDAYS.INTL,e.NORMDIST=u.NORM.DIST,e.NORMINV=u.NORM.INV,e.NORMSDIST=u.NORM.S.DIST,e.NORMSINV=u.NORM.S.INV,e.PERCENTILE=n(u.PERCENTILE.EXC,u.PERCENTILE),e.PERCENTILEEXC=u.PERCENTILE.EXC,e.PERCENTILEINC=u.PERCENTILE.INC,e.PERCENTRANK=n(u.PERCENTRANK.INC,u.PERCENTRANK),e.PERCENTRANKEXC=u.PERCENTRANK.EXC,e.PERCENTRANKINC=u.PERCENTRANK.INC,e.POISSON=n(u.POISSON.DIST,u.POISSON),e.POISSONDIST=u.POISSON.DIST,e.QUARTILE=n(u.QUARTILE.INC,u.QUARTILE),e.QUARTILEEXC=u.QUARTILE.EXC,e.QUARTILEINC=u.QUARTILE.INC,e.RANK=n(u.RANK.EQ,u.RANK),e.RANKAVG=u.RANK.AVG,e.RANKEQ=u.RANK.EQ,e.SKEWP=u.SKEW.P,e.STDEV=n(u.STDEV.S,u.STDEV),e.STDEVP=u.STDEV.P,e.STDEVS=u.STDEV.S,e.TDIST=u.T.DIST,e.TDISTRT=u.T.DIST.RT,e.TINV=u.T.INV,e.TTEST=u.T.TEST,e.VAR=n(u.VAR.S,u.VAR),e.VARP=u.VAR.P,e.VARS=u.VAR.S,e.WEIBULL=n(u.WEIBULL.DIST,u.WEIBULL),e.WEIBULLDIST=u.WEIBULL.DIST,e.WORKDAYINTL=i.WORKDAY.INTL,e.ZTEST=u.Z.TEST},function(module,exports,__webpack_require__){var numeric=__webpack_require__(3),utils=__webpack_require__(4),error=__webpack_require__(5),statistical=__webpack_require__(6),information=__webpack_require__(11);exports.ABS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.abs(utils.parseNumber(r))},exports.ACOS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.acos(r)},exports.ACOSH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r+Math.sqrt(r*r-1))},exports.ACOT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.atan(1/r)},exports.ACOTH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:.5*Math.log((r+1)/(r-1))},exports.AGGREGATE=function(r,e,t,n){if(r=utils.parseNumber(r),e=utils.parseNumber(r),utils.anyIsError(r,e))return error.value;switch(r){case 1:return statistical.AVERAGE(t);case 2:return statistical.COUNT(t);case 3:return statistical.COUNTA(t);case 4:return statistical.MAX(t);case 5:return statistical.MIN(t);case 6:return exports.PRODUCT(t);case 7:return statistical.STDEV.S(t);case 8:return statistical.STDEV.P(t);case 9:return exports.SUM(t);case 10:return statistical.VAR.S(t);case 11:return statistical.VAR.P(t);case 12:return statistical.MEDIAN(t);case 13:return statistical.MODE.SNGL(t);case 14:return statistical.LARGE(t,n);case 15:return statistical.SMALL(t,n);case 16:return statistical.PERCENTILE.INC(t,n);case 17:return statistical.QUARTILE.INC(t,n);case 18:return statistical.PERCENTILE.EXC(t,n);case 19:return statistical.QUARTILE.EXC(t,n)}},exports.ARABIC=function(r){if(!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(r))return error.value;var e=0;return r.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,function(r){e+={M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}[r]}),e},exports.ASIN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.asin(r)},exports.ASINH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r+Math.sqrt(r*r+1))},exports.ATAN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.atan(r)},exports.ATAN2=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:Math.atan2(r,e)},exports.ATANH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log((1+r)/(1-r))/2},exports.BASE=function(r,e,t){if(t=t||0,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;t=void 0===t?0:t;var n=r.toString(e);return new Array(Math.max(t+1-n.length,0)).join("0")+n},exports.CEILING=function(r,e,t){return e=void 0===e?1:e,t=void 0===t?0:t,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:0===e?0:(e=Math.abs(e),r>=0?Math.ceil(r/e)*e:0===t?-1*Math.floor(Math.abs(r)/e)*e:-1*Math.ceil(Math.abs(r)/e)*e)},exports.CEILING.MATH=exports.CEILING,exports.CEILING.PRECISE=exports.CEILING,exports.COMBIN=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:exports.FACT(r)/(exports.FACT(e)*exports.FACT(r-e))},exports.COMBINA=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:0===r&&0===e?1:exports.COMBIN(r+e-1,r-1)},exports.COS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.cos(r)},exports.COSH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:(Math.exp(r)+Math.exp(-r))/2},exports.COT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:1/Math.tan(r)},exports.COTH=function(r){if(r=utils.parseNumber(r),r instanceof Error)return r;var e=Math.exp(2*r);return(e+1)/(e-1)},exports.CSC=function(r){return r=utils.parseNumber(r),r instanceof Error?r:1/Math.sin(r)},exports.CSCH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:2/(Math.exp(r)-Math.exp(-r))},exports.DECIMAL=function(r,e){return arguments.length<1?error.value:parseInt(r,e)},exports.DEGREES=function(r){return r=utils.parseNumber(r),r instanceof Error?r:180*r/Math.PI},exports.EVEN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:exports.CEILING(r,-2,-1)},exports.EXP=Math.exp;var MEMOIZED_FACT=[];exports.FACT=function(r){if(r=utils.parseNumber(r),r instanceof Error)return r;var e=Math.floor(r);return 0===e||1===e?1:MEMOIZED_FACT[e]>0?MEMOIZED_FACT[e]:(MEMOIZED_FACT[e]=exports.FACT(e-1)*e,MEMOIZED_FACT[e])},exports.FACTDOUBLE=function(r){if(r=utils.parseNumber(r),r instanceof Error)return r;var e=Math.floor(r);return e<=0?1:e*exports.FACTDOUBLE(e-2)},exports.FLOOR=function(r,e,t){return e=void 0===e?1:e,t=void 0===t?0:t,r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:0===e?0:(e=Math.abs(e),r>=0?Math.floor(r/e)*e:0===t?-1*Math.ceil(Math.abs(r)/e)*e:-1*Math.floor(Math.abs(r)/e)*e)},exports.FLOOR.MATH=exports.FLOOR,exports.FLOOR.PRECISE=exports.FLOOR.MATH,exports.GCD=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=r.length,t=r[0],n=t<0?-t:t,a=1;as?n%=s:s%=n;n+=s}return n},exports.INT=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.floor(r)},exports.ISO={CEILING:exports.CEILING},exports.LCM=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e,t,n,a,u=1;void 0!==(n=r.pop());)for(;n>1;){if(n%2){for(e=3,t=Math.floor(Math.sqrt(n));e<=t&&n%e;e+=2);a=e<=t?e:n}else a=2;for(n/=a,u*=a,e=r.length;e;r[--e]%a===0&&1===(r[e]/=a)&&r.splice(e,1));}return u},exports.LN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r)},exports.LOG=function(r,e){return r=utils.parseNumber(r),e=void 0===e?10:utils.parseNumber(e),utils.anyIsError(r,e)?error.value:Math.log(r)/Math.log(e)},exports.LOG10=function(r){return r=utils.parseNumber(r),r instanceof Error?r:Math.log(r)/Math.log(10)},exports.MDETERM=function(r){return r=utils.parseMatrix(r),r instanceof Error?r:numeric.det(r)},exports.MINVERSE=function(r){return r=utils.parseMatrix(r),r instanceof Error?r:numeric.inv(r)},exports.MMULT=function(r,e){return r=utils.parseMatrix(r),e=utils.parseMatrix(e),utils.anyIsError(r,e)?error.value:numeric.dot(r,e)},exports.MOD=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;if(0===e)return error.div0;var t=Math.abs(r%e);return e>0?t:-t},exports.MROUND=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:r*e<0?error.num:Math.round(r/e)*e},exports.MULTINOMIAL=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=0,t=1,n=0;n0?e:-e},exports.PI=function(){return Math.PI},exports.POWER=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;var t=Math.pow(r,e);return isNaN(t)?error.num:t},exports.PRODUCT=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=1,t=0;t0?1:-1;return t*Math.floor(Math.abs(r)*Math.pow(10,e))/Math.pow(10,e)},exports.ROUNDUP=function(r,e){if(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;var t=r>0?1:-1;return t*Math.ceil(Math.abs(r)*Math.pow(10,e))/Math.pow(10,e)},exports.SEC=function(r){return r=utils.parseNumber(r),r instanceof Error?r:1/Math.cos(r)},exports.SECH=function(r){return r=utils.parseNumber(r),r instanceof Error?r:2/(Math.exp(r)+Math.exp(-r))},exports.SERIESSUM=function(r,e,t,n){if(r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),n=utils.parseNumberArray(n),utils.anyIsError(r,e,t,n))return error.value;for(var a=n[0]*Math.pow(r,e),u=1;u=e)},exports.LT=function(r,e){return 2!==arguments.length?error.na:(r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.error:r=!]/.test(criteria)||(criteria="=="+criteria),/=[^=]/.test(criteria)&&(criteria="="+criteria);for(var result=0,i=0;i0?1:-1;return t*Math.floor(Math.abs(r)*Math.pow(10,e))/Math.pow(10,e)}},function(r,e){r.exports=__WEBPACK_EXTERNAL_MODULE_3__},function(r,e,t){function n(r){return r&&r.reduce?r.reduce(function(r,e){var t=Array.isArray(r),n=Array.isArray(e);return t&&n?r.concat(e):t?(r.push(e),r):n?[r].concat(e):[r,e]}):r}function a(r){if(!r)return!1;for(var e=0;e=t)return n;n++}},exports.CHISQ={},exports.CHISQ.DIST=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:t?jStat.chisquare.cdf(r,e):jStat.chisquare.pdf(r,e)},exports.CHISQ.DIST.RT=function(r,e){return!r|!e?error.na:r<1||e>Math.pow(10,10)?error.num:"number"!=typeof r||"number"!=typeof e?error.value:1-jStat.chisquare.cdf(r,e)},exports.CHISQ.INV=function(r,e){return r=utils.parseNumber(r),e=utils.parseNumber(e),utils.anyIsError(r,e)?error.value:jStat.chisquare.inv(r,e)},exports.CHISQ.INV.RT=function(r,e){return!r|!e?error.na:r<0||r>1||e<1||e>Math.pow(10,10)?error.num:"number"!=typeof r||"number"!=typeof e?error.value:jStat.chisquare.inv(1-r,e)},exports.CHISQ.TEST=function(r,e){function t(r,e){var t=Math.exp(-.5*r);e%2===1&&(t*=Math.sqrt(2*r/f));for(var n=e;n>=2;)t=t*r/n,n-=2;for(var a=t,u=e;a>1e-10*t;)u+=2,a=a*r/u,t+=a;return 1-t}if(2!==arguments.length)return error.na;if(!(r instanceof Array&&e instanceof Array))return error.value;if(r.length!==e.length)return error.value;if(r[0]&&e[0]&&r[0].length!==e[0].length)return error.value;var n,a,u,s=r.length;for(a=0;a=!]/.test(criteria)||(criteria='=="'+criteria+'"');for(var matches=0,i=0;i=!]/.test(criteria)||(criteria='=="'+criteria+'"');for(var j=0;j1?error.num:jStat.centralF.inv(r,e,t)},exports.F.INV.RT=function(r,e,t){return 3!==arguments.length?error.na:r<0||r>1||e<1||e>Math.pow(10,10)||t<1||t>Math.pow(10,10)?error.num:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:jStat.centralF.inv(1-r,e,t)},exports.F.TEST=function(r,e){if(!r||!e)return error.na;if(!(r instanceof Array&&e instanceof Array))return error.na;if(r.length<2||e.length<2)return error.div0;var t=function(r,e){for(var t=0,n=0;ne[u-1]&&r[s]<=e[u]&&(a[u]+=1):u===n&&r[s]>e[n-1]&&(a[n]+=1)}return a},exports.GAMMA=function(r){return r=utils.parseNumber(r),r instanceof Error?r:0===r?error.num:parseInt(r,10)===r&&r<0?error.num:jStat.gammafn(r)},exports.GAMMA.DIST=function(r,e,t,n){return 4!==arguments.length?error.na:r<0||e<=0||t<=0?error.value:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:n?jStat.gamma.cdf(r,e,t,!0):jStat.gamma.pdf(r,e,t,!1)},exports.GAMMA.INV=function(r,e,t){return 3!==arguments.length?error.na:r<0||r>1||e<=0||t<=0?error.num:"number"!=typeof r||"number"!=typeof e||"number"!=typeof t?error.value:jStat.gamma.inv(r,e,t)},exports.GAMMALN=function(r){return r=utils.parseNumber(r),r instanceof Error?r:jStat.gammaln(r)},exports.GAMMALN.PRECISE=function(r){return 1!==arguments.length?error.na:r<=0?error.num:"number"!=typeof r?error.value:jStat.gammaln(r)},exports.GAUSS=function(r){return r=utils.parseNumber(r),r instanceof Error?r:jStat.normal.cdf(r,0,1)-.5},exports.GEOMEAN=function(){var r=utils.parseNumberArray(utils.flatten(arguments));return r instanceof Error?r:jStat.geomean(r)},exports.GROWTH=function(r,e,t,n){if(r=utils.parseNumberArray(r),r instanceof Error)return r;var a;if(void 0===e)for(e=[],a=1;a<=r.length;a++)e.push(a);if(void 0===t)for(t=[],a=1;a<=r.length;a++)t.push(a);if(e=utils.parseNumberArray(e),t=utils.parseNumberArray(t),utils.anyIsError(e,t))return error.value;void 0===n&&(n=!0);var u=r.length,s=0,i=0,o=0,l=0;for(a=0;au&&(u=n[e],a=[]),n[e]===u&&(a[a.length]=e);return a},exports.MODE.SNGL=function(){var r=utils.parseNumberArray(utils.flatten(arguments));return r instanceof Error?r:exports.MODE.MULT(r).sort(function(r,e){return r-e})[0]},exports.NEGBINOM={},exports.NEGBINOM.DIST=function(r,e,t,n){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:n?jStat.negbin.cdf(r,e,t):jStat.negbin.pdf(r,e,t)},exports.NORM={},exports.NORM.DIST=function(r,e,t,n){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:t<=0?error.num:n?jStat.normal.cdf(r,e,t):jStat.normal.pdf(r,e,t)},exports.NORM.INV=function(r,e,t){return r=utils.parseNumber(r),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t)?error.value:jStat.normal.inv(r,e,t)},exports.NORM.S={},exports.NORM.S.DIST=function(r,e){return r=utils.parseNumber(r),r instanceof Error?error.value:e?jStat.normal.cdf(r,0,1):jStat.normal.pdf(r,0,1)},exports.NORM.S.INV=function(r){return r=utils.parseNumber(r),r instanceof Error?error.value:jStat.normal.inv(r,0,1)},exports.PEARSON=function(r,e){if(e=utils.parseNumberArray(utils.flatten(e)),r=utils.parseNumberArray(utils.flatten(r)),utils.anyIsError(e,r))return error.value;for(var t=jStat.mean(r),n=jStat.mean(e),a=r.length,u=0,s=0,i=0,o=0;o1-1/(t+1))return error.num;var n=e*(t+1)-1,a=Math.floor(n);return utils.cleanFloat(n===a?r[n]:r[a]+(n-a)*(r[a+1]-r[a]))},exports.PERCENTILE.INC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;r=r.sort(function(r,e){return r-e});var t=r.length,n=e*(t-1),a=Math.floor(n);return utils.cleanFloat(n===a?r[n]:r[a]+(n-a)*(r[a+1]-r[a]))},exports.PERCENTRANK={},exports.PERCENTRANK.EXC=function(r,e,t){if(t=void 0===t?3:t,r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),t=utils.parseNumber(t),utils.anyIsError(r,e,t))return error.value;r=r.sort(function(r,e){return r-e});for(var n=misc.UNIQUE.apply(null,r),a=r.length,u=n.length,s=Math.pow(10,t),i=0,o=!1,l=0;!o&&l=n[l]&&(e=n[l]&&(e=0?e[r.indexOf(t)]:0;for(var a=r.sort(function(r,e){return r-e}),u=a.length,s=0,i=0;i=t&&a[i]<=n&&(s+=e[r.indexOf(a[i])]);return s},exports.QUARTILE={},exports.QUARTILE.EXC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;switch(e){case 1:return exports.PERCENTILE.EXC(r,.25);case 2:return exports.PERCENTILE.EXC(r,.5);case 3:return exports.PERCENTILE.EXC(r,.75);default:return error.num}},exports.QUARTILE.INC=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumber(e),utils.anyIsError(r,e))return error.value;switch(e){case 1:return exports.PERCENTILE.INC(r,.25);case 2:return exports.PERCENTILE.INC(r,.5);case 3:return exports.PERCENTILE.INC(r,.75);default:return error.num}},exports.RANK={},exports.RANK.AVG=function(r,e,t){if(r=utils.parseNumber(r),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;e=utils.flatten(e),t=t||!1;var n=t?function(r,e){return r-e}:function(r,e){return e-r};e=e.sort(n);for(var a=e.length,u=0,s=0;s1?(2*e.indexOf(r)+u+1)/2:e.indexOf(r)+1},exports.RANK.EQ=function(r,e,t){if(r=utils.parseNumber(r),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;t=t||!1;var n=t?function(r,e){return r-e}:function(r,e){return e-r};return e=e.sort(n),e.indexOf(r)+1},exports.ROW=function(r,e){if(2!==arguments.length)return error.na;if(e<0)return error.num;if(!(r instanceof Array)||"number"!=typeof e)return error.value;if(0!==r.length)return jStat.row(r,e)},exports.ROWS=function(r){return 1!==arguments.length?error.na:r instanceof Array?0===r.length?0:jStat.rows(r):error.value},exports.RSQ=function(r,e){return r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e)?error.value:Math.pow(exports.PEARSON(r,e),2)},exports.SKEW=function(){var r=utils.parseNumberArray(utils.flatten(arguments));if(r instanceof Error)return r;for(var e=jStat.mean(r),t=r.length,n=0,a=0;a1||e<1?error.num:utils.anyIsError(r,e)?error.value:Math.abs(jStat.studentt.inv(r/2,e))},exports.T.TEST=function(r,e){if(r=utils.parseNumberArray(utils.flatten(r)),e=utils.parseNumberArray(utils.flatten(e)),utils.anyIsError(r,e))return error.value;var t,n=jStat.mean(r),a=jStat.mean(e),u=0,s=0;for(t=0;t-1;)r[e]="TRUE";for(var t=0;(t=r.indexOf(!1))>-1;)r[t]="FALSE";return r.join("")},e.DBCS=function(){throw new Error("DBCS is not implemented")},e.DOLLAR=function(r,e){if(e=void 0===e?2:e,r=n.parseNumber(r),e=n.parseNumber(e),n.anyIsError(r,e))return a.value;var t="";return e<=0?(r=Math.round(r*Math.pow(10,e))/Math.pow(10,e),t="($0,0)"):e>0&&(t="($0,0."+new Array(e+1).join("0")+")"),u(r).format(t)},e.EXACT=function(r,e){return r===e},e.FIND=function(r,e,t){return t=void 0===t?0:t,e?e.indexOf(r,t-1)+1:null},e.FIXED=function(r,e,t){if(e=void 0===e?2:e,t=void 0!==t&&t,r=n.parseNumber(r),e=n.parseNumber(e),n.anyIsError(r,e))return a.value;var s=t?"0":"0,0";return e<=0?r=Math.round(r*Math.pow(10,e))/Math.pow(10,e):e>0&&(s+="."+new Array(e+1).join("0")),u(r).format(s)},e.HTML2TEXT=function(r){var e="";return r&&(r instanceof Array?r.forEach(function(r){""!==e&&(e+="\n"),e+=r.replace(/<(?:.|\n)*?>/gm,"")}):e=r.replace(/<(?:.|\n)*?>/gm,"")),e},e.LEFT=function(r,e){return e=void 0===e?1:e,e=n.parseNumber(e),e instanceof Error||"string"!=typeof r?a.value:r?r.substring(0,e):null},e.LEN=function(r){return 0===arguments.length?a.error:"string"==typeof r?r?r.length:0:r.length?r.length:a.value},e.LOWER=function(r){return"string"!=typeof r?a.value:r?r.toLowerCase():r},e.MID=function(r,e,t){if(e=n.parseNumber(e),t=n.parseNumber(t),n.anyIsError(e,t)||"string"!=typeof r)return t;var a=e-1,u=a+t;return r.substring(a,u)},e.NUMBERVALUE=function(r,e,t){return e="undefined"==typeof e?".":e,t="undefined"==typeof t?",":t,Number(r.replace(e,".").replace(t,""))},e.PRONETIC=function(){throw new Error("PRONETIC is not implemented")},e.PROPER=function(r){return void 0===r||0===r.length?a.value:(r===!0&&(r="TRUE"),r===!1&&(r="FALSE"),isNaN(r)&&"number"==typeof r?a.value:("number"==typeof r&&(r=""+r),r.replace(/\w\S*/g,function(r){return r.charAt(0).toUpperCase()+r.substr(1).toLowerCase()})))},e.REGEXEXTRACT=function(r,e){var t=r.match(new RegExp(e));return t?t[t.length>1?t.length-1:0]:null},e.REGEXMATCH=function(r,e,t){var n=r.match(new RegExp(e));return t?n:!!n},e.REGEXREPLACE=function(r,e,t){return r.replace(new RegExp(e),t)},e.REPLACE=function(r,e,t,u){return e=n.parseNumber(e),t=n.parseNumber(t),n.anyIsError(e,t)||"string"!=typeof r||"string"!=typeof u?a.value:r.substr(0,e-1)+u+r.substr(e-1+t)},e.REPT=function(r,e){return e=n.parseNumber(e),e instanceof Error?e:new Array(e+1).join(r)},e.RIGHT=function(r,e){return e=void 0===e?1:e,e=n.parseNumber(e),e instanceof Error?e:r?r.substring(r.length-e):null},e.SEARCH=function(r,e,t){var n;return"string"!=typeof r||"string"!=typeof e?a.value:(t=void 0===t?0:t,n=e.toLowerCase().indexOf(r.toLowerCase(),t-1)+1,0===n?a.value:n)},e.SPLIT=function(r,e){return r.split(e)},e.SUBSTITUTE=function(r,e,t,n){if(!(r&&e&&t))return r;if(void 0===n)return r.replace(new RegExp(e,"g"),t);for(var a=0,u=0;r.indexOf(e,a)>0;)if(a=r.indexOf(e,a+1),u++,u===n)return r.substring(0,a)+t+r.substring(a+e.length)},e.T=function(r){return"string"==typeof r?r:""},e.TEXT=function(r,e){return r=n.parseNumber(r),n.anyIsError(r)?a.na:u(r).format(e)},e.TRIM=function(r){return"string"!=typeof r?a.value:r.replace(/ +/g," ").trim()},e.UNICHAR=this.CHAR,e.UNICODE=this.CODE,e.UPPER=function(r){return"string"!=typeof r?a.value:r.toUpperCase()},e.VALUE=function(r){return"string"!=typeof r?a.value:u().unformat(r)}},function(r,e){r.exports=__WEBPACK_EXTERNAL_MODULE_8__},function(r,e){r.exports=__WEBPACK_EXTERNAL_MODULE_9__},function(r,e,t){var n=t(4),a=t(8);e.UNIQUE=function(){for(var r=[],e=0;e=0||"number"==typeof r&&(isNaN(r)||!isFinite(r))},e.ISERROR=function(r){return e.ISERR(r)||r===n.na},e.ISEVEN=function(r){return!(1&Math.floor(Math.abs(r)))},e.ISFORMULA=function(){throw new Error("ISFORMULA is not implemented")},e.ISLOGICAL=function(r){return r===!0||r===!1},e.ISNA=function(r){return r===n.na},e.ISNONTEXT=function(r){return"string"!=typeof r},e.ISNUMBER=function(r){return"number"==typeof r&&!isNaN(r)&&isFinite(r)},e.ISODD=function(r){return!!(1&Math.floor(Math.abs(r)))},e.ISREF=function(){throw new Error("ISREF is not implemented")},e.ISTEXT=function(r){return"string"==typeof r},e.N=function(r){return this.ISNUMBER(r)?r:r instanceof Date?r.getTime():r===!0?1:r===!1?0:this.ISERROR(r)?r:0},e.NA=function(){return n.na},e.SHEET=function(){throw new Error("SHEET is not implemented")},e.SHEETS=function(){throw new Error("SHEETS is not implemented")},e.TYPE=function(r){return this.ISNUMBER(r)?1:this.ISTEXT(r)?2:this.ISLOGICAL(r)?4:this.ISERROR(r)?16:Array.isArray(r)?64:void 0}},function(r,e,t){function n(r){return/^[01]{1,10}$/.test(r)}var a=t(5),u=t(9).jStat,s=t(7),i=t(4),o=t(13);e.BESSELI=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:o.besseli(r,e)},e.BESSELJ=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:o.besselj(r,e)},e.BESSELK=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:o.besselk(r,e)},e.BESSELY=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:o.bessely(r,e)},e.BIN2DEC=function(r){if(!n(r))return a.num;var e=parseInt(r,2),t=r.toString();return 10===t.length&&"1"===t.substring(0,1)?parseInt(t.substring(1),2)-512:e},e.BIN2HEX=function(r,e){if(!n(r))return a.num;var t=r.toString();if(10===t.length&&"1"===t.substring(0,1))return(0xfffffffe00+parseInt(t.substring(1),2)).toString(16);var u=parseInt(r,2).toString(16);return void 0===e?u:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.BIN2OCT=function(r,e){if(!n(r))return a.num;var t=r.toString();if(10===t.length&&"1"===t.substring(0,1))return(1073741312+parseInt(t.substring(1),2)).toString(8);var u=parseInt(r,2).toString(8);return void 0===e?u:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.BITAND=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r<0||e<0?a.num:Math.floor(r)!==r||Math.floor(e)!==e?a.num:r>0xffffffffffff||e>0xffffffffffff?a.num:r&e},e.BITLSHIFT=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r<0?a.num:Math.floor(r)!==r?a.num:r>0xffffffffffff?a.num:Math.abs(e)>53?a.num:e>=0?r<>-e},e.BITOR=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r<0||e<0?a.num:Math.floor(r)!==r||Math.floor(e)!==e?a.num:r>0xffffffffffff||e>0xffffffffffff?a.num:r|e},e.BITRSHIFT=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r<0?a.num:Math.floor(r)!==r?a.num:r>0xffffffffffff?a.num:Math.abs(e)>53?a.num:e>=0?r>>e:r<<-e},e.BITXOR=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r<0||e<0?a.num:Math.floor(r)!==r||Math.floor(e)!==e?a.num:r>0xffffffffffff||e>0xffffffffffff?a.num:r^e},e.COMPLEX=function(r,e,t){if(r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e))return r;if(t=void 0===t?"i":t,"i"!==t&&"j"!==t)return a.value;if(0===r&&0===e)return 0;if(0===r)return 1===e?t:e.toString()+t;if(0===e)return r.toString();var n=e>0?"+":"";return r.toString()+n+(1===e?t:e.toString()+t)},e.CONVERT=function(r,e,t){if(r=i.parseNumber(r),r instanceof Error)return r;for(var n,u=[["a.u. of action","?",null,"action",!1,!1,1.05457168181818e-34],["a.u. of charge","e",null,"electric_charge",!1,!1,1.60217653141414e-19],["a.u. of energy","Eh",null,"energy",!1,!1,4.35974417757576e-18],["a.u. of length","a?",null,"length",!1,!1,5.29177210818182e-11],["a.u. of mass","m?",null,"mass",!1,!1,9.10938261616162e-31],["a.u. of time","?/Eh",null,"time",!1,!1,2.41888432650516e-17],["admiralty knot","admkn",null,"speed",!1,!0,.514773333],["ampere","A",null,"electric_current",!0,!1,1],["ampere per meter","A/m",null,"magnetic_field_intensity",!0,!1,1],["ångström","Å",["ang"],"length",!1,!0,1e-10],["are","ar",null,"area",!1,!0,100],["astronomical unit","ua",null,"length",!1,!1,1.49597870691667e-11],["bar","bar",null,"pressure",!1,!1,1e5],["barn","b",null,"area",!1,!1,1e-28],["becquerel","Bq",null,"radioactivity",!0,!1,1],["bit","bit",["b"],"information",!1,!0,1],["btu","BTU",["btu"],"energy",!1,!0,1055.05585262],["byte","byte",null,"information",!1,!0,8],["candela","cd",null,"luminous_intensity",!0,!1,1],["candela per square metre","cd/m?",null,"luminance",!0,!1,1],["coulomb","C",null,"electric_charge",!0,!1,1],["cubic ångström","ang3",["ang^3"],"volume",!1,!0,1e-30],["cubic foot","ft3",["ft^3"],"volume",!1,!0,.028316846592],["cubic inch","in3",["in^3"],"volume",!1,!0,16387064e-12],["cubic light-year","ly3",["ly^3"],"volume",!1,!0,8.46786664623715e-47],["cubic metre","m?",null,"volume",!0,!0,1],["cubic mile","mi3",["mi^3"],"volume",!1,!0,4168181825.44058],["cubic nautical mile","Nmi3",["Nmi^3"],"volume",!1,!0,6352182208],["cubic Pica","Pica3",["Picapt3","Pica^3","Picapt^3"],"volume",!1,!0,7.58660370370369e-8],["cubic yard","yd3",["yd^3"],"volume",!1,!0,.764554857984],["cup","cup",null,"volume",!1,!0,.0002365882365],["dalton","Da",["u"],"mass",!1,!1,1.66053886282828e-27],["day","d",["day"],"time",!1,!0,86400],["degree","°",null,"angle",!1,!1,.0174532925199433],["degrees Rankine","Rank",null,"temperature",!1,!0,.555555555555556],["dyne","dyn",["dy"],"force",!1,!0,1e-5],["electronvolt","eV",["ev"],"energy",!1,!0,1.60217656514141],["ell","ell",null,"length",!1,!0,1.143],["erg","erg",["e"],"energy",!1,!0,1e-7],["farad","F",null,"electric_capacitance",!0,!1,1],["fluid ounce","oz",null,"volume",!1,!0,295735295625e-16],["foot","ft",null,"length",!1,!0,.3048],["foot-pound","flb",null,"energy",!1,!0,1.3558179483314],["gal","Gal",null,"acceleration",!1,!1,.01],["gallon","gal",null,"volume",!1,!0,.003785411784],["gauss","G",["ga"],"magnetic_flux_density",!1,!0,1],["grain","grain",null,"mass",!1,!0,647989e-10],["gram","g",null,"mass",!1,!0,.001],["gray","Gy",null,"absorbed_dose",!0,!1,1],["gross registered ton","GRT",["regton"],"volume",!1,!0,2.8316846592],["hectare","ha",null,"area",!1,!0,1e4],["henry","H",null,"inductance",!0,!1,1],["hertz","Hz",null,"frequency",!0,!1,1],["horsepower","HP",["h"],"power",!1,!0,745.69987158227],["horsepower-hour","HPh",["hh","hph"],"energy",!1,!0,2684519.538],["hour","h",["hr"],"time",!1,!0,3600],["imperial gallon (U.K.)","uk_gal",null,"volume",!1,!0,.00454609],["imperial hundredweight","lcwt",["uk_cwt","hweight"],"mass",!1,!0,50.802345],["imperial quart (U.K)","uk_qt",null,"volume",!1,!0,.0011365225],["imperial ton","brton",["uk_ton","LTON"],"mass",!1,!0,1016.046909],["inch","in",null,"length",!1,!0,.0254],["international acre","uk_acre",null,"area",!1,!0,4046.8564224],["IT calorie","cal",null,"energy",!1,!0,4.1868],["joule","J",null,"energy",!0,!0,1],["katal","kat",null,"catalytic_activity",!0,!1,1],["kelvin","K",["kel"],"temperature",!0,!0,1],["kilogram","kg",null,"mass",!0,!0,1],["knot","kn",null,"speed",!1,!0,.514444444444444],["light-year","ly",null,"length",!1,!0,9460730472580800],["litre","L",["l","lt"],"volume",!1,!0,.001],["lumen","lm",null,"luminous_flux",!0,!1,1],["lux","lx",null,"illuminance",!0,!1,1],["maxwell","Mx",null,"magnetic_flux",!1,!1,1e-18],["measurement ton","MTON",null,"volume",!1,!0,1.13267386368],["meter per hour","m/h",["m/hr"],"speed",!1,!0,.00027777777777778],["meter per second","m/s",["m/sec"],"speed",!0,!0,1],["meter per second squared","m?s??",null,"acceleration",!0,!1,1],["parsec","pc",["parsec"],"length",!1,!0,0x6da012f958ee1c],["meter squared per second","m?/s",null,"kinematic_viscosity",!0,!1,1],["metre","m",null,"length",!0,!0,1],["miles per hour","mph",null,"speed",!1,!0,.44704],["millimetre of mercury","mmHg",null,"pressure",!1,!1,133.322],["minute","?",null,"angle",!1,!1,.000290888208665722],["minute","min",["mn"],"time",!1,!0,60],["modern teaspoon","tspm",null,"volume",!1,!0,5e-6],["mole","mol",null,"amount_of_substance",!0,!1,1],["morgen","Morgen",null,"area",!1,!0,2500],["n.u. of action","?",null,"action",!1,!1,1.05457168181818e-34],["n.u. of mass","m?",null,"mass",!1,!1,9.10938261616162e-31],["n.u. of speed","c?",null,"speed",!1,!1,299792458],["n.u. of time","?/(me?c??)",null,"time",!1,!1,1.28808866778687e-21],["nautical mile","M",["Nmi"],"length",!1,!0,1852],["newton","N",null,"force",!0,!0,1],["œrsted","Oe ",null,"magnetic_field_intensity",!1,!1,79.5774715459477],["ohm","Ω",null,"electric_resistance",!0,!1,1],["ounce mass","ozm",null,"mass",!1,!0,.028349523125],["pascal","Pa",null,"pressure",!0,!1,1],["pascal second","Pa?s",null,"dynamic_viscosity",!0,!1,1],["pferdestärke","PS",null,"power",!1,!0,735.49875],["phot","ph",null,"illuminance",!1,!1,1e-4],["pica (1/6 inch)","pica",null,"length",!1,!0,.00035277777777778],["pica (1/72 inch)","Pica",["Picapt"],"length",!1,!0,.00423333333333333],["poise","P",null,"dynamic_viscosity",!1,!1,.1],["pond","pond",null,"force",!1,!0,.00980665],["pound force","lbf",null,"force",!1,!0,4.4482216152605],["pound mass","lbm",null,"mass",!1,!0,.45359237],["quart","qt",null,"volume",!1,!0,.000946352946],["radian","rad",null,"angle",!0,!1,1],["second","?",null,"angle",!1,!1,484813681109536e-20],["second","s",["sec"],"time",!0,!0,1],["short hundredweight","cwt",["shweight"],"mass",!1,!0,45.359237],["siemens","S",null,"electrical_conductance",!0,!1,1],["sievert","Sv",null,"equivalent_dose",!0,!1,1],["slug","sg",null,"mass",!1,!0,14.59390294],["square ångström","ang2",["ang^2"],"area",!1,!0,1e-20],["square foot","ft2",["ft^2"],"area",!1,!0,.09290304],["square inch","in2",["in^2"],"area",!1,!0,64516e-8],["square light-year","ly2",["ly^2"],"area",!1,!0,8.95054210748189e31],["square meter","m?",null,"area",!0,!0,1],["square mile","mi2",["mi^2"],"area",!1,!0,2589988.110336],["square nautical mile","Nmi2",["Nmi^2"],"area",!1,!0,3429904],["square Pica","Pica2",["Picapt2","Pica^2","Picapt^2"],"area",!1,!0,1792111111111e-17],["square yard","yd2",["yd^2"],"area",!1,!0,.83612736],["statute mile","mi",null,"length",!1,!0,1609.344],["steradian","sr",null,"solid_angle",!0,!1,1],["stilb","sb",null,"luminance",!1,!1,1e-4],["stokes","St",null,"kinematic_viscosity",!1,!1,1e-4],["stone","stone",null,"mass",!1,!0,6.35029318],["tablespoon","tbs",null,"volume",!1,!0,147868e-10],["teaspoon","tsp",null,"volume",!1,!0,492892e-11],["tesla","T",null,"magnetic_flux_density",!0,!0,1],["thermodynamic calorie","c",null,"energy",!1,!0,4.184],["ton","ton",null,"mass",!1,!0,907.18474],["tonne","t",null,"mass",!1,!1,1e3],["U.K. pint","uk_pt",null,"volume",!1,!0,.00056826125],["U.S. bushel","bushel",null,"volume",!1,!0,.03523907],["U.S. oil barrel","barrel",null,"volume",!1,!0,.158987295],["U.S. pint","pt",["us_pt"],"volume",!1,!0,.000473176473],["U.S. survey mile","survey_mi",null,"length",!1,!0,1609.347219],["U.S. survey/statute acre","us_acre",null,"area",!1,!0,4046.87261],["volt","V",null,"voltage",!0,!1,1],["watt","W",null,"power",!0,!0,1],["watt-hour","Wh",["wh"],"energy",!1,!0,3600],["weber","Wb",null,"magnetic_flux",!0,!1,1],["yard","yd",null,"length",!1,!0,.9144],["year","yr",null,"time",!1,!0,31557600]],s={Yi:["yobi",80,1.2089258196146292e24,"Yi","yotta"],Zi:["zebi",70,0x400000000000000000,"Zi","zetta"],Ei:["exbi",60,0x1000000000000000,"Ei","exa"],Pi:["pebi",50,0x4000000000000,"Pi","peta"],Ti:["tebi",40,1099511627776,"Ti","tera"],Gi:["gibi",30,1073741824,"Gi","giga"],Mi:["mebi",20,1048576,"Mi","mega"],ki:["kibi",10,1024,"ki","kilo"]},o={Y:["yotta",1e24,"Y"],Z:["zetta",1e21,"Z"],E:["exa",1e18,"E"],P:["peta",1e15,"P"],T:["tera",1e12,"T"],G:["giga",1e9,"G"],M:["mega",1e6,"M"],k:["kilo",1e3,"k"],h:["hecto",100,"h"],e:["dekao",10,"e"],d:["deci",.1,"d"],c:["centi",.01,"c"],m:["milli",.001,"m"],u:["micro",1e-6,"u"],n:["nano",1e-9,"n"],p:["pico",1e-12,"p"],f:["femto",1e-15,"f"],a:["atto",1e-18,"a"],z:["zepto",1e-21,"z"],y:["yocto",1e-24,"y"]},l=null,f=null,p=e,c=t,m=1,E=1,N=0;N=0)&&(l=u[N]),(u[N][1]===c||n.indexOf(c)>=0)&&(f=u[N]);if(null===l){var I=s[e.substring(0,2)],v=o[e.substring(0,1)];"da"===e.substring(0,2)&&(v=["dekao",10,"da"]),I?(m=I[2],p=e.substring(2)):v&&(m=v[1],p=e.substring(v[2].length));for(var h=0;h=0)&&(l=u[h])}if(null===f){var g=s[t.substring(0,2)],M=o[t.substring(0,1)];"da"===t.substring(0,2)&&(M=["dekao",10,"da"]),g?(E=g[2],c=t.substring(2)):M&&(E=M[1],c=t.substring(M[2].length));for(var b=0;b=0)&&(f=u[b])}return null===l||null===f?a.na:l[3]!==f[3]?a.na:r*l[6]*m/(f[6]*E)},e.DEC2BIN=function(r,e){if(r=i.parseNumber(r),r instanceof Error)return r;if(!/^-?[0-9]{1,3}$/.test(r)||r<-512||r>511)return a.num;if(r<0)return"1"+s.REPT("0",9-(512+r).toString(2).length)+(512+r).toString(2);var t=parseInt(r,10).toString(2);return"undefined"==typeof e?t:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=t.length?s.REPT("0",e-t.length)+t:a.num)},e.DEC2HEX=function(r,e){if(r=i.parseNumber(r),r instanceof Error)return r;if(!/^-?[0-9]{1,12}$/.test(r)||r<-549755813888||r>549755813887)return a.num;if(r<0)return(1099511627776+r).toString(16);var t=parseInt(r,10).toString(16);return"undefined"==typeof e?t:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=t.length?s.REPT("0",e-t.length)+t:a.num)},e.DEC2OCT=function(r,e){if(r=i.parseNumber(r),r instanceof Error)return r; +if(!/^-?[0-9]{1,9}$/.test(r)||r<-536870912||r>536870911)return a.num;if(r<0)return(1073741824+r).toString(8);var t=parseInt(r,10).toString(8);return"undefined"==typeof e?t:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=t.length?s.REPT("0",e-t.length)+t:a.num)},e.DELTA=function(r,e){return e=void 0===e?0:e,r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:r===e?1:0},e.ERF=function(r,e){return e=void 0===e?0:e,r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?a.value:u.erf(r)},e.ERF.PRECISE=function(){throw new Error("ERF.PRECISE is not implemented")},e.ERFC=function(r){return isNaN(r)?a.value:u.erfc(r)},e.ERFC.PRECISE=function(){throw new Error("ERFC.PRECISE is not implemented")},e.GESTEP=function(r,e){return e=e||0,r=i.parseNumber(r),i.anyIsError(e,r)?r:r>=e?1:0},e.HEX2BIN=function(r,e){if(!/^[0-9A-Fa-f]{1,10}$/.test(r))return a.num;var t=10===r.length&&"f"===r.substring(0,1).toLowerCase(),n=t?parseInt(r,16)-1099511627776:parseInt(r,16);if(n<-512||n>511)return a.num;if(t)return"1"+s.REPT("0",9-(512+n).toString(2).length)+(512+n).toString(2);var u=n.toString(2);return void 0===e?u:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.HEX2DEC=function(r){if(!/^[0-9A-Fa-f]{1,10}$/.test(r))return a.num;var e=parseInt(r,16);return e>=549755813888?e-1099511627776:e},e.HEX2OCT=function(r,e){if(!/^[0-9A-Fa-f]{1,10}$/.test(r))return a.num;var t=parseInt(r,16);if(t>536870911&&t<0xffe0000000)return a.num;if(t>=0xffe0000000)return(t-0xffc0000000).toString(8);var n=t.toString(8);return void 0===e?n:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=n.length?s.REPT("0",e-n.length)+n:a.num)},e.IMABS=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:Math.sqrt(Math.pow(t,2)+Math.pow(n,2))},e.IMAGINARY=function(r){if(void 0===r||r===!0||r===!1)return a.value;if(0===r||"0"===r)return 0;if(["i","j"].indexOf(r)>=0)return 1;r=r.replace("+i","+1i").replace("-i","-1i").replace("+j","+1j").replace("-j","-1j");var e=r.indexOf("+"),t=r.indexOf("-");0===e&&(e=r.indexOf("+",1)),0===t&&(t=r.indexOf("-",1));var n=r.substring(r.length-1,r.length),u="i"===n||"j"===n;return e>=0||t>=0?u?e>=0?isNaN(r.substring(0,e))||isNaN(r.substring(e+1,r.length-1))?a.num:Number(r.substring(e+1,r.length-1)):isNaN(r.substring(0,t))||isNaN(r.substring(t+1,r.length-1))?a.num:-Number(r.substring(t+1,r.length-1)):a.num:u?isNaN(r.substring(0,r.length-1))?a.num:r.substring(0,r.length-1):isNaN(r)?a.num:0},e.IMARGUMENT=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:0===t&&0===n?a.div0:0===t&&n>0?Math.PI/2:0===t&&n<0?-Math.PI/2:0===n&&t>0?0:0===n&&t<0?-Math.PI:t>0?Math.atan(n/t):t<0&&n>=0?Math.atan(n/t)+Math.PI:Math.atan(n/t)-Math.PI},e.IMCONJUGATE=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",0!==n?e.COMPLEX(t,-n,u):r},e.IMCOS=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.cos(t)*(Math.exp(n)+Math.exp(-n))/2,-Math.sin(t)*(Math.exp(n)-Math.exp(-n))/2,u)},e.IMCOSH=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.cos(n)*(Math.exp(t)+Math.exp(-t))/2,Math.sin(n)*(Math.exp(t)-Math.exp(-t))/2,u)},e.IMCOT=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:e.IMDIV(e.IMCOS(r),e.IMSIN(r))},e.IMDIV=function(r,t){var n=e.IMREAL(r),u=e.IMAGINARY(r),s=e.IMREAL(t),o=e.IMAGINARY(t);if(i.anyIsError(n,u,s,o))return a.value;var l=r.substring(r.length-1),f=t.substring(t.length-1),p="i";if("j"===l?p="j":"j"===f&&(p="j"),0===s&&0===o)return a.num;var c=s*s+o*o;return e.COMPLEX((n*s+u*o)/c,(u*s-n*o)/c,p)},e.IMEXP=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);u="i"===u||"j"===u?u:"i";var s=Math.exp(t);return e.COMPLEX(s*Math.cos(n),s*Math.sin(n),u)},e.IMLN=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.log(Math.sqrt(t*t+n*n)),Math.atan(n/t),u)},e.IMLOG10=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.log(Math.sqrt(t*t+n*n))/Math.log(10),Math.atan(n/t)/Math.log(10),u)},e.IMLOG2=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.log(Math.sqrt(t*t+n*n))/Math.log(2),Math.atan(n/t)/Math.log(2),u)},e.IMPOWER=function(r,t){t=i.parseNumber(t);var n=e.IMREAL(r),u=e.IMAGINARY(r);if(i.anyIsError(t,n,u))return a.value;var s=r.substring(r.length-1);s="i"===s||"j"===s?s:"i";var o=Math.pow(e.IMABS(r),t),l=e.IMARGUMENT(r);return e.COMPLEX(o*Math.cos(t*l),o*Math.sin(t*l),s)},e.IMPRODUCT=function(){for(var r=arguments[0],t=1;t=0)return 0;var e=r.indexOf("+"),t=r.indexOf("-");0===e&&(e=r.indexOf("+",1)),0===t&&(t=r.indexOf("-",1));var n=r.substring(r.length-1,r.length),u="i"===n||"j"===n;return e>=0||t>=0?u?e>=0?isNaN(r.substring(0,e))||isNaN(r.substring(e+1,r.length-1))?a.num:Number(r.substring(0,e)):isNaN(r.substring(0,t))||isNaN(r.substring(t+1,r.length-1))?a.num:Number(r.substring(0,t)):a.num:u?isNaN(r.substring(0,r.length-1))?a.num:0:isNaN(r)?a.num:r},e.IMSEC=function(r){if(r===!0||r===!1)return a.value;var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:e.IMDIV("1",e.IMCOS(r))},e.IMSECH=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.value:e.IMDIV("1",e.IMCOSH(r))},e.IMSIN=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.sin(t)*(Math.exp(n)+Math.exp(-n))/2,Math.cos(t)*(Math.exp(n)-Math.exp(-n))/2,u)},e.IMSINH=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);return u="i"===u||"j"===u?u:"i",e.COMPLEX(Math.cos(n)*(Math.exp(t)-Math.exp(-t))/2,Math.sin(n)*(Math.exp(t)+Math.exp(-t))/2,u)},e.IMSQRT=function(r){var t=e.IMREAL(r),n=e.IMAGINARY(r);if(i.anyIsError(t,n))return a.value;var u=r.substring(r.length-1);u="i"===u||"j"===u?u:"i";var s=Math.sqrt(e.IMABS(r)),o=e.IMARGUMENT(r);return e.COMPLEX(s*Math.cos(o/2),s*Math.sin(o/2),u)},e.IMCSC=function(r){if(r===!0||r===!1)return a.value;var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.num:e.IMDIV("1",e.IMSIN(r))},e.IMCSCH=function(r){if(r===!0||r===!1)return a.value;var t=e.IMREAL(r),n=e.IMAGINARY(r);return i.anyIsError(t,n)?a.num:e.IMDIV("1",e.IMSINH(r))},e.IMSUB=function(r,e){var t=this.IMREAL(r),n=this.IMAGINARY(r),u=this.IMREAL(e),s=this.IMAGINARY(e);if(i.anyIsError(t,n,u,s))return a.value;var o=r.substring(r.length-1),l=e.substring(e.length-1),f="i";return"j"===o?f="j":"j"===l&&(f="j"),this.COMPLEX(t-u,n-s,f)},e.IMSUM=function(){for(var r=i.flatten(arguments),e=r[0],t=1;t511)return a.num;if(t)return"1"+s.REPT("0",9-(512+n).toString(2).length)+(512+n).toString(2);var u=n.toString(2);return"undefined"==typeof e?u:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=u.length?s.REPT("0",e-u.length)+u:a.num)},e.OCT2DEC=function(r){if(!/^[0-7]{1,10}$/.test(r))return a.num;var e=parseInt(r,8);return e>=536870912?e-1073741824:e},e.OCT2HEX=function(r,e){if(!/^[0-7]{1,10}$/.test(r))return a.num;var t=parseInt(r,8);if(t>=536870912)return"ff"+(t+3221225472).toString(16);var n=t.toString(16);return void 0===e?n:isNaN(e)?a.value:e<0?a.num:(e=Math.floor(e),e>=n.length?s.REPT("0",e-n.length)+n:a.num)}},function(r,e,t){function n(r,e){return r.reduce(function(r,t){return e*r+t},0)}function a(r,e,t,n,a){a||(a=-1);var u,s=2/r;if(0===e)return t;if(1===e)return n;for(var i=1;i!=e;++i)u=n*i*s+a*t,t=n,n=u;return n}function u(r,e,t,n,u){return function(s,i){if(0===i)return r(s);if(1===i)return e(s);if(i<0)throw t+": Order ("+i+") must be nonnegative";if(1==n&&0===s)throw t+": Undefined when x == 0";if(2==n&&s<=0)throw t+": Undefined when x <= 0";var o=r(s),l=e(s);return a(s,i,o,l,u)}}var s=Math,i=function(){function r(r){var e,a,f,p=r*r,c=s.abs(r)-.785398164;return s.abs(r)<8?(a=n(t,p),f=n(u,p),e=a/f):(p=64/p,a=n(i,p),f=n(o,p),e=s.sqrt(l/s.abs(r))*(s.cos(c)*a-s.sin(c)*f*8/s.abs(r))),e}function e(r){var e,t,a,u=r*r,i=s.abs(r)-2.356194491;return Math.abs(r)<8?(t=r*n(f,u),a=n(p,u),e=t/a):(u=64/u,t=n(c,u),a=n(m,u),e=s.sqrt(l/s.abs(r))*(s.cos(i)*t-s.sin(i)*a*8/s.abs(r)),r<0&&(e=-e)),e}var t=[57568490574,-13362590354,651619640.7,-11214424.18,77392.33017,-184.9052456].reverse(),u=[57568490411,1029532985,9494680.718,59272.64853,267.8532712,1].reverse(),i=[1,-.001098628627,2734510407e-14,-2073370639e-15,2.093887211e-7].reverse(),o=[-.01562499995,.0001430488765,-6911147651e-15,7.621095161e-7,-9.34935152e-8].reverse(),l=.636619772,f=[72362614232,-7895059235,242396853.1,-2972611.439,15704.4826,-30.16036606].reverse(),p=[144725228442,2300535178,18583304.74,99447.43394,376.9991397,1].reverse(),c=[1,.00183105,-3516396496e-14,2457520174e-15,-2.40337019e-7].reverse(),m=[.04687499995,-.0002002690873,8449199096e-15,-8.8228987e-7,1.05787412e-7].reverse();return function(t,n){if(n=Math.round(n),0===n)return r(s.abs(t));if(1===n)return e(s.abs(t));if(n<0)throw"BESSELJ: Order ("+n+") must be nonnegative";if(0===s.abs(t))return 0;var u,i,o,l,f,p,c,m,E=2/s.abs(t);if(s.abs(t)>n)u=a(t,n,r(s.abs(t)),e(s.abs(t)),-1);else{for(o=2*s.floor((n+s.floor(s.sqrt(40*n)))/2),l=0,p=u=f=0,c=1,i=o;i>0;i--)m=i*E*c-p,p=c,c=m,s.abs(c)>1e10&&(c*=1e-10,p*=1e-10,u*=1e-10,f*=1e-10),l&&(f+=c),l=!l,i==n&&(u=p);f=2*f-c,u/=f}return t<0&&n%2?-u:u}}(),o=function(){function r(r){var e,u,p,c=r*r,m=r-.785398164;return r<8?(u=n(t,c),p=n(a,c),e=u/p+f*i(r,0)*s.log(r)):(c=64/c,u=n(o,c),p=n(l,c),e=s.sqrt(f/r)*(s.sin(m)*u+s.cos(m)*p*8/r)),e}function e(r){var e,t,a,u=r*r,o=r-2.356194491;return r<8?(t=r*n(p,u),a=n(c,u),e=t/a+f*(i(r,1)*s.log(r)-1/r)):(u=64/u,t=n(m,u),a=n(E,u),e=s.sqrt(f/r)*(s.sin(o)*t+s.cos(o)*a*8/r)),e}var t=[-2957821389,7062834065,-512359803.6,10879881.29,-86327.92757,228.4622733].reverse(),a=[40076544269,745249964.8,7189466.438,47447.2647,226.1030244,1].reverse(),o=[1,-.001098628627,2734510407e-14,-2073370639e-15,2.093887211e-7].reverse(),l=[-.01562499995,.0001430488765,-6911147651e-15,7.621095161e-7,-9.34945152e-8].reverse(),f=.636619772,p=[-4900604943e3,127527439e4,-51534381390,734926455.1,-4237922.726,8511.937935].reverse(),c=[249958057e5,424441966400,3733650367,22459040.02,102042.605,354.9632885,1].reverse(),m=[1,.00183105,-3516396496e-14,2457520174e-15,-2.40337019e-7].reverse(),E=[.04687499995,-.0002002690873,8449199096e-15,-8.8228987e-7,1.05787412e-7].reverse();return u(r,e,"BESSELY",1,-1)}(),l=function(){function r(r){return r<=3.75?n(t,r*r/14.0625):s.exp(s.abs(r))/s.sqrt(s.abs(r))*n(a,3.75/s.abs(r))}function e(r){return r<3.75?r*n(u,r*r/14.0625):(r<0?-1:1)*s.exp(s.abs(r))/s.sqrt(s.abs(r))*n(i,3.75/s.abs(r))}var t=[1,3.5156229,3.0899424,1.2067492,.2659732,.0360768,.0045813].reverse(),a=[.39894228,.01328592,.00225319,-.00157565,.00916281,-.02057706,.02635537,-.01647633,.00392377].reverse(),u=[.5,.87890594,.51498869,.15084934,.02658733,.00301532,32411e-8].reverse(),i=[.39894228,-.03988024,-.00362018,.00163801,-.01031555,.02282967,-.02895312,.01787654,-.00420059].reverse();return function t(n,a){if(a=Math.round(a),0===a)return r(n);if(1==a)return e(n);if(a<0)throw"BESSELI Order ("+a+") must be nonnegative";if(0===s.abs(n))return 0;var u,i,o,l,f,p,c=2/s.abs(n);for(o=2*s.round((a+s.round(s.sqrt(40*a)))/2),l=u=0,f=1,i=o;i>0;i--)p=i*c*f+l,l=f,f=p,s.abs(f)>1e10&&(f*=1e-10,l*=1e-10,u*=1e-10),i==a&&(u=l);return u*=t(n,0)/f,n<0&&a%2?-u:u}}(),f=function(){function r(r){return r<=2?-s.log(r/2)*l(r,0)+n(t,r*r/4):s.exp(-r)/s.sqrt(r)*n(a,2/r)}function e(r){return r<=2?s.log(r/2)*l(r,1)+1/r*n(i,r*r/4):s.exp(-r)/s.sqrt(r)*n(o,2/r)}var t=[-.57721566,.4227842,.23069756,.0348859,.00262698,1075e-7,74e-7].reverse(),a=[1.25331414,-.07832358,.02189568,-.01062446,.00587872,-.0025154,53208e-8].reverse(),i=[1,.15443144,-.67278579,-.18156897,-.01919402,-.00110404,-4686e-8].reverse(),o=[1.25331414,.23498619,-.0365562,.01504268,-.00780353,.00325614,-68245e-8].reverse();return u(r,e,"BESSELK",2,1)}();e.besselj=i,e.bessely=o,e.besseli=l,e.besselk=f},function(r,e,t){function n(r){return 1===new Date(r,1,29).getMonth()}function a(r,e){return Math.ceil((e-r)/1e3/60/60/24)}function u(r){var e=r>-22038912e5?2:1;return(r-o)/864e5+e}var s=t(5),i=t(4),o=new Date(1900,0,1),l=[void 0,0,1,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,void 0,1,2,3,4,5,6,0],f=[[],[1,2,3,4,5,6,7],[7,1,2,3,4,5,6],[6,0,1,2,3,4,5],[],[],[],[],[],[],[],[7,1,2,3,4,5,6],[6,7,1,2,3,4,5],[5,6,7,1,2,3,4],[4,5,6,7,1,2,3],[3,4,5,6,7,1,2],[2,3,4,5,6,7,1],[1,2,3,4,5,6,7]],p=[[],[6,0],[0,1],[1,2],[2,3],[3,4],[4,5],[5,6],void 0,void 0,void 0,[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]];e.DATE=function(r,e,t){if(r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),i.anyIsError(r,e,t))return s.value;if(r<0||e<0||t<0)return s.num;var n=new Date(r,e-1,t);return n},e.DATEVALUE=function(r){if("string"!=typeof r)return s.value;var e=Date.parse(r);return isNaN(e)?s.value:e<=-22038912e5?(e-o)/864e5+1:(e-o)/864e5+2},e.DAY=function(r){var e=i.parseDate(r);return e instanceof Error?e:e.getDate()},e.DAYS=function(r,e){return r=i.parseDate(r),e=i.parseDate(e),r instanceof Error?r:e instanceof Error?e:u(r)-u(e)},e.DAYS360=function(r,e,t){if(t=i.parseBool(t),r=i.parseDate(r),e=i.parseDate(e),r instanceof Error)return r;if(e instanceof Error)return e;if(t instanceof Error)return t;var n,a,u=r.getMonth(),s=e.getMonth();if(t)n=31===r.getDate()?30:r.getDate(),a=31===e.getDate()?30:e.getDate();else{var o=new Date(r.getFullYear(),u+1,0).getDate(),l=new Date(e.getFullYear(),s+1,0).getDate();n=r.getDate()===o?30:r.getDate(),e.getDate()===l?n<30?(s++,a=1):a=30:a=e.getDate()}return 360*(e.getFullYear()-r.getFullYear())+30*(s-u)+(a-n)},e.EDATE=function(r,e){return r=i.parseDate(r),r instanceof Error?r:isNaN(e)?s.value:(e=parseInt(e,10),r.setMonth(r.getMonth()+e),u(r))},e.EOMONTH=function(r,e){return r=i.parseDate(r),r instanceof Error?r:isNaN(e)?s.value:(e=parseInt(e,10),u(new Date(r.getFullYear(),r.getMonth()+e+1,0)))},e.HOUR=function(r){return r=i.parseDate(r),r instanceof Error?r:r.getHours()},e.INTERVAL=function(r){if("number"!=typeof r&&"string"!=typeof r)return s.value;r=parseInt(r,10);var e=Math.floor(r/94608e4);r%=94608e4;var t=Math.floor(r/2592e3);r%=2592e3;var n=Math.floor(r/86400);r%=86400;var a=Math.floor(r/3600);r%=3600;var u=Math.floor(r/60);r%=60;var i=r;return e=e>0?e+"Y":"",t=t>0?t+"M":"",n=n>0?n+"D":"",a=a>0?a+"H":"",u=u>0?u+"M":"",i=i>0?i+"S":"","P"+e+t+n+"T"+a+u+i},e.ISOWEEKNUM=function(r){if(r=i.parseDate(r),r instanceof Error)return r;r.setHours(0,0,0),r.setDate(r.getDate()+4-(r.getDay()||7));var e=new Date(r.getFullYear(),0,1);return Math.ceil(((r-e)/864e5+1)/7)},e.MINUTE=function(r){return r=i.parseDate(r),r instanceof Error?r:r.getMinutes()},e.MONTH=function(r){return r=i.parseDate(r),r instanceof Error?r:r.getMonth()+1},e.NETWORKDAYS=function(r,e,t){return this.NETWORKDAYS.INTL(r,e,1,t)},e.NETWORKDAYS.INTL=function(r,e,t,n){if(r=i.parseDate(r),r instanceof Error)return r;if(e=i.parseDate(e),e instanceof Error)return e;if(t=void 0===t?p[1]:p[t],!(t instanceof Array))return s.value;void 0===n?n=[]:n instanceof Array||(n=[n]);for(var a=0;a0?f.getUTCDay():f.getDay(),m=!1;c!==t[0]&&c!==t[1]||(m=!0);for(var E=0;E=a)return!0;var u=e.getFullYear(),s=new Date(u,2,1);return n(u)&&e>=s&&rf||s===f&&u>=l))return(o===p&&n(o)||c(r,e)||1===f&&29===l)&&(m=366),a(r,e)/m;var E=p-o+1,N=(new Date(p+1,0,1)-new Date(o,0,1))/1e3/60/60/24,I=N/E;return a(r,e)/I;case 2:return a(r,e)/360;case 3:return a(r,e)/365;case 4:return(l+30*f+360*p-(u+30*s+360*o))/360}}},function(module,exports,__webpack_require__){function compact(r){if(!r)return r;for(var e=[],t=0;tmaxCriteriaLength&&(maxCriteriaLength=criterias[i].length);for(var k=1;k1?error.num:a[n[0]]},exports.DMAX=function(r,e,t){if(isNaN(e)&&"string"!=typeof e)return error.value;var n=findResultIndex(r,t),a=[];if("string"==typeof e){var u=exports.FINDFIELD(r,e);a=utils.rest(r[u])}else a=utils.rest(r[e]);for(var s=a[n[0]],i=1;ia[n[i]]&&(s=a[n[i]]);return s},exports.DPRODUCT=function(r,e,t){if(isNaN(e)&&"string"!=typeof e)return error.value;var n=findResultIndex(r,t),a=[];if("string"==typeof e){var u=exports.FINDFIELD(r,e);a=utils.rest(r[u])}else a=utils.rest(r[e]);for(var s=[],i=0;i254?n.value:arguments.length0){var e=arguments[0],t=arguments.length-1,n=Math.floor(t/2),a=!1,u=t%2===0?null:arguments[arguments.length-1];if(n)for(var s=0;ss)return u.num;if(0!==o&&1!==o)return u.num;var l=e.PMT(r,t,n,0,o),f=0;1===a&&0===o&&(f=-n,a++);for(var p=a;p<=s;p++)f+=1===o?e.FV(r,p-2,l,n,1)-l:e.FV(r,p-1,l,n,0);return f*=r},e.CUMPRINC=function(r,t,n,a,s,o){if(r=i.parseNumber(r),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,t,n))return u.value;if(r<=0||t<=0||n<=0)return u.num;if(a<1||s<1||a>s)return u.num;if(0!==o&&1!==o)return u.num;var l=e.PMT(r,t,n,0,o),f=0;1===a&&(f=0===o?l+n*r:l,a++);for(var p=a;p<=s;p++)f+=o>0?l-(e.FV(r,p-2,l,n,1)-l)*r:l-e.FV(r,p-1,l,n,0)*r;return f},e.DB=function(r,e,t,n,a){if(a=void 0===a?12:a,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;if(r<0||e<0||t<0||n<0)return u.num;if([1,2,3,4,5,6,7,8,9,10,11,12].indexOf(a)===-1)return u.num;if(n>t)return u.num;if(e>=r)return 0;for(var s=(1-Math.pow(e/r,1/t)).toFixed(3),o=r*s*a/12,l=o,f=0,p=n===t?t-1:n,c=2;c<=p;c++)f=(r-l)*s,l+=f;return 1===n?o:n===t?(r-l)*s:f},e.DDB=function(r,e,t,n,a){if(a=void 0===a?2:a,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;if(r<0||e<0||t<0||n<0||a<=0)return u.num;if(n>t)return u.num;if(e>=r)return 0;for(var s=0,o=0,l=1;l<=n;l++)o=Math.min((r-s)*(a/t),r-e-s),s+=o;return o},e.DISC=function(){throw new Error("DISC is not implemented")},e.DOLLARDE=function(r,e){if(r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e))return u.value;if(e<0)return u.num;if(e>=0&&e<1)return u.div0;e=parseInt(e,10);var t=parseInt(r,10);t+=r%1*Math.pow(10,Math.ceil(Math.log(e)/Math.LN10))/e;var n=Math.pow(10,Math.ceil(Math.log(e)/Math.LN2)+1);return t=Math.round(t*n)/n},e.DOLLARFR=function(r,e){if(r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e))return u.value;if(e<0)return u.num;if(e>=0&&e<1)return u.div0;e=parseInt(e,10);var t=parseInt(r,10);return t+=r%1*Math.pow(10,-Math.ceil(Math.log(e)/Math.LN10))*e},e.DURATION=function(){throw new Error("DURATION is not implemented")},e.EFFECT=function(r,e){return r=i.parseNumber(r),e=i.parseNumber(e),i.anyIsError(r,e)?u.value:r<=0||e<1?u.num:(e=parseInt(e,10),Math.pow(1+r/e,e)-1)},e.FV=function(r,e,t,n,a){if(n=n||0,a=a||0,r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),a=i.parseNumber(a),i.anyIsError(r,e,t,n,a))return u.value;var s;if(0===r)s=n+t*e;else{var o=Math.pow(1+r,e);s=1===a?n*o+t*(1+r)*(o-1)/r:n*o+t*(o-1)/r}return-s},e.FVSCHEDULE=function(r,e){if(r=i.parseNumber(r),e=i.parseNumberArray(i.flatten(e)),i.anyIsError(r,e))return u.value;for(var t=e.length,n=r,a=0;a0&&(s=!0),r[l]<0&&(o=!0);if(!s||!o)return u.num;e=void 0===e?.1:e;var f,p,c,m=e,E=1e-10,N=!0;do c=t(r,a,m),f=m-c/n(r,a,m),p=Math.abs(f-m),m=f,N=p>E&&Math.abs(c)>E;while(N);return m},e.ISPMT=function(r,e,t,n){return r=i.parseNumber(r),e=i.parseNumber(e),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,e,t,n)?u.value:n*r*(e/t-1)},e.MDURATION=function(){throw new Error("MDURATION is not implemented")},e.MIRR=function(r,t,n){if(r=i.parseNumberArray(i.flatten(r)),t=i.parseNumber(t),n=i.parseNumber(n),i.anyIsError(r,t,n))return u.value;for(var a=r.length,s=[],o=[],l=0;lt?u.num:(n=parseInt(n,10),(r-e)*(t-n+1)*2/(t*(t+1)))},e.TBILLEQ=function(r,e,t){return r=i.parseDate(r),e=i.parseDate(e),t=i.parseNumber(t),i.anyIsError(r,e,t)?u.value:t<=0?u.num:r>e?u.num:e-r>31536e6?u.num:365*t/(360-t*s.DAYS360(r,e,!1))},e.TBILLPRICE=function(r,e,t){return r=i.parseDate(r),e=i.parseDate(e),t=i.parseNumber(t),i.anyIsError(r,e,t)?u.value:t<=0?u.num:r>e?u.num:e-r>31536e6?u.num:100*(1-t*s.DAYS360(r,e,!1)/360)},e.TBILLYIELD=function(r,e,t){return r=i.parseDate(r),e=i.parseDate(e),t=i.parseNumber(t),i.anyIsError(r,e,t)?u.value:t<=0?u.num:r>e?u.num:e-r>31536e6?u.num:360*(100-t)/(t*s.DAYS360(r,e,!1))},e.VDB=function(){throw new Error("VDB is not implemented")},e.XIRR=function(r,e,t){if(r=i.parseNumberArray(i.flatten(r)),e=i.parseDateArray(i.flatten(e)),t=i.parseNumber(t),i.anyIsError(r,e,t))return u.value;for(var n=function(r,e,t){for(var n=t+1,a=r[0],u=1;u0&&(o=!0),r[f]<0&&(l=!0);if(!o||!l)return u.num;t=t||.1;var p,c,m,E=t,N=1e-10,I=!0;do m=n(r,e,E),p=E-m/a(r,e,E),c=Math.abs(p-E),E=p,I=c>N&&Math.abs(m)>N;while(I);return E},e.XNPV=function(r,e,t){if(r=i.parseNumber(r),e=i.parseNumberArray(i.flatten(e)),t=i.parseDateArray(i.flatten(t)),i.anyIsError(r,e,t))return u.value;for(var n=0,a=0;au&&(a=s+1,u=e[s]):(a=s+1,u=e[s]))}else if(0===t){if("string"==typeof r){if(r=r.replace(/\?/g,"."),e[s].toLowerCase().match(r.toLowerCase()))return s+1}else if(e[s]===r)return s+1}else if(t===-1){if(e[s]===r)return s+1;e[s]>r&&(u?e[s]=!]/.test(criteria)) { + criteria = '==' + criteria; + } + if (/=[^=]/.test(criteria)) { + criteria = '=' + criteria; } var result = 0; for (var i = 0; i < range.length; i++) { - result += (eval(range[i] + criteria)) ? range[i] : 0; // jshint ignore:line + result += (eval(range[i] + criteria)) ? sum_range[i] : 0; // jshint ignore:line } return result; }; diff --git a/test/math-trig.js b/test/math-trig.js index 136da758..3cdcd660 100644 --- a/test/math-trig.js +++ b/test/math-trig.js @@ -700,6 +700,9 @@ suite('Math & Trig', function() { test("SUMIF", function() { mathTrig.SUMIF([1, 2, 3], '>2').should.equal(3); + mathTrig.SUMIF([1, 2, 3], '=2').should.equal(2); + mathTrig.SUMIF([1, 2, 3], '>2', [4, 5, 6]).should.equal(6); + mathTrig.SUMIF(['"A"', '"B"', '"B"'], '"B"', [1, 2, 3]).should.equal(5); mathTrig.SUMIF([ [1, 1], [2, 2],