diff --git a/.npmignore b/.npmignore index 1fa0fb7..e5dec87 100644 --- a/.npmignore +++ b/.npmignore @@ -11,5 +11,4 @@ package-lock.json yarn.lock gulpfile.js LICENSE -README.md CHANGELOG.md diff --git a/README.md b/README.md index e47e28e..96b0947 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,13 @@ [![Contributors][contributors-image]][contributors-url] [![Pull Requests Welcome][pull-requests-image]][pull-requests-url] -A collection of useful helper functions. +A collection of useful JavaScript helper functions. -## Client-Side Usage +## Documentation + +Work-in-progress API documentation is available [here][documentation-url]. + +## Web Usage ```html @@ -22,12 +26,12 @@ A collection of useful helper functions. ``` -## Server-Side Usage +## Node.js Usage ```javascript const utilities = require("extra-utilities"); -utilities.isBoolean(false); // => true +utilities.isValidNumber(NaN); // => false ``` ## Installation @@ -43,11 +47,21 @@ To build the distribution files for this module: ```bash npm run build ``` -or + +## Running Unit Tests + +To run the unit test suite for this module: +```bash +npm run test +``` + +## Generating Documentation ```bash -gulp build +npm run docs ``` +[documentation-url]: https://nitro404.github.io/extra-utilities/module-utilities.html + [npm-url]: https://www.npmjs.com/package/extra-utilities [npm-version-image]: https://img.shields.io/npm/v/extra-utilities.svg [npm-downloads-image]: http://img.shields.io/npm/dm/extra-utilities.svg diff --git a/dist/extra-utilities.js b/dist/extra-utilities.js index 6ca84c9..ce5009d 100644 --- a/dist/extra-utilities.js +++ b/dist/extra-utilities.js @@ -7,10 +7,6 @@ "use strict"; if(typeof require !== "undefined") { - if(typeof validator === "undefined") { - global.validator = require("validator"); - } - if(typeof changeCase === "undefined") { global.changeCase = require("change-case-bundled"); } @@ -69,6 +65,38 @@ return typeof value !== "number" || isNaN(value) || value === -Infinity || value === Infinity; }; + utilities.isInteger = function isInteger(value, allowObjects) { + if(Number.isInteger(value)) { + return true; + } + + if(value instanceof Number && utilities.parseBoolean(allowObjects, true)) { + return Number.isInteger(value.valueOf()); + } + + if(typeof value !== "string") { + return false; + } + + return !!value.match(/^([+-]?[1-9][0-9]*|0)$/); + }; + + utilities.isFloat = function isFloat(value, allowObjects) { + if(typeof value === "number") { + return !isNaN(value) && isFinite(value); + } + + if(value instanceof Number && utilities.parseBoolean(allowObjects, true)) { + return true; + } + + if(typeof value !== "string") { + return false; + } + + return !!value.match(/^([+-]?(((([1-9][0-9]*|0)?\.)[0-9]+)|([1-9][0-9]*|0)))$/); + }; + utilities.isEmptyString = function isEmptyString(value, trim) { return typeof value !== "string" || (utilities.parseBoolean(trim, true) ? value.trim().length === 0 : value.length === 0); }; @@ -321,10 +349,13 @@ newValue = parseInt(value); } else if(typeof value === "string") { - if(validator.isFloat(value)) { + if(utilities.isFloat(value)) { newValue = parseInt(value); } } + else if(value instanceof Number) { + newValue = parseInt(value.valueOf()); + } if(utilities.isInvalidNumber(newValue)) { defaultValue = parseInt(defaultValue); @@ -335,17 +366,20 @@ return newValue; }; - utilities.parseFloatingPointNumber = function parseFloatingPointNumber(value, defaultValue) { + utilities.parseFloat = function parseFloatingPointNumber(value, defaultValue) { var newValue = NaN; if(typeof value === "number") { newValue = value; } else if(typeof value === "string") { - if(validator.isFloat(value)) { + if(utilities.isFloat(value)) { newValue = parseFloat(value); } } + else if(value instanceof Number) { + newValue = value.valueOf(); + } if(utilities.isInvalidNumber(newValue)) { return utilities.isValidNumber(defaultValue) ? defaultValue : NaN; @@ -354,13 +388,15 @@ return newValue; }; + utilities.parseFloatingPointNumber = utilities.parseFloat; + utilities.parseDate = function parseDate(value, defaultValue) { if(!utilities.isDate(defaultValue)) { defaultValue = null; } if(typeof value === "number") { - if(utilities.isInvalidNumber(value) || !Number.isInteger(value)) { + if(utilities.isInvalidNumber(value) || !Number.isInteger(value) || value < 0) { return defaultValue; } @@ -375,7 +411,7 @@ var timestamp = null; - if(validator.isInt(formattedValue)) { + if(utilities.isInteger(formattedValue)) { timestamp = parseInt(formattedValue); } else { @@ -395,15 +431,9 @@ return defaultValue; }; - utilities.parseTime = function parseTime(value, throwErrors) { - throwErrors = utilities.parseBoolean(throwErrors); - + utilities.parseTime = function parseTime(value) { if(utilities.isEmptyString(value)) { - if(throwErrors) { - throw new Error("Invalid or empty time value."); - } - - return null; + throw new Error("Invalid or empty time value."); } var formattedValue = value.trim(); @@ -415,11 +445,7 @@ var regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2])); if(utilities.isInvalidNumber(regularHour)) { - if(throwErrors) { - throw new Error("Invalid regular hour: \"" + regularTime[2] + "\"."); - } - - return null; + throw new Error("Invalid regular hour: \"" + regularTime[2] + "\"."); } minutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4])); @@ -432,11 +458,7 @@ var morning = period === "AM" ? true : (period === "PM" ? false : null); if(morning === null) { - if(throwErrors) { - throw new Error("Invalid period: \"" + regularTime[5] + "\"."); - } - - return null; + throw new Error("Invalid period: \"" + regularTime[5] + "\"."); } hour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12); @@ -461,31 +483,19 @@ } if(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) { - if(throwErrors) { - throw new Error("Invalid military time: \"" + formattedValue + "\"."); - } - - return null; + throw new Error("Invalid military time: \"" + formattedValue + "\"."); } hour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour)); if(utilities.isInvalidNumber(hour)) { - if(throwErrors) { - throw new Error("Invalid military time hour: \"" + militaryHour + "\"."); - } - - return null; + throw new Error("Invalid military time hour: \"" + militaryHour + "\"."); } minutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes)); if(utilities.isInvalidNumber(minutes)) { - if(throwErrors) { - throw new Error("Invalid military time minutes: \"" + militaryMinutes + "\"."); - } - - return null; + throw new Error("Invalid military time minutes: \"" + militaryMinutes + "\"."); } if(hour === 24 && minutes === 0) { @@ -493,27 +503,15 @@ } } else { - if(throwErrors) { - throw new Error("Invalid time: \"" + formattedValue + "\"."); - } - - return null; + throw new Error("Invalid time: \"" + formattedValue + "\"."); } } if(hour < 0 || hour > 23) { - if(throwErrors) { - throw new Error("Time hour is out of range (0 - 23): \"" + hour + "\"."); - } - - return null; + throw new Error("Time hour is out of range (0 - 23): \"" + hour + "\"."); } else if(minutes < 0 || minutes > 59) { - if(throwErrors) { - throw new Error("Time minutes is out of range (0 - 59): \"" + minutes + "\"."); - } - - return null; + throw new Error("Time minutes is out of range (0 - 59): \"" + minutes + "\"."); } var regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12); @@ -614,14 +612,14 @@ return null; } - if(throwErrors) { - return new RegExp(regExpData[1], regExpData[2]); - } - try { return new RegExp(regExpData[1], regExpData[2]); } catch(error) { + if(throwErrors) { + throw error; + } + return null; } }; @@ -1411,12 +1409,12 @@ }; utilities.trimString = function trimString(value, defaultValue) { - return typeof value === "string" ? value.trim() : (defaultValue === undefined ? null : defaultValue); + return typeof value === "string" ? value.trim() : (typeof defaultValue === "string" ? defaultValue : null); }; utilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) { if(typeof value !== "string") { - return defaultValue === undefined ? null : defaultValue; + return typeof defaultValue === "string" ? defaultValue : null; } var nullTerminatorIndex = value.indexOf("\0"); @@ -1428,9 +1426,9 @@ return value; }; - utilities.trimWhitespace = function trimWhitespace(value, trimNewlines) { + utilities.trimWhitespace = function trimWhitespace(value, trimNewlines, defaultValue) { if(typeof value !== "string") { - return null; + return typeof defaultValue === "string" ? defaultValue : null; } var trimmedString = value.replace(/^[ \t]+|[ \t]+$/gm, ""); @@ -1442,9 +1440,9 @@ return trimmedString; }; - utilities.trimTrailingNewlines = function trimTrailingNewlines(value) { + utilities.trimTrailingNewlines = function trimTrailingNewlines(value, defaultValue) { if(typeof value !== "string") { - return null; + return typeof defaultValue === "string" ? defaultValue : null; } if(utilities.isEmptyString(value)) { @@ -1553,10 +1551,10 @@ else if(typeof value === "number" && isNaN(value)) { return "NaN"; } - else if(utilities.isDate(value)) { + else if(value instanceof Date) { return value.toString(); } - else if(utilities.isRegularExpression(value)) { + else if(value instanceof RegExp) { var flags = ""; for(var flag in regExpFlags) { @@ -1567,17 +1565,11 @@ return "/" + value.source + "/" + flags; } - else if(utilities.isFunction(value)) { + else if(value instanceof Function) { return value.toString(); } - else if(utilities.isError(value)) { - var error = { message: value.message }; - - for(var attribute in value) { - error[attribute] = value[attribute]; - } - - return JSON.stringify(error); + else if(value instanceof Error) { + return value.stack; } return JSON.stringify(value); @@ -1949,24 +1941,56 @@ return formattedValue; }; - utilities.joinPaths = function joinPaths(base, path) { - var formattedBase = typeof base === "string" ? base.trim().replace(/[\/\\]+$/, "") : null; - var formattedPath = typeof path === "string" ? path.trim().replace(/^[\/\\]+/, "") : null; + utilities.joinPaths = function joinPaths(paths, options) { + if(!Array.isArray(paths)) { + paths = Array.prototype.slice.call(arguments); + } + + if(paths.length !== 0 && utilities.isObjectStrict(paths[paths.length - 1])) { + options = paths.splice(paths.length - 1, 1)[0]; + } + + if(!utilities.isObjectStrict(options)) { + options = { }; + } + + options.separator = utilities.trimString(options.separator); + + if(options.separator !== "/" && options.separator !== "\\") { + options.separator = "/"; + } + var newPath = ""; - if(utilities.isNonEmptyString(formattedBase)) { - newPath += formattedBase; + for(var i = 0; i < paths.length; i++) { + var path = utilities.trimString(paths[i]); - if(utilities.isNonEmptyString(formattedPath)) { - newPath += "/"; + if(utilities.isEmptyString(path)) { + continue; } - } - if(utilities.isNonEmptyString(formattedPath)) { - newPath += formattedPath; + if(utilities.isEmptyString(newPath)) { + if(path === "/" || path === "\\") { + newPath = path; + } + else { + newPath = path.replace(/[\/\\]+$/, ""); + } + } + else { + path = path.replace(/^[\/\\]+/, ""); + + if(utilities.isNonEmptyString(path)) { + if(newPath[newPath.length - 1] !== options.separator) { + newPath += options.separator; + } + + newPath += path; + } + } } - return newPath; + return newPath.replace(/[\/\\]/g, options.separator); }; utilities.createQueryString = function createQueryString(value, includeQuestionMark) { @@ -2207,7 +2231,7 @@ var part = null; for(var i = 0; i < versionData.length; i++) { - if(validator.isInt(versionData[i])) { + if(utilities.isInteger(versionData[i])) { part = utilities.parseInteger(versionData[i]); if(utilities.isInvalidNumber(part) || part < 0) { @@ -2239,28 +2263,19 @@ return version.length === 0 ? null : version; }; - utilities.compareVersions = function compareVersions(v1, v2, caseSensitive, throwErrors) { + utilities.compareVersions = function compareVersions(v1, v2, caseSensitive) { caseSensitive = utilities.parseBoolean(caseSensitive, false); - throwErrors = utilities.parseBoolean(throwErrors, false); v1 = utilities.parseVersion(v1); if(v1 === null) { - if(throwErrors) { - throw new Error("Cannot compare invalid or empty first version."); - } - - return null; + throw new Error("Cannot compare invalid or empty first version."); } v2 = utilities.parseVersion(v2); if(v2 === null) { - if(throwErrors) { - throw new Error("Cannot compare invalid or empty second version."); - } - - return null; + throw new Error("Cannot compare invalid or empty second version."); } var index = 0; diff --git a/dist/extra-utilities.js.map b/dist/extra-utilities.js.map index 006d4df..bb2ef5b 100644 --- a/dist/extra-utilities.js.map +++ b/dist/extra-utilities.js.map @@ -1 +1 @@ -{"version":3,"names":[],"mappings":"","sources":["extra-utilities.js"],"sourcesContent":["(function(global, factory) {\n\ttypeof exports === \"object\" && typeof module !== \"undefined\" ? module.exports = factory() :\n\ttypeof define === \"function\" && define.amd ? define(factory) :\n\t(global.utilities = factory());\n} (this, function() {\n\n\t\"use strict\";\n\n\tif(typeof require !== \"undefined\") {\n\t\tif(typeof validator === \"undefined\") {\n\t\t\tglobal.validator = require(\"validator\");\n\t\t}\n\n\t\tif(typeof changeCase === \"undefined\") {\n\t\t\tglobal.changeCase = require(\"change-case-bundled\");\n\t\t}\n\t}\n\n\tvar utilities = { };\n\n\tvar regExpFlags = {\n\t\tglobal: \"g\",\n\t\tmultiline: \"m\",\n\t\tignoreCase: \"i\",\n\t\tsticky: \"y\",\n\t\tunicode: \"u\"\n\t};\n\n\tvar formatTypes = [\"boolean\", \"bool\", \"integer\", \"int\", \"float\", \"number\", \"string\", \"object\", \"array\", \"date\", \"regex\", \"regexp\", \"regularexpression\", \"function\", \"func\"];\n\n\tvar stringCaseFunctions = {\n\t\tcamel: changeCase.camelCase,\n\t\tcapital: changeCase.capitalCase,\n\t\tconstant: changeCase.constantCase,\n\t\tdot: changeCase.dotCase,\n\t\theader: changeCase.headerCase,\n\t\tlower: changeCase.lowerCase,\n\t\tlowerFirst: changeCase.lowerCaseFirst,\n\t\tno: changeCase.noCase,\n\t\tparam: changeCase.paramCase,\n\t\tpascal: changeCase.pascalCase,\n\t\tpath: changeCase.pathCase,\n\t\tsentence: changeCase.sentenceCase,\n\t\tsnake: changeCase.snakeCase,\n\t\tsponge: changeCase.spongeCase,\n\t\tswap: changeCase.swapCase,\n\t\ttitle: changeCase.titleCase,\n\t\tupper: changeCase.upperCase,\n\t\tupperFirst: changeCase.upperCaseFirst\n\t};\n\n\tutilities.isValid = function isValid(value) {\n\t\treturn value !== undefined && value !== null;\n\t};\n\n\tutilities.isInvalid = function isInvalid(value) {\n\t\treturn value === undefined || value === null;\n\t};\n\n\tutilities.isBoolean = function isBoolean(value, allowObjects) {\n\t\treturn value === true || value === false || (!!allowObjects && value instanceof Boolean);\n\t};\n\n\tutilities.isValidNumber = function isValidNumber(value) {\n\t\treturn typeof value === \"number\" && !isNaN(value) && value !== -Infinity && value !== Infinity;\n\t};\n\n\tutilities.isInvalidNumber = function isInvalidNumber(value) {\n\t\treturn typeof value !== \"number\" || isNaN(value) || value === -Infinity || value === Infinity;\n\t};\n\n\tutilities.isEmptyString = function isEmptyString(value, trim) {\n\t\treturn typeof value !== \"string\" || (utilities.parseBoolean(trim, true) ? value.trim().length === 0 : value.length === 0);\n\t};\n\n\tutilities.isNonEmptyString = function isNonEmptyString(value, trim) {\n\t\treturn typeof value === \"string\" && (utilities.parseBoolean(trim, true) ? value.trim().length !== 0 : value.length !== 0);\n\t};\n\n\tutilities.isObject = function isObject(value, strict) {\n\t\treturn value !== undefined && (strict ? value !== null && value.constructor === Object : value instanceof Object && !(value instanceof Function));\n\t};\n\n\tutilities.isObjectStrict = function isObjectStrict(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object;\n\t};\n\n\tutilities.isEmptyObject = function isEmptyObject(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length === 0;\n\t};\n\n\tutilities.isNonEmptyObject = function isNonEmptyObject(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length !== 0;\n\t};\n\n\tutilities.isEmptyArray = function isEmptyArray(value) {\n\t\treturn Array.isArray(value) ? value.length === 0 : true;\n\t};\n\n\tutilities.isNonEmptyArray = function isNonEmptyArray(value) {\n\t\treturn Array.isArray(value) && value.length !== 0;\n\t};\n\n\tutilities.isDate = function isDate(value) {\n\t\treturn value instanceof Date;\n\t};\n\n\tutilities.isError = function isError(value) {\n\t\treturn value instanceof Error;\n\t};\n\n\tutilities.isRegularExpression = function isRegularExpression(value) {\n\t\treturn value instanceof RegExp;\n\t};\n\n\tutilities.isFunction = function isFunction(value) {\n\t\treturn value instanceof Function;\n\t};\n\n\tutilities.isComment = function isComment(value, comment) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(comment)) {\n\t\t\tcomment = \"//\";\n\t\t}\n\n\t\tvar commentStartIndex = -1;\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tif(value[i] === \" \" || value[i] == \"\\t\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(value[i] == comment[0]) {\n\t\t\t\tcommentStartIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif(commentStartIndex < 0 || value.length - commentStartIndex < comment.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor(var i = commentStartIndex; i < value.length; i++) {\n\t\t\tif(i - commentStartIndex >= comment.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(value[i] != comment[i - commentStartIndex]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isVisible = function isVisible(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn !element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn !element.hidden();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isHidden = function isHidden(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn !element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn !element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn element.hidden();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.isEnabled = function isEnabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn !element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn !element.disabled();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isDisabled = function isDisabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn !element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn !element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn element.disabled();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) {\n\t\tif(typeof stringA !== \"string\" || typeof stringB !== \"string\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn stringA.localeCompare(stringB, undefined, { sensitivity: \"accent\" }) === 0;\n\t};\n\n\tutilities.parseBoolean = function parseBoolean(value, defaultValue) {\n\t\tif(utilities.isBoolean(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isBoolean(value, true)) {\n\t\t\treturn value.valueOf();\n\t\t}\n\n\t\tif(!utilities.isBoolean(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(value === 0) {\n\t\t\treturn false;\n\t\t}\n\t\telse if(value === 1) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tvar formattedValue = value.trim().toLowerCase();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue.length === 1) {\n\t\t\tvar character = formattedValue.charAt(0);\n\n\t\t\tif(character === \"t\" || character === \"y\") {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if(character === \"f\" || character === \"n\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"0\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"1\") {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue === \"true\" || formattedValue === \"yes\" || formattedValue === \"on\") {\n\t\t\treturn true;\n\t\t}\n\t\telse if(formattedValue === \"false\" || formattedValue === \"no\" || formattedValue === \"off\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseInteger = function parseInteger(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = parseInt(value);\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(validator.isFloat(value)) {\n\t\t\t\tnewValue = parseInt(value);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\tdefaultValue = parseInt(defaultValue);\n\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseFloatingPointNumber = function parseFloatingPointNumber(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = value;\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(validator.isFloat(value)) {\n\t\t\t\tnewValue = parseFloat(value);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseDate = function parseDate(value, defaultValue) {\n\t\tif(!utilities.isDate(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(typeof value === \"number\") {\n\t\t\tif(utilities.isInvalidNumber(value) || !Number.isInteger(value)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(parseInt(value));\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tvar formattedValue = value.trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\tvar timestamp = null;\n\n\t\t\tif(validator.isInt(formattedValue)) {\n\t\t\t\ttimestamp = parseInt(formattedValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimestamp = Date.parse(formattedValue);\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(timestamp)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(timestamp);\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseTime = function parseTime(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors);\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid or empty time value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar hour = null;\n\t\tvar minutes = null;\n\t\tvar regularTime = formattedValue.match(/^[ \\t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \\t]*([ap]m))[ \\t]*$/i);\n\n\t\tif(regularTime) {\n\t\t\tvar regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));\n\n\t\t\tif(utilities.isInvalidNumber(regularHour)) {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid regular hour: \\\"\" + regularTime[2] + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4]));\n\n\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\tminutes = 0;\n\t\t\t}\n\n\t\t\tvar period = regularTime[5].toUpperCase();\n\t\t\tvar morning = period === \"AM\" ? true : (period === \"PM\" ? false : null);\n\n\t\t\tif(morning === null) {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid period: \\\"\" + regularTime[5] + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\thour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12);\n\n\t\t\tif(hour === 24) {\n\t\t\t\thour = 0;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tvar militaryTime = formattedValue.match(/^[ \\t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \\t]*$/i);\n\n\t\t\tif(militaryTime) {\n\t\t\t\tvar militaryHour = militaryTime[3];\n\t\t\t\tvar militaryMinutes = militaryTime[6];\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tmilitaryHour = militaryTime[8];\n\n\t\t\t\t\tif(utilities.isNonEmptyString(militaryTime[9])) {\n\t\t\t\t\t\tmilitaryMinutes = militaryTime[9];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\thour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour));\n\n\t\t\t\tif(utilities.isInvalidNumber(hour)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time hour: \\\"\" + militaryHour + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes));\n\n\t\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time minutes: \\\"\" + militaryMinutes + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif(hour === 24 && minutes === 0) {\n\t\t\t\t\thour = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tif(hour < 0 || hour > 23) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Time hour is out of range (0 - 23): \\\"\" + hour + \"\\\".\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\telse if(minutes < 0 || minutes > 59) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Time minutes is out of range (0 - 59): \\\"\" + minutes + \"\\\".\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12);\n\t\tvar period = hour < 12 ? \"AM\" : \"PM\";\n\n\t\treturn {\n\t\t\tregular: {\n\t\t\t\traw: regularHour + \":\" + utilities.addLeadingZeroes(minutes, 2) + \" \" + period,\n\t\t\t\thour: regularHour,\n\t\t\t\tminutes: minutes,\n\t\t\t\tperiod: period,\n\t\t\t\tmorning: hour < 12\n\t\t\t},\n\t\t\tmilitary: {\n\t\t\t\traw: utilities.addLeadingZeroes(hour, 2) + utilities.addLeadingZeroes(minutes, 2),\n\t\t\t\thour: hour,\n\t\t\t\tminutes: minutes\n\t\t\t}\n\t\t};\n\t};\n\n\tutilities.parseEmail = function parseEmail(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?(@.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailData) || emailData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailData[1] + emailData[3];\n\t};\n\n\tutilities.parseEmailDomain = function parseEmailDomain(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailDomainData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?@(.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailDomainData) || emailDomainData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailDomainData[3];\n\t};\n\n\tutilities.parseStringList = function parseStringList(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar data = value.split(/[;,]+/);\n\t\tvar formattedList = [];\n\t\tvar formattedValue = null;\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tformattedValue = data[i].trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tformattedList.push(formattedValue);\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.parseRegularExpression = function parseRegularExpression(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tif(utilities.isRegularExpression(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Regular expression cannot be empty.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regExpData = value.match(/\\s*\\/(.*)\\/(.*)\\s*/);\n\n\t\tif(!regExpData) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid regular expression value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(throwErrors) {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\t\tcatch(error) {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\tutilities.parseYouTubeLink = function parseYouTubeLink(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar linkData = formattedValue.match(/.*(?:youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=)([^#\\&\\?]*).*/i);\n\n\t\tif(linkData && linkData[1].length >= 11) {\n\t\t\treturn linkData[1];\n\t\t}\n\n\t\tif(formattedValue.match(/[A-Z0-9_-]{11,}/i)) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\treturn null;\n\t};\n\n\tutilities.formatValue = function formatValue(value, format, options) {\n\t\tif(utilities.isObjectStrict(options)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(options.throwErrors, false)\n\t\t\t};\n\n\t\t\toptions.verbose = utilities.parseBoolean(options.verbose, !options.throwErrors);\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: false,\n\t\t\t\tverbose: true\n\t\t\t};\n\t\t}\n\n\t\tif(!utilities.isObjectStrict(format)) {\n\t\t\treturn utilities.clone(value);\n\t\t}\n\n\t\tformat = utilities.clone(format);\n\n\t\tvar errorMessage = null;\n\n\t\tif(utilities.isEmptyString(format.type)) {\n\t\t\terrorMessage = \"Invalid required type format value - expected non-empty string.\";\n\t\t}\n\t\telse {\n\t\t\tvar originalType = format.type;\n\n\t\t\tformat.type = format.type.trim().toLowerCase();\n\n\t\t\tvar validFormatType = false;\n\n\t\t\tfor(var i = 0; i < formatTypes.length; i++) {\n\t\t\t\tif(format.type === formatTypes[i]) {\n\t\t\t\t\tvalidFormatType = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!validFormatType) {\n\t\t\t\terrorMessage = \"Invalid required type format value - expected one of \" + formatTypes.join(\", \") + \", received \\\"\" + utilities.toString(originalType) + \"\\\".\";\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(format.type === \"bool\") {\n\t\t\t\t\tformat.type = \"boolean\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"int\") {\n\t\t\t\t\tformat.type = \"integer\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"number\") {\n\t\t\t\t\tformat.type = \"float\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"string\") {\n\t\t\t\t\tif(format.trim !== undefined) {\n\t\t\t\t\t\tvar originalTrim = format.trim;\n\n\t\t\t\t\t\tformat.trim = utilities.parseBoolean(format.trim);\n\n\t\t\t\t\t\tif(format.trim === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional trim string format value - expected boolean, received \\\"\" + utilities.toString(originalTrim) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.case !== undefined) {\n\t\t\t\t\t\t\tif(utilities.isEmptyString(format.case)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional string case format value - expected non-empty string.\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar originalCase = format.case;\n\n\t\t\t\t\t\t\t\tformat.case = changeCase.camelCase(format.case.trim());\n\n\t\t\t\t\t\t\t\tif(!utilities.isFunction(stringCaseFunctions[format.case])) {\n\t\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional case format value - expected one of \" + Object.keys(stringCaseFunctions).join(\", \") + \", received \\\"\" + utilities.toString(originalCase) + \"\\\".\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"object\") {\n\t\t\t\t\tif(format.strict !== undefined) {\n\t\t\t\t\t\tvar originalStrict = format.strict;\n\n\t\t\t\t\t\tformat.strict = utilities.parseBoolean(format.strict);\n\n\t\t\t\t\t\tif(format.strict === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional strict object format value - expected boolean, received \\\"\" + utilities.toString(originalStrict) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.autopopulate !== undefined) {\n\t\t\t\t\t\t\tvar originalAutopopulate = format.autopopulate;\n\n\t\t\t\t\t\t\tformat.autopopulate = utilities.parseBoolean(format.autopopulate);\n\n\t\t\t\t\t\t\tif(format.autopopulate === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional autopopulate object format value - expected boolean, received \\\"\" + utilities.toString(originalAutopopulate) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.order !== undefined) {\n\t\t\t\t\t\t\tvar originalOrder = format.order;\n\n\t\t\t\t\t\t\tformat.order = utilities.parseBoolean(format.order);\n\n\t\t\t\t\t\t\tif(format.order === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional order object format value - expected boolean, received \\\"\" + utilities.toString(originalOrder) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.removeExtra !== undefined) {\n\t\t\t\t\t\t\tvar originalRemoveExtra = format.removeExtra;\n\n\t\t\t\t\t\t\tformat.removeExtra = utilities.parseBoolean(format.removeExtra);\n\n\t\t\t\t\t\t\tif(format.removeExtra === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional removeExtra object format value - expected boolean, received \\\"\" + utilities.toString(originalRemoveExtra) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"regexp\" || format.type === \"regularexpression\") {\n\t\t\t\t\tformat.type = \"regex\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"func\") {\n\t\t\t\t\tformat.type = \"function\";\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.format !== undefined && !utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional format format value - expected object, received \\\"\" + utilities.toString(format.format) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"string\" || format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.nonEmpty !== undefined) {\n\t\t\t\t\t\t\tvar originalNonEmpty = format.nonEmpty;\n\n\t\t\t\t\t\t\tformat.nonEmpty = utilities.parseBoolean(format.nonEmpty);\n\n\t\t\t\t\t\t\tif(format.nonEmpty === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional nonEmpty format value - expected boolean, received \\\"\" + utilities.toString(originalNonEmpty) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.nullable !== undefined) {\n\t\t\t\tvar originalNullable = format.nullable;\n\n\t\t\t\tformat.nullable = utilities.parseBoolean(format.nullable);\n\n\t\t\t\tif(format.nullable === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional nullable format value - expected boolean, received \\\"\" + utilities.toString(originalNullable) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.required !== undefined) {\n\t\t\t\tvar originalRequired = format.required;\n\n\t\t\t\tformat.required = utilities.parseBoolean(format.required);\n\n\t\t\t\tif(format.required === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional required format value - expected boolean, received \\\"\" + utilities.toString(originalRequired) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.parser !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.parser)) {\n\t\t\t\t\terrorMessage = \"Invalid optional parser format value - expected function, received \\\"\" + utilities.toString(format.parser) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.validator !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.validator)) {\n\t\t\t\t\terrorMessage = \"Invalid optional validator format value - expected function, received \\\"\" + utilities.toString(format.validator) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.formatter !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.formatter)) {\n\t\t\t\t\terrorMessage = \"Invalid optional formatter format value - expected function, received \\\"\" + utilities.toString(format.formatter) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isFunction(format.parser)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar formattedValue = undefined;\n\n\t\tif(value === undefined) {\n\t\t\tformattedValue = utilities.clone(format.default);\n\t\t}\n\t\telse if(value === null) {\n\t\t\tif(format.nullable) {\n\t\t\t\tformattedValue = null;\n\t\t\t}\n\t\t\telse if(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Value cannot be null!\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"boolean\") {\n\t\t\tformattedValue = utilities.parseBoolean(value);\n\n\t\t\tif(formattedValue === null) {\n\t\t\t\terrorMessage = \"Invalid boolean value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"integer\") {\n\t\t\tformattedValue = utilities.parseInteger(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid integer value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"float\") {\n\t\t\tformattedValue = utilities.parseFloatingPointNumber(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid float value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"string\") {\n\t\t\tformattedValue = typeof value === \"string\" ? value : utilities.toString(value);\n\n\t\t\tif(format.trim) {\n\t\t\t\tformattedValue = formattedValue.trim();\n\t\t\t}\n\n\t\t\tif(format.case !== undefined) {\n\t\t\t\tformattedValue = stringCaseFunctions[format.case](formattedValue);\n\t\t\t}\n\n\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\tvar message = \"String value cannot be empty.\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"array\") {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\tif(!Array.isArray(formattedValue)) {\n\t\t\t\t\t\terrorMessage = \"Invalid stringified array value type - expected array: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\terrorMessage = \"Invalid stringified array value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(Array.isArray(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Invalid value type - expected array or stringified array: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\tif(Array.isArray(formattedValue)) {\n\t\t\t\t\tvar formattedArray = [];\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\tvar formattedElement = null;\n\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, subOptions);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(formattedElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(utilities.clone(formattedValue[i]));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tformattedValue = formattedArray;\n\n\t\t\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\t\t\tvar message = \"Array value cannot be empty.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"date\") {\n\t\t\tformattedValue = utilities.parseDate(value);\n\n\t\t\tif(!utilities.isDate(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid date value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"regex\") {\n\t\t\tif(utilities.isRegularExpression(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\terrorMessage = error.message;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid regular expression value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"function\") {\n\t\t\tformattedValue = value;\n\n\t\t\tif(!utilities.isFunction(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid function value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.type === \"object\") {\n\t\t\t\tif(utilities.isValid(value)) {\n\t\t\t\t\tif(typeof value === \"string\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\t\t\tif(!utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(utilities.isObject(value, format.strict)) {\n\t\t\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\terrorMessage = \"Invalid value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object or stringified object: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\t\t\tif(format.autopopulate && !utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\tformattedValue = { };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format) && utilities.isObject(formattedValue)) {\n\t\t\t\t\t\tvar attribute = null;\n\t\t\t\t\t\tvar attributes = Object.keys(format.format);\n\n\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], options);\n\n\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], subOptions);\n\n\t\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.removeExtra) {\n\t\t\t\t\t\t\tvar newValue = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(utilities.isValid(format.format[attribute])) {\n\t\t\t\t\t\t\t\t\tnewValue[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = newValue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.order) {\n\t\t\t\t\t\t\tvar orderedObject = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(format.format);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(formattedValue[attribute] !== undefined) {\n\t\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\n\t\t\t\t\t\t\t\t\tdelete formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar extraAttributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < extraAttributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = extraAttributes[i];\n\n\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = orderedObject;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(format.nonEmpty && utilities.isEmptyObject(formattedValue)) {\n\t\t\t\t\t\tvar message = \"Object value must contain at least one attribute.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(formattedValue === undefined) {\n\t\t\tif(format.required) {\n\t\t\t\tvar message = \"Missing required value!\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.validator)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\tthrow new Error(\"Validation check failed!\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\t\tvar message = \"Validation check failed!\";\n\n\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.formatter)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.formatObject = function formatObject(object, format, removeExtra, throwErrors) {\n\t\tif(!utilities.isObjectStrict(object) && (!utilities.isObjectStrict(removeExtra) || !utilities.isFunction(removeExtra.parser))) {\n\t\t\treturn { };\n\t\t}\n\n\t\tvar options = null;\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(removeExtra.throwErrors, utilities.parseBoolean(throwErrors, false)),\n\t\t\t\tverbose: utilities.parseBoolean(removeExtra.verbose, false)\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(throwErrors, false),\n\t\t\t\tverbose: false\n\t\t\t};\n\t\t}\n\n\t\tvar subFormat = {\n\t\t\ttype: \"object\",\n\t\t\tstrict: false,\n\t\t\tautopopulate: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.autopopulate, false) : false,\n\t\t\torder: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.order, false) : false,\n\t\t\tremoveExtra: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.removeExtra, utilities.parseBoolean(removeExtra, false)) : utilities.parseBoolean(removeExtra, false),\n\t\t\tnullable: true,\n\t\t\trequired: false,\n\t\t\tformat: format\n\t\t};\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\tif(utilities.isFunction(removeExtra.parser)) {\n\t\t\t\tsubFormat.parser = removeExtra.parser;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.validator)) {\n\t\t\t\tsubFormat.validator = removeExtra.validator;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.formatter)) {\n\t\t\t\tsubFormat.formatter = removeExtra.formatter;\n\t\t\t}\n\t\t}\n\n\t\tvar formattedObject = null;\n\n\t\tif(options.throwErrors) {\n\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\tobject,\n\t\t\t\tsubFormat,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\tsubOptions.throwErrors = true;\n\n\t\t\ttry {\n\t\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\t\tobject,\n\t\t\t\t\tsubFormat,\n\t\t\t\t\tsubOptions\n\t\t\t\t);\n\t\t\t}\n\t\t\tcatch(error) {\n\t\t\t\tif(options.verbose) {\n\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn utilities.isObjectStrict(formattedObject) || (utilities.isObjectStrict(removeExtra) && utilities.isFunction(removeExtra.parser)) ? formattedObject : { };\n\t};\n\n\tutilities.formatStringList = function formatStringList(value, stringify) {\n\t\tvar data = null;\n\n\t\tif(utilities.isNonEmptyString(value)) {\n\t\t\tdata = utilities.parseStringList(value);\n\t\t}\n\t\telse if(utilities.isNonEmptyArray(value)) {\n\t\t\tdata = value;\n\t\t}\n\t\telse if(typeof value === \"string\" || Array.isArray(value)) {\n\t\t\treturn \"\";\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedList = \"\";\n\t\tvar formattedValue = null;\n\n\t\tstringify = utilities.parseBoolean(stringify);\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tif(typeof data[i] !== \"string\") {\n\t\t\t\tif(stringify === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if(stringify) {\n\t\t\t\t\tformattedValue = utilities.toString(data[i]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tformattedValue = data[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tformattedValue = data[i].trim();\n\t\t\t}\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(formattedList.length > 0) {\n\t\t\t\tformattedList += \", \";\n\t\t\t}\n\n\t\t\tformattedList += formattedValue;\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.leftShift = function leftShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number * Math.pow(2, bits);\n\t};\n\n\tutilities.rightShift = function rightShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number / Math.pow(2, bits);\n\t};\n\n\tutilities.trimString = function trimString(value, defaultValue) {\n\t\treturn typeof value === \"string\" ? value.trim() : (defaultValue === undefined ? null : defaultValue);\n\t};\n\n\tutilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue === undefined ? null : defaultValue;\n\t\t}\n\n\t\tvar nullTerminatorIndex = value.indexOf(\"\\0\");\n\n\t\tif(nullTerminatorIndex >= 0) {\n\t\t\treturn value.substr(0, nullTerminatorIndex);\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.trimWhitespace = function trimWhitespace(value, trimNewlines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar trimmedString = value.replace(/^[ \\t]+|[ \\t]+$/gm, \"\");\n\n\t\tif(utilities.parseBoolean(trimNewlines, false)) {\n\t\t\ttrimmedString = trimmedString.replace(/\\r\\n?|\\n/g, \"\");\n\t\t}\n\n\t\treturn trimmedString;\n\t};\n\n\tutilities.trimTrailingNewlines = function trimTrailingNewlines(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn value.replace(/[ \\t\\r\\n]+$/, \"\");\n\t};\n\n\tutilities.replaceNonBreakingSpaces = function replaceNonBreakingSpaces(value) {\n\t\treturn typeof value === \"string\" ? value.replace(/ /gi, \" \") : null;\n\t};\n\n\tutilities.indentText = function indentText(value, amount, indentation, clearEmptyLines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tclearEmptyLines = utilities.parseBoolean(clearEmptyLines, true);\n\n\t\tamount = utilities.parseInteger(amount, 1);\n\n\t\tif(amount < 0) {\n\t\t\tamount = 0;\n\t\t}\n\n\t\tindentation = typeof indentation === \"string\" ? indentation : \"\\t\";\n\n\t\tvar totalIndentation = \"\";\n\n\t\tfor(var i = 0; i < amount; i++) {\n\t\t\ttotalIndentation += indentation;\n\t\t}\n\n\t\tvar line = null;\n\t\tvar lines = value.split(/\\r\\n?|\\n/g);\n\t\tvar indentedParagraph = \"\";\n\n\t\tfor(var i = 0; i < lines.length; i++) {\n\t\t\tline = lines[i];\n\n\t\t\tindentedParagraph += (utilities.isEmptyString(line) && clearEmptyLines ? \"\" : totalIndentation + line) + ((i < lines.length - 1) ? \"\\n\" : \"\");\n\t\t}\n\n\t\treturn indentedParagraph;\n\t};\n\n\tutilities.trimLeadingZeroes = function trimLeadingZeroes(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\t\telse if(formattedValue.match(/^[0]+$/)) {\n\t\t\treturn \"0\";\n\t\t}\n\n\t\treturn formattedValue.replace(/^0+/, \"\");\n\t};\n\n\tutilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) {\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.toString();\n\t\texpectedLength = utilities.parseInteger(expectedLength);\n\n\t\tif(utilities.isInvalidNumber(expectedLength) || expectedLength < 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar numberOfZeroes = expectedLength - value.length;\n\n\t\tfor(var i = 0; i < numberOfZeroes; i++) {\n\t\t\tvalue = \"0\" + value;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.toString = function toString(value) {\n\t\tif(value === undefined) {\n\t\t\treturn \"undefined\";\n\t\t}\n\t\telse if(value === null) {\n\t\t\treturn \"null\";\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value === Infinity) {\n\t\t\treturn \"Infinity\";\n\t\t}\n\t\telse if(value === -Infinity) {\n\t\t\treturn \"-Infinity\";\n\t\t}\n\t\telse if(typeof value === \"number\" && isNaN(value)) {\n\t\t\treturn \"NaN\";\n\t\t}\n\t\telse if(utilities.isDate(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(utilities.isRegularExpression(value)) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn \"/\" + value.source + \"/\" + flags;\n\t\t}\n\t\telse if(utilities.isFunction(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(utilities.isError(value)) {\n\t\t\tvar error = { message: value.message };\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\terror[attribute] = value[attribute];\n\t\t\t}\n\n\t\t\treturn JSON.stringify(error);\n\t\t}\n\n\t\treturn JSON.stringify(value);\n\t};\n\n\tutilities.compareDates = function compareDates(a, b) {\n\t\ta = utilities.parseDate(a);\n\t\tb = utilities.parseDate(b);\n\n\t\tif(a === null && b === null) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tif(a === null) {\n\t\t\treturn -1;\n\t\t}\n\t\telse if(b === null) {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn a.getTime() - b.getTime();\n\t};\n\n\tutilities.compareCasePercentage = function compareCasePercentage(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar c = null;\n\t\tvar upper = 0;\n\t\tvar lower = 0;\n\t\tvar lowerA = \"a\".charCodeAt();\n\t\tvar lowerZ = \"z\".charCodeAt();\n\t\tvar upperA = \"A\".charCodeAt();\n\t\tvar upperZ = \"Z\".charCodeAt();\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tc = value.charCodeAt(i);\n\n\t\t\tif(c >= lowerA && c <= lowerZ) {\n\t\t\t\tlower++;\n\t\t\t}\n\t\t\telse if(c >= upperA && c <= upperZ) {\n\t\t\t\tupper++;\n\t\t\t}\n\t\t}\n\n\t\treturn upper - lower;\n\t};\n\n\tutilities.reverseString = function reverseString(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.replace(\n\t\t\t/([\\0-\\u02FF\\u0370-\\u1AAF\\u1B00-\\u1DBF\\u1E00-\\u20CF\\u2100-\\uD7FF\\uE000-\\uFE1F\\uFE30-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])([\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F]+)/g,\n\t\t\tfunction($0, $1, $2) {\n\t\t\t\treturn utilities.reverseString($2) + $1;\n\t\t\t}\n\t\t).replace(/([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])/g, \"$2$1\");\n\n\t\tvar reverse = \"\";\n\n\t\tfor(var i = value.length - 1; i >= 0; i--) {\n\t\t\treverse += value[i];\n\t\t}\n\n\t\treturn reverse;\n\t};\n\n\tutilities.createError = function createError(message, status) {\n\t\tvar error = new Error(message);\n\t\terror.status = utilities.parseInteger(status, 500);\n\t\treturn error;\n\t};\n\n\tutilities.clone = function clone(value) {\n\t\tif(!utilities.isObject(value)) {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value instanceof Boolean) {\n\t\t\treturn new Boolean(value.valueOf());\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\tvar copy = new Date();\n\t\t\tcopy.setTime(value.getTime());\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Array) {\n\t\t\tvar copy = [];\n\n\t\t\tfor(var i = 0, length = value.length; i < length; i++) {\n\t\t\t\tcopy[i] = utilities.clone(value[i]);\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Set) {\n\t\t\treturn new Set(value);\n\t\t}\n\t\telse if(value instanceof Map) {\n\t\t\treturn new Map(value);\n\t\t}\n\t\telse if(value instanceof RegExp) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new RegExp(value.source, flags);\n\t\t}\n\t\telse if(typeof Buffer !== \"undefined\" && value instanceof Buffer) {\n\t\t\treturn Buffer.from instanceof Function ? Buffer.from(value) : new Buffer(value);\n\t\t}\n\t\telse if(value instanceof Object) {\n\t\t\tvar copy = null;\n\n\t\t\tif(value instanceof Error) {\n\t\t\t\tcopy = new Error(value.message);\n\n\t\t\t\tcopy.stack = utilities.clone(value.stack);\n\n\t\t\t\tvar properties = Object.keys(value);\n\n\t\t\t\tfor(var i = 0; i < properties.length; i++) {\n\t\t\t\t\tcopy[properties[i]] = utilities.clone(value[properties[i]]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcopy = { };\n\t\t\t}\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\tif(Object.prototype.hasOwnProperty.call(value, attribute)) {\n\t\t\t\t\tcopy[attribute] = utilities.clone(value[attribute]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.merge = function merge(a, b, copy, deepMerge) {\n\t\tif(!utilities.isObject(a) || Array.isArray(a)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar newObject = null;\n\n\t\tcopy = utilities.parseBoolean(copy, true);\n\n\t\tif(copy) {\n\t\t\tnewObject = utilities.clone(a);\n\t\t}\n\t\telse {\n\t\t\tnewObject = a;\n\t\t}\n\n\t\tif(!utilities.isObject(a) || Array.isArray(a) || !utilities.isObject(b) || Array.isArray(b)) {\n\t\t\treturn newObject;\n\t\t}\n\n\t\tvar attribute = null;\n\t\tvar value = null;\n\t\tvar newValue = null;\n\t\tvar attributes = Object.keys(b);\n\n\t\tdeepMerge = utilities.parseBoolean(deepMerge, true);\n\n\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\tattribute = attributes[i];\n\t\t\tvalue = newObject[attribute];\n\n\t\t\tif(copy) {\n\t\t\t\tnewValue = utilities.clone(b[attribute]);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewValue = b[attribute];\n\t\t\t}\n\n\t\t\tif(deepMerge && utilities.isObject(value) && !Array.isArray(value) && utilities.isObject(newValue) && !Array.isArray(newValue)) {\n\t\t\t\tnewObject[attribute] = utilities.merge(value, newValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewObject[attribute] = newValue;\n\t\t\t}\n\t\t}\n\n\t\treturn newObject;\n\t};\n\n\tutilities.getFileName = function getFileName(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(i + 1, filePath.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn filePath;\n\t};\n\n\tutilities.getFilePath = function getFilePath(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.getFileExtension = function getFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(i + 1, fileName.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.fileHasExtension = function fileHasExtension(fileName, extension) {\n\t\tif(utilities.isEmptyString(fileName) || utilities.isEmptyString(extension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar actualFileExtension = utilities.getFileExtension(fileName);\n\n\t\tif(utilities.isEmptyString(actualFileExtension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn actualFileExtension.toLowerCase() === extension.trim().toLowerCase();\n\t};\n\n\tutilities.reverseFileExtension = function reverseFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = fileName.trim();\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i) + \".\" + utilities.reverseString(fileName.substring(i + 1, fileName.length));\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.truncateFileName = function truncateFileName(fileName, maxLength) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tif(utilities.isEmptyString(fileName)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tmaxLength = utilities.parseInteger(maxLength);\n\n\t\tif(utilities.isInvalidNumber(maxLength) || maxLength < 0) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tif(maxLength === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif(fileName.length <= maxLength) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tvar extension = \"\";\n\t\tvar originalFileName = fileName;\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\textension = fileName.substring(i + 1, fileName.length);\n\t\t\t\toriginalFileName = fileName.substring(0, i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(maxLength - (extension.length + (extension.length > 0 ? 1 : 0)) < 1) {\n\t\t\treturn originalFileName.substring(0, maxLength);\n\t\t}\n\n\t\treturn originalFileName.substring(0, maxLength - extension.length - (extension.length > 0 ? 1 : 0)) + (extension.length > 0 ? \".\" + extension : \"\");\n\t};\n\n\tutilities.prependSlash = function prependSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[0] !== \"/\" && formattedValue[0] !== \"\\\\\") {\n\t\t\tformattedValue = \"/\" + formattedValue;\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.appendSlash = function appendSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[formattedValue.length - 1] !== \"/\" && formattedValue[formattedValue.length - 1] !== \"\\\\\") {\n\t\t\tformattedValue += \"/\";\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.joinPaths = function joinPaths(base, path) {\n\t\tvar formattedBase = typeof base === \"string\" ? base.trim().replace(/[\\/\\\\]+$/, \"\") : null;\n\t\tvar formattedPath = typeof path === \"string\" ? path.trim().replace(/^[\\/\\\\]+/, \"\") : null;\n\t\tvar newPath = \"\";\n\n\t\tif(utilities.isNonEmptyString(formattedBase)) {\n\t\t\tnewPath += formattedBase;\n\n\t\t\tif(utilities.isNonEmptyString(formattedPath)) {\n\t\t\t\tnewPath += \"/\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isNonEmptyString(formattedPath)) {\n\t\t\tnewPath += formattedPath;\n\t\t}\n\n\t\treturn newPath;\n\t};\n\n\tutilities.createQueryString = function createQueryString(value, includeQuestionMark) {\n\t\tif(!utilities.isObjectStrict(value)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar parameters = Object.keys(value).map(function(key) {\n\t\t\treturn encodeURIComponent(key) + \"=\" + encodeURIComponent(utilities.toString(value[key]));\n\t\t}).join(\"&\");\n\n\t\tif(parameters.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\treturn (utilities.parseBoolean(includeQuestionMark, false) ? \"?\" : \"\") + parameters;\n\t};\n\n\tutilities.createRange = function createRange(start, end) {\n\t\tvar formattedStart = utilities.parseInteger(start);\n\t\tvar formattedEnd = utilities.parseInteger(end);\n\n\t\tif(arguments.length === 1) {\n\t\t\tformattedEnd = formattedStart;\n\t\t\tformattedStart = 0;\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(formattedStart) || utilities.isInvalidNumber(formattedEnd) || formattedStart > formattedEnd) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar range = [];\n\n\t\tfor(var i = formattedStart; i <= formattedEnd; i++) {\n\t\t\trange.push(i);\n\t\t}\n\n\t\treturn range;\n\t};\n\n\tutilities.futureMonths = function futureMonths(date, prependZero) {\n\t\tdate = utilities.parseDate(date);\n\n\t\tif(date === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar currentDate = new Date();\n\t\tvar month = 0;\n\n\t\tif(date.getFullYear() === currentDate.getFullYear()) {\n\t\t\tmonth = currentDate.getMonth();\n\t\t}\n\n\t\tvar months = [];\n\n\t\tprependZero = utilities.parseBoolean(prependZero, false);\n\n\t\tfor(var i = 0; i < 12; i++) {\n\t\t\tif(i >= month) {\n\t\t\t\tif(prependZero) {\n\t\t\t\t\tmonths.push((i <= 8 ? \"0\" : \"\") + (i + 1));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmonths.push(i + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn months;\n\t};\n\n\tutilities.visibleElements = function visibleElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar visibleElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isVisible(elements[i])) {\n\t\t\t\tvisibleElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn visibleElements;\n\t};\n\n\tutilities.hiddenElements = function hiddenElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar hiddenElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isHidden(elements[i])) {\n\t\t\t\thiddenElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn hiddenElements;\n\t};\n\n\tutilities.enabledElements = function enabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar enabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isEnabled(elements[i])) {\n\t\t\t\tenabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn enabledElements;\n\t};\n\n\tutilities.disabledElements = function disabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar disabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isDisabled(elements[i])) {\n\t\t\t\tdisabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn disabledElements;\n\t};\n\n\tutilities.elementsWithAttribute = function elementsWithAttribute(elements, attribute, hasAttribute) {\n\t\tif(!Array.isArray(elements) || utilities.isEmptyString(attribute)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar element = null;\n\t\tvar filteredElements = [];\n\n\t\tattribute = attribute.trim();\n\t\thasAttribute = utilities.parseBoolean(hasAttribute, true);\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\telement = elements[i];\n\n\t\t\tif(!utilities.isObject(element)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(elements[i][attribute])) {\n\t\t\t\tif(!hasAttribute) {\n\t\t\t\t\tfilteredElements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(hasAttribute) {\n\t\t\t\t\tfilteredElements.push(elements[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn filteredElements;\n\t};\n\n\tutilities.elementsWithoutAttribute = function elementsWithoutAttribute(elements, attribute) {\n\t\treturn utilities.elementsWithAttribute(elements, attribute, false);\n\t};\n\n\tutilities.matchAttribute = function matchAttribute(element, attribute, value) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(attribute)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn element[attribute.trim()] === value;\n\t};\n\n\tutilities.generateVersions = function generateVersions(version, prefix, suffix) {\n\t\tversion = utilities.parseVersion(version);\n\n\t\tif(version === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tprefix = utilities.trimString(prefix);\n\t\tsuffix = utilities.trimString(suffix);\n\n\t\tvar versions = [];\n\t\tvar value = null;\n\n\t\tfor(var i = 0; i < version.length; i++) {\n\t\t\tvalue = \"\";\n\n\t\t\tif(utilities.isNonEmptyString(prefix)) {\n\t\t\t\tvalue += prefix;\n\t\t\t}\n\n\t\t\tfor(var j = 0; j <= i; j++) {\n\t\t\t\tif(j > 0) {\n\t\t\t\t\tvalue += \"_\";\n\t\t\t\t}\n\n\t\t\t\tvalue += version[j];\n\t\t\t}\n\n\t\t\tif(utilities.isNonEmptyString(suffix)) {\n\t\t\t\tvalue += suffix;\n\t\t\t}\n\n\t\t\tversions.push(value);\n\t\t}\n\n\t\treturn versions;\n\t};\n\n\tutilities.parseVersion = function parseVersion(value, trimTrailingZeroes) {\n\t\tvar formattedValue = utilities.isValidNumber(value) ? value.toString() : value;\n\n\t\tif(typeof formattedValue !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar version = [];\n\t\tvar versionData = formattedValue.match(/[^. \\t]+/g);\n\n\t\tif(versionData === null || versionData.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar part = null;\n\n\t\tfor(var i = 0; i < versionData.length; i++) {\n\t\t\tif(validator.isInt(versionData[i])) {\n\t\t\t\tpart = utilities.parseInteger(versionData[i]);\n\n\t\t\t\tif(utilities.isInvalidNumber(part) || part < 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tversion.push(part.toString());\n\t\t\t}\n\t\t\telse {\n\t\t\t\tversion.push(versionData[i]);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.parseBoolean(trimTrailingZeroes, false)) {\n\t\t\twhile(true) {\n\t\t\t\tif(version.length <= 1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif(version[version.length - 1] === \"0\") {\n\t\t\t\t\tversion.pop();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn version.length === 0 ? null : version;\n\t};\n\n\tutilities.compareVersions = function compareVersions(v1, v2, caseSensitive, throwErrors) {\n\t\tcaseSensitive = utilities.parseBoolean(caseSensitive, false);\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tv1 = utilities.parseVersion(v1);\n\n\t\tif(v1 === null) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Cannot compare invalid or empty first version.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tv2 = utilities.parseVersion(v2);\n\n\t\tif(v2 === null) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Cannot compare invalid or empty second version.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar index = 0;\n\n\t\twhile(true) {\n\t\t\tif(index >= v1.length) {\n\t\t\t\tif(v1.length === v2.length) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tfor(var i = index; i < v2.length; i++) {\n\t\t\t\t\tif(v2[i] !== \"0\") {\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tif(index >= v2.length) {\n\t\t\t\tfor(var i = index; i < v1.length; i++) {\n\t\t\t\t\tif(v1[i] !== \"0\") {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tvar formattedA = utilities.parseInteger(v1[index]);\n\t\t\tvar formattedB = utilities.parseInteger(v2[index]);\n\n\t\t\tif(utilities.isInvalidNumber(formattedA)) {\n\t\t\t\tformattedA = caseSensitive ? v1[index] : v1[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(formattedB)) {\n\t\t\t\tformattedB = caseSensitive ? v2[index] : v2[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(Number.isInteger(formattedA)) {\n\t\t\t\tif(!Number.isInteger(formattedB)) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(Number.isInteger(formattedB)) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(formattedA > formattedB) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse if(formattedA < formattedB) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tindex++;\n\t\t}\n\t};\n\n\treturn utilities;\n\n}));\n"],"file":"extra-utilities.js"} \ No newline at end of file +{"version":3,"names":[],"mappings":"","sources":["extra-utilities.js"],"sourcesContent":["(function(global, factory) {\n\ttypeof exports === \"object\" && typeof module !== \"undefined\" ? module.exports = factory() :\n\ttypeof define === \"function\" && define.amd ? define(factory) :\n\t(global.utilities = factory());\n} (this, function() {\n\n\t\"use strict\";\n\n\tif(typeof require !== \"undefined\") {\n\t\tif(typeof changeCase === \"undefined\") {\n\t\t\tglobal.changeCase = require(\"change-case-bundled\");\n\t\t}\n\t}\n\n\tvar utilities = { };\n\n\tvar regExpFlags = {\n\t\tglobal: \"g\",\n\t\tmultiline: \"m\",\n\t\tignoreCase: \"i\",\n\t\tsticky: \"y\",\n\t\tunicode: \"u\"\n\t};\n\n\tvar formatTypes = [\"boolean\", \"bool\", \"integer\", \"int\", \"float\", \"number\", \"string\", \"object\", \"array\", \"date\", \"regex\", \"regexp\", \"regularexpression\", \"function\", \"func\"];\n\n\tvar stringCaseFunctions = {\n\t\tcamel: changeCase.camelCase,\n\t\tcapital: changeCase.capitalCase,\n\t\tconstant: changeCase.constantCase,\n\t\tdot: changeCase.dotCase,\n\t\theader: changeCase.headerCase,\n\t\tlower: changeCase.lowerCase,\n\t\tlowerFirst: changeCase.lowerCaseFirst,\n\t\tno: changeCase.noCase,\n\t\tparam: changeCase.paramCase,\n\t\tpascal: changeCase.pascalCase,\n\t\tpath: changeCase.pathCase,\n\t\tsentence: changeCase.sentenceCase,\n\t\tsnake: changeCase.snakeCase,\n\t\tsponge: changeCase.spongeCase,\n\t\tswap: changeCase.swapCase,\n\t\ttitle: changeCase.titleCase,\n\t\tupper: changeCase.upperCase,\n\t\tupperFirst: changeCase.upperCaseFirst\n\t};\n\n\tutilities.isValid = function isValid(value) {\n\t\treturn value !== undefined && value !== null;\n\t};\n\n\tutilities.isInvalid = function isInvalid(value) {\n\t\treturn value === undefined || value === null;\n\t};\n\n\tutilities.isBoolean = function isBoolean(value, allowObjects) {\n\t\treturn value === true || value === false || (!!allowObjects && value instanceof Boolean);\n\t};\n\n\tutilities.isValidNumber = function isValidNumber(value) {\n\t\treturn typeof value === \"number\" && !isNaN(value) && value !== -Infinity && value !== Infinity;\n\t};\n\n\tutilities.isInvalidNumber = function isInvalidNumber(value) {\n\t\treturn typeof value !== \"number\" || isNaN(value) || value === -Infinity || value === Infinity;\n\t};\n\n\tutilities.isInteger = function isInteger(value, allowObjects) {\n\t\tif(Number.isInteger(value)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(value instanceof Number && utilities.parseBoolean(allowObjects, true)) {\n\t\t\treturn Number.isInteger(value.valueOf());\n\t\t}\n\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !!value.match(/^([+-]?[1-9][0-9]*|0)$/);\n\t};\n\n\tutilities.isFloat = function isFloat(value, allowObjects) {\n\t\tif(typeof value === \"number\") {\n\t\t\treturn !isNaN(value) && isFinite(value);\n\t\t}\n\n\t\tif(value instanceof Number && utilities.parseBoolean(allowObjects, true)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !!value.match(/^([+-]?(((([1-9][0-9]*|0)?\\.)[0-9]+)|([1-9][0-9]*|0)))$/);\n\t};\n\n\tutilities.isEmptyString = function isEmptyString(value, trim) {\n\t\treturn typeof value !== \"string\" || (utilities.parseBoolean(trim, true) ? value.trim().length === 0 : value.length === 0);\n\t};\n\n\tutilities.isNonEmptyString = function isNonEmptyString(value, trim) {\n\t\treturn typeof value === \"string\" && (utilities.parseBoolean(trim, true) ? value.trim().length !== 0 : value.length !== 0);\n\t};\n\n\tutilities.isObject = function isObject(value, strict) {\n\t\treturn value !== undefined && (strict ? value !== null && value.constructor === Object : value instanceof Object && !(value instanceof Function));\n\t};\n\n\tutilities.isObjectStrict = function isObjectStrict(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object;\n\t};\n\n\tutilities.isEmptyObject = function isEmptyObject(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length === 0;\n\t};\n\n\tutilities.isNonEmptyObject = function isNonEmptyObject(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length !== 0;\n\t};\n\n\tutilities.isEmptyArray = function isEmptyArray(value) {\n\t\treturn Array.isArray(value) ? value.length === 0 : true;\n\t};\n\n\tutilities.isNonEmptyArray = function isNonEmptyArray(value) {\n\t\treturn Array.isArray(value) && value.length !== 0;\n\t};\n\n\tutilities.isDate = function isDate(value) {\n\t\treturn value instanceof Date;\n\t};\n\n\tutilities.isError = function isError(value) {\n\t\treturn value instanceof Error;\n\t};\n\n\tutilities.isRegularExpression = function isRegularExpression(value) {\n\t\treturn value instanceof RegExp;\n\t};\n\n\tutilities.isFunction = function isFunction(value) {\n\t\treturn value instanceof Function;\n\t};\n\n\tutilities.isComment = function isComment(value, comment) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(comment)) {\n\t\t\tcomment = \"//\";\n\t\t}\n\n\t\tvar commentStartIndex = -1;\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tif(value[i] === \" \" || value[i] == \"\\t\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(value[i] == comment[0]) {\n\t\t\t\tcommentStartIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif(commentStartIndex < 0 || value.length - commentStartIndex < comment.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor(var i = commentStartIndex; i < value.length; i++) {\n\t\t\tif(i - commentStartIndex >= comment.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(value[i] != comment[i - commentStartIndex]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isVisible = function isVisible(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn !element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn !element.hidden();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isHidden = function isHidden(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn !element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn !element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn element.hidden();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.isEnabled = function isEnabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn !element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn !element.disabled();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isDisabled = function isDisabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn !element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn !element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn element.disabled();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) {\n\t\tif(typeof stringA !== \"string\" || typeof stringB !== \"string\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn stringA.localeCompare(stringB, undefined, { sensitivity: \"accent\" }) === 0;\n\t};\n\n\tutilities.parseBoolean = function parseBoolean(value, defaultValue) {\n\t\tif(utilities.isBoolean(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isBoolean(value, true)) {\n\t\t\treturn value.valueOf();\n\t\t}\n\n\t\tif(!utilities.isBoolean(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(value === 0) {\n\t\t\treturn false;\n\t\t}\n\t\telse if(value === 1) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tvar formattedValue = value.trim().toLowerCase();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue.length === 1) {\n\t\t\tvar character = formattedValue.charAt(0);\n\n\t\t\tif(character === \"t\" || character === \"y\") {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if(character === \"f\" || character === \"n\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"0\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"1\") {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue === \"true\" || formattedValue === \"yes\" || formattedValue === \"on\") {\n\t\t\treturn true;\n\t\t}\n\t\telse if(formattedValue === \"false\" || formattedValue === \"no\" || formattedValue === \"off\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseInteger = function parseInteger(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = parseInt(value);\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(utilities.isFloat(value)) {\n\t\t\t\tnewValue = parseInt(value);\n\t\t\t}\n\t\t}\n\t\telse if(value instanceof Number) {\n\t\t\tnewValue = parseInt(value.valueOf());\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\tdefaultValue = parseInt(defaultValue);\n\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseFloat = function parseFloatingPointNumber(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = value;\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(utilities.isFloat(value)) {\n\t\t\t\tnewValue = parseFloat(value);\n\t\t\t}\n\t\t}\n\t\telse if(value instanceof Number) {\n\t\t\tnewValue = value.valueOf();\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseFloatingPointNumber = utilities.parseFloat;\n\n\tutilities.parseDate = function parseDate(value, defaultValue) {\n\t\tif(!utilities.isDate(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(typeof value === \"number\") {\n\t\t\tif(utilities.isInvalidNumber(value) || !Number.isInteger(value) || value < 0) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(parseInt(value));\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tvar formattedValue = value.trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\tvar timestamp = null;\n\n\t\t\tif(utilities.isInteger(formattedValue)) {\n\t\t\t\ttimestamp = parseInt(formattedValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimestamp = Date.parse(formattedValue);\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(timestamp)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(timestamp);\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseTime = function parseTime(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tthrow new Error(\"Invalid or empty time value.\");\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar hour = null;\n\t\tvar minutes = null;\n\t\tvar regularTime = formattedValue.match(/^[ \\t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \\t]*([ap]m))[ \\t]*$/i);\n\n\t\tif(regularTime) {\n\t\t\tvar regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));\n\n\t\t\tif(utilities.isInvalidNumber(regularHour)) {\n\t\t\t\tthrow new Error(\"Invalid regular hour: \\\"\" + regularTime[2] + \"\\\".\");\n\t\t\t}\n\n\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4]));\n\n\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\tminutes = 0;\n\t\t\t}\n\n\t\t\tvar period = regularTime[5].toUpperCase();\n\t\t\tvar morning = period === \"AM\" ? true : (period === \"PM\" ? false : null);\n\n\t\t\tif(morning === null) {\n\t\t\t\tthrow new Error(\"Invalid period: \\\"\" + regularTime[5] + \"\\\".\");\n\t\t\t}\n\n\t\t\thour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12);\n\n\t\t\tif(hour === 24) {\n\t\t\t\thour = 0;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tvar militaryTime = formattedValue.match(/^[ \\t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \\t]*$/i);\n\n\t\t\tif(militaryTime) {\n\t\t\t\tvar militaryHour = militaryTime[3];\n\t\t\t\tvar militaryMinutes = militaryTime[6];\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tmilitaryHour = militaryTime[8];\n\n\t\t\t\t\tif(utilities.isNonEmptyString(militaryTime[9])) {\n\t\t\t\t\t\tmilitaryMinutes = militaryTime[9];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tthrow new Error(\"Invalid military time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\thour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour));\n\n\t\t\t\tif(utilities.isInvalidNumber(hour)) {\n\t\t\t\t\tthrow new Error(\"Invalid military time hour: \\\"\" + militaryHour + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes));\n\n\t\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\t\tthrow new Error(\"Invalid military time minutes: \\\"\" + militaryMinutes + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\tif(hour === 24 && minutes === 0) {\n\t\t\t\t\thour = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new Error(\"Invalid time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t}\n\t\t}\n\n\t\tif(hour < 0 || hour > 23) {\n\t\t\tthrow new Error(\"Time hour is out of range (0 - 23): \\\"\" + hour + \"\\\".\");\n\t\t}\n\t\telse if(minutes < 0 || minutes > 59) {\n\t\t\tthrow new Error(\"Time minutes is out of range (0 - 59): \\\"\" + minutes + \"\\\".\");\n\t\t}\n\n\t\tvar regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12);\n\t\tvar period = hour < 12 ? \"AM\" : \"PM\";\n\n\t\treturn {\n\t\t\tregular: {\n\t\t\t\traw: regularHour + \":\" + utilities.addLeadingZeroes(minutes, 2) + \" \" + period,\n\t\t\t\thour: regularHour,\n\t\t\t\tminutes: minutes,\n\t\t\t\tperiod: period,\n\t\t\t\tmorning: hour < 12\n\t\t\t},\n\t\t\tmilitary: {\n\t\t\t\traw: utilities.addLeadingZeroes(hour, 2) + utilities.addLeadingZeroes(minutes, 2),\n\t\t\t\thour: hour,\n\t\t\t\tminutes: minutes\n\t\t\t}\n\t\t};\n\t};\n\n\tutilities.parseEmail = function parseEmail(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?(@.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailData) || emailData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailData[1] + emailData[3];\n\t};\n\n\tutilities.parseEmailDomain = function parseEmailDomain(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailDomainData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?@(.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailDomainData) || emailDomainData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailDomainData[3];\n\t};\n\n\tutilities.parseStringList = function parseStringList(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar data = value.split(/[;,]+/);\n\t\tvar formattedList = [];\n\t\tvar formattedValue = null;\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tformattedValue = data[i].trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tformattedList.push(formattedValue);\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.parseRegularExpression = function parseRegularExpression(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tif(utilities.isRegularExpression(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Regular expression cannot be empty.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regExpData = value.match(/\\s*\\/(.*)\\/(.*)\\s*/);\n\n\t\tif(!regExpData) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid regular expression value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\t\tcatch(error) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t};\n\n\tutilities.parseYouTubeLink = function parseYouTubeLink(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar linkData = formattedValue.match(/.*(?:youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=)([^#\\&\\?]*).*/i);\n\n\t\tif(linkData && linkData[1].length >= 11) {\n\t\t\treturn linkData[1];\n\t\t}\n\n\t\tif(formattedValue.match(/[A-Z0-9_-]{11,}/i)) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\treturn null;\n\t};\n\n\tutilities.formatValue = function formatValue(value, format, options) {\n\t\tif(utilities.isObjectStrict(options)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(options.throwErrors, false)\n\t\t\t};\n\n\t\t\toptions.verbose = utilities.parseBoolean(options.verbose, !options.throwErrors);\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: false,\n\t\t\t\tverbose: true\n\t\t\t};\n\t\t}\n\n\t\tif(!utilities.isObjectStrict(format)) {\n\t\t\treturn utilities.clone(value);\n\t\t}\n\n\t\tformat = utilities.clone(format);\n\n\t\tvar errorMessage = null;\n\n\t\tif(utilities.isEmptyString(format.type)) {\n\t\t\terrorMessage = \"Invalid required type format value - expected non-empty string.\";\n\t\t}\n\t\telse {\n\t\t\tvar originalType = format.type;\n\n\t\t\tformat.type = format.type.trim().toLowerCase();\n\n\t\t\tvar validFormatType = false;\n\n\t\t\tfor(var i = 0; i < formatTypes.length; i++) {\n\t\t\t\tif(format.type === formatTypes[i]) {\n\t\t\t\t\tvalidFormatType = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!validFormatType) {\n\t\t\t\terrorMessage = \"Invalid required type format value - expected one of \" + formatTypes.join(\", \") + \", received \\\"\" + utilities.toString(originalType) + \"\\\".\";\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(format.type === \"bool\") {\n\t\t\t\t\tformat.type = \"boolean\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"int\") {\n\t\t\t\t\tformat.type = \"integer\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"number\") {\n\t\t\t\t\tformat.type = \"float\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"string\") {\n\t\t\t\t\tif(format.trim !== undefined) {\n\t\t\t\t\t\tvar originalTrim = format.trim;\n\n\t\t\t\t\t\tformat.trim = utilities.parseBoolean(format.trim);\n\n\t\t\t\t\t\tif(format.trim === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional trim string format value - expected boolean, received \\\"\" + utilities.toString(originalTrim) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.case !== undefined) {\n\t\t\t\t\t\t\tif(utilities.isEmptyString(format.case)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional string case format value - expected non-empty string.\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar originalCase = format.case;\n\n\t\t\t\t\t\t\t\tformat.case = changeCase.camelCase(format.case.trim());\n\n\t\t\t\t\t\t\t\tif(!utilities.isFunction(stringCaseFunctions[format.case])) {\n\t\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional case format value - expected one of \" + Object.keys(stringCaseFunctions).join(\", \") + \", received \\\"\" + utilities.toString(originalCase) + \"\\\".\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"object\") {\n\t\t\t\t\tif(format.strict !== undefined) {\n\t\t\t\t\t\tvar originalStrict = format.strict;\n\n\t\t\t\t\t\tformat.strict = utilities.parseBoolean(format.strict);\n\n\t\t\t\t\t\tif(format.strict === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional strict object format value - expected boolean, received \\\"\" + utilities.toString(originalStrict) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.autopopulate !== undefined) {\n\t\t\t\t\t\t\tvar originalAutopopulate = format.autopopulate;\n\n\t\t\t\t\t\t\tformat.autopopulate = utilities.parseBoolean(format.autopopulate);\n\n\t\t\t\t\t\t\tif(format.autopopulate === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional autopopulate object format value - expected boolean, received \\\"\" + utilities.toString(originalAutopopulate) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.order !== undefined) {\n\t\t\t\t\t\t\tvar originalOrder = format.order;\n\n\t\t\t\t\t\t\tformat.order = utilities.parseBoolean(format.order);\n\n\t\t\t\t\t\t\tif(format.order === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional order object format value - expected boolean, received \\\"\" + utilities.toString(originalOrder) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.removeExtra !== undefined) {\n\t\t\t\t\t\t\tvar originalRemoveExtra = format.removeExtra;\n\n\t\t\t\t\t\t\tformat.removeExtra = utilities.parseBoolean(format.removeExtra);\n\n\t\t\t\t\t\t\tif(format.removeExtra === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional removeExtra object format value - expected boolean, received \\\"\" + utilities.toString(originalRemoveExtra) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"regexp\" || format.type === \"regularexpression\") {\n\t\t\t\t\tformat.type = \"regex\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"func\") {\n\t\t\t\t\tformat.type = \"function\";\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.format !== undefined && !utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional format format value - expected object, received \\\"\" + utilities.toString(format.format) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"string\" || format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.nonEmpty !== undefined) {\n\t\t\t\t\t\t\tvar originalNonEmpty = format.nonEmpty;\n\n\t\t\t\t\t\t\tformat.nonEmpty = utilities.parseBoolean(format.nonEmpty);\n\n\t\t\t\t\t\t\tif(format.nonEmpty === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional nonEmpty format value - expected boolean, received \\\"\" + utilities.toString(originalNonEmpty) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.nullable !== undefined) {\n\t\t\t\tvar originalNullable = format.nullable;\n\n\t\t\t\tformat.nullable = utilities.parseBoolean(format.nullable);\n\n\t\t\t\tif(format.nullable === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional nullable format value - expected boolean, received \\\"\" + utilities.toString(originalNullable) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.required !== undefined) {\n\t\t\t\tvar originalRequired = format.required;\n\n\t\t\t\tformat.required = utilities.parseBoolean(format.required);\n\n\t\t\t\tif(format.required === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional required format value - expected boolean, received \\\"\" + utilities.toString(originalRequired) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.parser !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.parser)) {\n\t\t\t\t\terrorMessage = \"Invalid optional parser format value - expected function, received \\\"\" + utilities.toString(format.parser) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.validator !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.validator)) {\n\t\t\t\t\terrorMessage = \"Invalid optional validator format value - expected function, received \\\"\" + utilities.toString(format.validator) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.formatter !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.formatter)) {\n\t\t\t\t\terrorMessage = \"Invalid optional formatter format value - expected function, received \\\"\" + utilities.toString(format.formatter) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isFunction(format.parser)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar formattedValue = undefined;\n\n\t\tif(value === undefined) {\n\t\t\tformattedValue = utilities.clone(format.default);\n\t\t}\n\t\telse if(value === null) {\n\t\t\tif(format.nullable) {\n\t\t\t\tformattedValue = null;\n\t\t\t}\n\t\t\telse if(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Value cannot be null!\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"boolean\") {\n\t\t\tformattedValue = utilities.parseBoolean(value);\n\n\t\t\tif(formattedValue === null) {\n\t\t\t\terrorMessage = \"Invalid boolean value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"integer\") {\n\t\t\tformattedValue = utilities.parseInteger(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid integer value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"float\") {\n\t\t\tformattedValue = utilities.parseFloatingPointNumber(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid float value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"string\") {\n\t\t\tformattedValue = typeof value === \"string\" ? value : utilities.toString(value);\n\n\t\t\tif(format.trim) {\n\t\t\t\tformattedValue = formattedValue.trim();\n\t\t\t}\n\n\t\t\tif(format.case !== undefined) {\n\t\t\t\tformattedValue = stringCaseFunctions[format.case](formattedValue);\n\t\t\t}\n\n\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\tvar message = \"String value cannot be empty.\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"array\") {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\tif(!Array.isArray(formattedValue)) {\n\t\t\t\t\t\terrorMessage = \"Invalid stringified array value type - expected array: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\terrorMessage = \"Invalid stringified array value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(Array.isArray(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Invalid value type - expected array or stringified array: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\tif(Array.isArray(formattedValue)) {\n\t\t\t\t\tvar formattedArray = [];\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\tvar formattedElement = null;\n\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, subOptions);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(formattedElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(utilities.clone(formattedValue[i]));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tformattedValue = formattedArray;\n\n\t\t\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\t\t\tvar message = \"Array value cannot be empty.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"date\") {\n\t\t\tformattedValue = utilities.parseDate(value);\n\n\t\t\tif(!utilities.isDate(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid date value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"regex\") {\n\t\t\tif(utilities.isRegularExpression(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\terrorMessage = error.message;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid regular expression value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"function\") {\n\t\t\tformattedValue = value;\n\n\t\t\tif(!utilities.isFunction(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid function value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.type === \"object\") {\n\t\t\t\tif(utilities.isValid(value)) {\n\t\t\t\t\tif(typeof value === \"string\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\t\t\tif(!utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(utilities.isObject(value, format.strict)) {\n\t\t\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\terrorMessage = \"Invalid value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object or stringified object: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\t\t\tif(format.autopopulate && !utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\tformattedValue = { };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format) && utilities.isObject(formattedValue)) {\n\t\t\t\t\t\tvar attribute = null;\n\t\t\t\t\t\tvar attributes = Object.keys(format.format);\n\n\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], options);\n\n\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], subOptions);\n\n\t\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.removeExtra) {\n\t\t\t\t\t\t\tvar newValue = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(utilities.isValid(format.format[attribute])) {\n\t\t\t\t\t\t\t\t\tnewValue[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = newValue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.order) {\n\t\t\t\t\t\t\tvar orderedObject = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(format.format);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(formattedValue[attribute] !== undefined) {\n\t\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\n\t\t\t\t\t\t\t\t\tdelete formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar extraAttributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < extraAttributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = extraAttributes[i];\n\n\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = orderedObject;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(format.nonEmpty && utilities.isEmptyObject(formattedValue)) {\n\t\t\t\t\t\tvar message = \"Object value must contain at least one attribute.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(formattedValue === undefined) {\n\t\t\tif(format.required) {\n\t\t\t\tvar message = \"Missing required value!\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.validator)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\tthrow new Error(\"Validation check failed!\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\t\tvar message = \"Validation check failed!\";\n\n\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.formatter)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.formatObject = function formatObject(object, format, removeExtra, throwErrors) {\n\t\tif(!utilities.isObjectStrict(object) && (!utilities.isObjectStrict(removeExtra) || !utilities.isFunction(removeExtra.parser))) {\n\t\t\treturn { };\n\t\t}\n\n\t\tvar options = null;\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(removeExtra.throwErrors, utilities.parseBoolean(throwErrors, false)),\n\t\t\t\tverbose: utilities.parseBoolean(removeExtra.verbose, false)\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(throwErrors, false),\n\t\t\t\tverbose: false\n\t\t\t};\n\t\t}\n\n\t\tvar subFormat = {\n\t\t\ttype: \"object\",\n\t\t\tstrict: false,\n\t\t\tautopopulate: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.autopopulate, false) : false,\n\t\t\torder: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.order, false) : false,\n\t\t\tremoveExtra: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.removeExtra, utilities.parseBoolean(removeExtra, false)) : utilities.parseBoolean(removeExtra, false),\n\t\t\tnullable: true,\n\t\t\trequired: false,\n\t\t\tformat: format\n\t\t};\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\tif(utilities.isFunction(removeExtra.parser)) {\n\t\t\t\tsubFormat.parser = removeExtra.parser;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.validator)) {\n\t\t\t\tsubFormat.validator = removeExtra.validator;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.formatter)) {\n\t\t\t\tsubFormat.formatter = removeExtra.formatter;\n\t\t\t}\n\t\t}\n\n\t\tvar formattedObject = null;\n\n\t\tif(options.throwErrors) {\n\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\tobject,\n\t\t\t\tsubFormat,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\tsubOptions.throwErrors = true;\n\n\t\t\ttry {\n\t\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\t\tobject,\n\t\t\t\t\tsubFormat,\n\t\t\t\t\tsubOptions\n\t\t\t\t);\n\t\t\t}\n\t\t\tcatch(error) {\n\t\t\t\tif(options.verbose) {\n\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn utilities.isObjectStrict(formattedObject) || (utilities.isObjectStrict(removeExtra) && utilities.isFunction(removeExtra.parser)) ? formattedObject : { };\n\t};\n\n\tutilities.formatStringList = function formatStringList(value, stringify) {\n\t\tvar data = null;\n\n\t\tif(utilities.isNonEmptyString(value)) {\n\t\t\tdata = utilities.parseStringList(value);\n\t\t}\n\t\telse if(utilities.isNonEmptyArray(value)) {\n\t\t\tdata = value;\n\t\t}\n\t\telse if(typeof value === \"string\" || Array.isArray(value)) {\n\t\t\treturn \"\";\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedList = \"\";\n\t\tvar formattedValue = null;\n\n\t\tstringify = utilities.parseBoolean(stringify);\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tif(typeof data[i] !== \"string\") {\n\t\t\t\tif(stringify === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if(stringify) {\n\t\t\t\t\tformattedValue = utilities.toString(data[i]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tformattedValue = data[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tformattedValue = data[i].trim();\n\t\t\t}\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(formattedList.length > 0) {\n\t\t\t\tformattedList += \", \";\n\t\t\t}\n\n\t\t\tformattedList += formattedValue;\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.leftShift = function leftShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number * Math.pow(2, bits);\n\t};\n\n\tutilities.rightShift = function rightShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number / Math.pow(2, bits);\n\t};\n\n\tutilities.trimString = function trimString(value, defaultValue) {\n\t\treturn typeof value === \"string\" ? value.trim() : (typeof defaultValue === \"string\" ? defaultValue : null);\n\t};\n\n\tutilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn typeof defaultValue === \"string\" ? defaultValue : null;\n\t\t}\n\n\t\tvar nullTerminatorIndex = value.indexOf(\"\\0\");\n\n\t\tif(nullTerminatorIndex >= 0) {\n\t\t\treturn value.substr(0, nullTerminatorIndex);\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.trimWhitespace = function trimWhitespace(value, trimNewlines, defaultValue) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn typeof defaultValue === \"string\" ? defaultValue : null;\n\t\t}\n\n\t\tvar trimmedString = value.replace(/^[ \\t]+|[ \\t]+$/gm, \"\");\n\n\t\tif(utilities.parseBoolean(trimNewlines, false)) {\n\t\t\ttrimmedString = trimmedString.replace(/\\r\\n?|\\n/g, \"\");\n\t\t}\n\n\t\treturn trimmedString;\n\t};\n\n\tutilities.trimTrailingNewlines = function trimTrailingNewlines(value, defaultValue) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn typeof defaultValue === \"string\" ? defaultValue : null;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn value.replace(/[ \\t\\r\\n]+$/, \"\");\n\t};\n\n\tutilities.replaceNonBreakingSpaces = function replaceNonBreakingSpaces(value) {\n\t\treturn typeof value === \"string\" ? value.replace(/ /gi, \" \") : null;\n\t};\n\n\tutilities.indentText = function indentText(value, amount, indentation, clearEmptyLines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tclearEmptyLines = utilities.parseBoolean(clearEmptyLines, true);\n\n\t\tamount = utilities.parseInteger(amount, 1);\n\n\t\tif(amount < 0) {\n\t\t\tamount = 0;\n\t\t}\n\n\t\tindentation = typeof indentation === \"string\" ? indentation : \"\\t\";\n\n\t\tvar totalIndentation = \"\";\n\n\t\tfor(var i = 0; i < amount; i++) {\n\t\t\ttotalIndentation += indentation;\n\t\t}\n\n\t\tvar line = null;\n\t\tvar lines = value.split(/\\r\\n?|\\n/g);\n\t\tvar indentedParagraph = \"\";\n\n\t\tfor(var i = 0; i < lines.length; i++) {\n\t\t\tline = lines[i];\n\n\t\t\tindentedParagraph += (utilities.isEmptyString(line) && clearEmptyLines ? \"\" : totalIndentation + line) + ((i < lines.length - 1) ? \"\\n\" : \"\");\n\t\t}\n\n\t\treturn indentedParagraph;\n\t};\n\n\tutilities.trimLeadingZeroes = function trimLeadingZeroes(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\t\telse if(formattedValue.match(/^[0]+$/)) {\n\t\t\treturn \"0\";\n\t\t}\n\n\t\treturn formattedValue.replace(/^0+/, \"\");\n\t};\n\n\tutilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) {\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.toString();\n\t\texpectedLength = utilities.parseInteger(expectedLength);\n\n\t\tif(utilities.isInvalidNumber(expectedLength) || expectedLength < 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar numberOfZeroes = expectedLength - value.length;\n\n\t\tfor(var i = 0; i < numberOfZeroes; i++) {\n\t\t\tvalue = \"0\" + value;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.toString = function toString(value) {\n\t\tif(value === undefined) {\n\t\t\treturn \"undefined\";\n\t\t}\n\t\telse if(value === null) {\n\t\t\treturn \"null\";\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value === Infinity) {\n\t\t\treturn \"Infinity\";\n\t\t}\n\t\telse if(value === -Infinity) {\n\t\t\treturn \"-Infinity\";\n\t\t}\n\t\telse if(typeof value === \"number\" && isNaN(value)) {\n\t\t\treturn \"NaN\";\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(value instanceof RegExp) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn \"/\" + value.source + \"/\" + flags;\n\t\t}\n\t\telse if(value instanceof Function) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(value instanceof Error) {\n\t\t\treturn value.stack;\n\t\t}\n\n\t\treturn JSON.stringify(value);\n\t};\n\n\tutilities.compareDates = function compareDates(a, b) {\n\t\ta = utilities.parseDate(a);\n\t\tb = utilities.parseDate(b);\n\n\t\tif(a === null && b === null) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tif(a === null) {\n\t\t\treturn -1;\n\t\t}\n\t\telse if(b === null) {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn a.getTime() - b.getTime();\n\t};\n\n\tutilities.compareCasePercentage = function compareCasePercentage(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar c = null;\n\t\tvar upper = 0;\n\t\tvar lower = 0;\n\t\tvar lowerA = \"a\".charCodeAt();\n\t\tvar lowerZ = \"z\".charCodeAt();\n\t\tvar upperA = \"A\".charCodeAt();\n\t\tvar upperZ = \"Z\".charCodeAt();\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tc = value.charCodeAt(i);\n\n\t\t\tif(c >= lowerA && c <= lowerZ) {\n\t\t\t\tlower++;\n\t\t\t}\n\t\t\telse if(c >= upperA && c <= upperZ) {\n\t\t\t\tupper++;\n\t\t\t}\n\t\t}\n\n\t\treturn upper - lower;\n\t};\n\n\tutilities.reverseString = function reverseString(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.replace(\n\t\t\t/([\\0-\\u02FF\\u0370-\\u1AAF\\u1B00-\\u1DBF\\u1E00-\\u20CF\\u2100-\\uD7FF\\uE000-\\uFE1F\\uFE30-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])([\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F]+)/g,\n\t\t\tfunction($0, $1, $2) {\n\t\t\t\treturn utilities.reverseString($2) + $1;\n\t\t\t}\n\t\t).replace(/([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])/g, \"$2$1\");\n\n\t\tvar reverse = \"\";\n\n\t\tfor(var i = value.length - 1; i >= 0; i--) {\n\t\t\treverse += value[i];\n\t\t}\n\n\t\treturn reverse;\n\t};\n\n\tutilities.createError = function createError(message, status) {\n\t\tvar error = new Error(message);\n\t\terror.status = utilities.parseInteger(status, 500);\n\t\treturn error;\n\t};\n\n\tutilities.clone = function clone(value) {\n\t\tif(!utilities.isObject(value)) {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value instanceof Boolean) {\n\t\t\treturn new Boolean(value.valueOf());\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\tvar copy = new Date();\n\t\t\tcopy.setTime(value.getTime());\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Array) {\n\t\t\tvar copy = [];\n\n\t\t\tfor(var i = 0, length = value.length; i < length; i++) {\n\t\t\t\tcopy[i] = utilities.clone(value[i]);\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Set) {\n\t\t\treturn new Set(value);\n\t\t}\n\t\telse if(value instanceof Map) {\n\t\t\treturn new Map(value);\n\t\t}\n\t\telse if(value instanceof RegExp) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new RegExp(value.source, flags);\n\t\t}\n\t\telse if(typeof Buffer !== \"undefined\" && value instanceof Buffer) {\n\t\t\treturn Buffer.from instanceof Function ? Buffer.from(value) : new Buffer(value);\n\t\t}\n\t\telse if(value instanceof Object) {\n\t\t\tvar copy = null;\n\n\t\t\tif(value instanceof Error) {\n\t\t\t\tcopy = new Error(value.message);\n\n\t\t\t\tcopy.stack = utilities.clone(value.stack);\n\n\t\t\t\tvar properties = Object.keys(value);\n\n\t\t\t\tfor(var i = 0; i < properties.length; i++) {\n\t\t\t\t\tcopy[properties[i]] = utilities.clone(value[properties[i]]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcopy = { };\n\t\t\t}\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\tif(Object.prototype.hasOwnProperty.call(value, attribute)) {\n\t\t\t\t\tcopy[attribute] = utilities.clone(value[attribute]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.merge = function merge(a, b, copy, deepMerge) {\n\t\tif(!utilities.isObject(a) || Array.isArray(a)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar newObject = null;\n\n\t\tcopy = utilities.parseBoolean(copy, true);\n\n\t\tif(copy) {\n\t\t\tnewObject = utilities.clone(a);\n\t\t}\n\t\telse {\n\t\t\tnewObject = a;\n\t\t}\n\n\t\tif(!utilities.isObject(a) || Array.isArray(a) || !utilities.isObject(b) || Array.isArray(b)) {\n\t\t\treturn newObject;\n\t\t}\n\n\t\tvar attribute = null;\n\t\tvar value = null;\n\t\tvar newValue = null;\n\t\tvar attributes = Object.keys(b);\n\n\t\tdeepMerge = utilities.parseBoolean(deepMerge, true);\n\n\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\tattribute = attributes[i];\n\t\t\tvalue = newObject[attribute];\n\n\t\t\tif(copy) {\n\t\t\t\tnewValue = utilities.clone(b[attribute]);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewValue = b[attribute];\n\t\t\t}\n\n\t\t\tif(deepMerge && utilities.isObject(value) && !Array.isArray(value) && utilities.isObject(newValue) && !Array.isArray(newValue)) {\n\t\t\t\tnewObject[attribute] = utilities.merge(value, newValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewObject[attribute] = newValue;\n\t\t\t}\n\t\t}\n\n\t\treturn newObject;\n\t};\n\n\tutilities.getFileName = function getFileName(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(i + 1, filePath.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn filePath;\n\t};\n\n\tutilities.getFilePath = function getFilePath(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.getFileExtension = function getFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(i + 1, fileName.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.fileHasExtension = function fileHasExtension(fileName, extension) {\n\t\tif(utilities.isEmptyString(fileName) || utilities.isEmptyString(extension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar actualFileExtension = utilities.getFileExtension(fileName);\n\n\t\tif(utilities.isEmptyString(actualFileExtension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn actualFileExtension.toLowerCase() === extension.trim().toLowerCase();\n\t};\n\n\tutilities.reverseFileExtension = function reverseFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = fileName.trim();\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i) + \".\" + utilities.reverseString(fileName.substring(i + 1, fileName.length));\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.truncateFileName = function truncateFileName(fileName, maxLength) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tif(utilities.isEmptyString(fileName)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tmaxLength = utilities.parseInteger(maxLength);\n\n\t\tif(utilities.isInvalidNumber(maxLength) || maxLength < 0) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tif(maxLength === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif(fileName.length <= maxLength) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tvar extension = \"\";\n\t\tvar originalFileName = fileName;\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\textension = fileName.substring(i + 1, fileName.length);\n\t\t\t\toriginalFileName = fileName.substring(0, i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(maxLength - (extension.length + (extension.length > 0 ? 1 : 0)) < 1) {\n\t\t\treturn originalFileName.substring(0, maxLength);\n\t\t}\n\n\t\treturn originalFileName.substring(0, maxLength - extension.length - (extension.length > 0 ? 1 : 0)) + (extension.length > 0 ? \".\" + extension : \"\");\n\t};\n\n\tutilities.prependSlash = function prependSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[0] !== \"/\" && formattedValue[0] !== \"\\\\\") {\n\t\t\tformattedValue = \"/\" + formattedValue;\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.appendSlash = function appendSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[formattedValue.length - 1] !== \"/\" && formattedValue[formattedValue.length - 1] !== \"\\\\\") {\n\t\t\tformattedValue += \"/\";\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.joinPaths = function joinPaths(paths, options) {\n\t\tif(!Array.isArray(paths)) {\n\t\t\tpaths = Array.prototype.slice.call(arguments);\n\t\t}\n\n\t\tif(paths.length !== 0 && utilities.isObjectStrict(paths[paths.length - 1])) {\n\t\t\toptions = paths.splice(paths.length - 1, 1)[0];\n\t\t}\n\n\t\tif(!utilities.isObjectStrict(options)) {\n\t\t\toptions = { };\n\t\t}\n\n\t\toptions.separator = utilities.trimString(options.separator);\n\n\t\tif(options.separator !== \"/\" && options.separator !== \"\\\\\") {\n\t\t\toptions.separator = \"/\";\n\t\t}\n\n\t\tvar newPath = \"\";\n\n\t\tfor(var i = 0; i < paths.length; i++) {\n\t\t\tvar path = utilities.trimString(paths[i]);\n\n\t\t\tif(utilities.isEmptyString(path)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(utilities.isEmptyString(newPath)) {\n\t\t\t\tif(path === \"/\" || path === \"\\\\\") {\n\t\t\t\t\tnewPath = path;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnewPath = path.replace(/[\\/\\\\]+$/, \"\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tpath = path.replace(/^[\\/\\\\]+/, \"\");\n\n\t\t\t\tif(utilities.isNonEmptyString(path)) {\n\t\t\t\t\tif(newPath[newPath.length - 1] !== options.separator) {\n\t\t\t\t\t\tnewPath += options.separator;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPath += path;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn newPath.replace(/[\\/\\\\]/g, options.separator);\n\t};\n\n\tutilities.createQueryString = function createQueryString(value, includeQuestionMark) {\n\t\tif(!utilities.isObjectStrict(value)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar parameters = Object.keys(value).map(function(key) {\n\t\t\treturn encodeURIComponent(key) + \"=\" + encodeURIComponent(utilities.toString(value[key]));\n\t\t}).join(\"&\");\n\n\t\tif(parameters.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\treturn (utilities.parseBoolean(includeQuestionMark, false) ? \"?\" : \"\") + parameters;\n\t};\n\n\tutilities.createRange = function createRange(start, end) {\n\t\tvar formattedStart = utilities.parseInteger(start);\n\t\tvar formattedEnd = utilities.parseInteger(end);\n\n\t\tif(arguments.length === 1) {\n\t\t\tformattedEnd = formattedStart;\n\t\t\tformattedStart = 0;\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(formattedStart) || utilities.isInvalidNumber(formattedEnd) || formattedStart > formattedEnd) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar range = [];\n\n\t\tfor(var i = formattedStart; i <= formattedEnd; i++) {\n\t\t\trange.push(i);\n\t\t}\n\n\t\treturn range;\n\t};\n\n\tutilities.futureMonths = function futureMonths(date, prependZero) {\n\t\tdate = utilities.parseDate(date);\n\n\t\tif(date === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar currentDate = new Date();\n\t\tvar month = 0;\n\n\t\tif(date.getFullYear() === currentDate.getFullYear()) {\n\t\t\tmonth = currentDate.getMonth();\n\t\t}\n\n\t\tvar months = [];\n\n\t\tprependZero = utilities.parseBoolean(prependZero, false);\n\n\t\tfor(var i = 0; i < 12; i++) {\n\t\t\tif(i >= month) {\n\t\t\t\tif(prependZero) {\n\t\t\t\t\tmonths.push((i <= 8 ? \"0\" : \"\") + (i + 1));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmonths.push(i + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn months;\n\t};\n\n\tutilities.visibleElements = function visibleElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar visibleElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isVisible(elements[i])) {\n\t\t\t\tvisibleElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn visibleElements;\n\t};\n\n\tutilities.hiddenElements = function hiddenElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar hiddenElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isHidden(elements[i])) {\n\t\t\t\thiddenElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn hiddenElements;\n\t};\n\n\tutilities.enabledElements = function enabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar enabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isEnabled(elements[i])) {\n\t\t\t\tenabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn enabledElements;\n\t};\n\n\tutilities.disabledElements = function disabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar disabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isDisabled(elements[i])) {\n\t\t\t\tdisabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn disabledElements;\n\t};\n\n\tutilities.elementsWithAttribute = function elementsWithAttribute(elements, attribute, hasAttribute) {\n\t\tif(!Array.isArray(elements) || utilities.isEmptyString(attribute)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar element = null;\n\t\tvar filteredElements = [];\n\n\t\tattribute = attribute.trim();\n\t\thasAttribute = utilities.parseBoolean(hasAttribute, true);\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\telement = elements[i];\n\n\t\t\tif(!utilities.isObject(element)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(elements[i][attribute])) {\n\t\t\t\tif(!hasAttribute) {\n\t\t\t\t\tfilteredElements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(hasAttribute) {\n\t\t\t\t\tfilteredElements.push(elements[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn filteredElements;\n\t};\n\n\tutilities.elementsWithoutAttribute = function elementsWithoutAttribute(elements, attribute) {\n\t\treturn utilities.elementsWithAttribute(elements, attribute, false);\n\t};\n\n\tutilities.matchAttribute = function matchAttribute(element, attribute, value) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(attribute)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn element[attribute.trim()] === value;\n\t};\n\n\tutilities.generateVersions = function generateVersions(version, prefix, suffix) {\n\t\tversion = utilities.parseVersion(version);\n\n\t\tif(version === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tprefix = utilities.trimString(prefix);\n\t\tsuffix = utilities.trimString(suffix);\n\n\t\tvar versions = [];\n\t\tvar value = null;\n\n\t\tfor(var i = 0; i < version.length; i++) {\n\t\t\tvalue = \"\";\n\n\t\t\tif(utilities.isNonEmptyString(prefix)) {\n\t\t\t\tvalue += prefix;\n\t\t\t}\n\n\t\t\tfor(var j = 0; j <= i; j++) {\n\t\t\t\tif(j > 0) {\n\t\t\t\t\tvalue += \"_\";\n\t\t\t\t}\n\n\t\t\t\tvalue += version[j];\n\t\t\t}\n\n\t\t\tif(utilities.isNonEmptyString(suffix)) {\n\t\t\t\tvalue += suffix;\n\t\t\t}\n\n\t\t\tversions.push(value);\n\t\t}\n\n\t\treturn versions;\n\t};\n\n\tutilities.parseVersion = function parseVersion(value, trimTrailingZeroes) {\n\t\tvar formattedValue = utilities.isValidNumber(value) ? value.toString() : value;\n\n\t\tif(typeof formattedValue !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar version = [];\n\t\tvar versionData = formattedValue.match(/[^. \\t]+/g);\n\n\t\tif(versionData === null || versionData.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar part = null;\n\n\t\tfor(var i = 0; i < versionData.length; i++) {\n\t\t\tif(utilities.isInteger(versionData[i])) {\n\t\t\t\tpart = utilities.parseInteger(versionData[i]);\n\n\t\t\t\tif(utilities.isInvalidNumber(part) || part < 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tversion.push(part.toString());\n\t\t\t}\n\t\t\telse {\n\t\t\t\tversion.push(versionData[i]);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.parseBoolean(trimTrailingZeroes, false)) {\n\t\t\twhile(true) {\n\t\t\t\tif(version.length <= 1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif(version[version.length - 1] === \"0\") {\n\t\t\t\t\tversion.pop();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn version.length === 0 ? null : version;\n\t};\n\n\tutilities.compareVersions = function compareVersions(v1, v2, caseSensitive) {\n\t\tcaseSensitive = utilities.parseBoolean(caseSensitive, false);\n\n\t\tv1 = utilities.parseVersion(v1);\n\n\t\tif(v1 === null) {\n\t\t\tthrow new Error(\"Cannot compare invalid or empty first version.\");\n\t\t}\n\n\t\tv2 = utilities.parseVersion(v2);\n\n\t\tif(v2 === null) {\n\t\t\tthrow new Error(\"Cannot compare invalid or empty second version.\");\n\t\t}\n\n\t\tvar index = 0;\n\n\t\twhile(true) {\n\t\t\tif(index >= v1.length) {\n\t\t\t\tif(v1.length === v2.length) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tfor(var i = index; i < v2.length; i++) {\n\t\t\t\t\tif(v2[i] !== \"0\") {\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tif(index >= v2.length) {\n\t\t\t\tfor(var i = index; i < v1.length; i++) {\n\t\t\t\t\tif(v1[i] !== \"0\") {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tvar formattedA = utilities.parseInteger(v1[index]);\n\t\t\tvar formattedB = utilities.parseInteger(v2[index]);\n\n\t\t\tif(utilities.isInvalidNumber(formattedA)) {\n\t\t\t\tformattedA = caseSensitive ? v1[index] : v1[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(formattedB)) {\n\t\t\t\tformattedB = caseSensitive ? v2[index] : v2[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(Number.isInteger(formattedA)) {\n\t\t\t\tif(!Number.isInteger(formattedB)) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(Number.isInteger(formattedB)) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(formattedA > formattedB) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse if(formattedA < formattedB) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tindex++;\n\t\t}\n\t};\n\n\treturn utilities;\n\n}));\n"],"file":"extra-utilities.js"} \ No newline at end of file diff --git a/dist/extra-utilities.min.js b/dist/extra-utilities.min.js index b27cb04..2a666c9 100644 --- a/dist/extra-utilities.min.js +++ b/dist/extra-utilities.min.js @@ -1,2 +1 @@ -!function(global,factory){"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define(factory):global.utilities=factory()}(this,function(){"use strict";"undefined"!=typeof require&&("undefined"==typeof validator&&(global.validator=require("validator")),"undefined"==typeof changeCase&&(global.changeCase=require("change-case-bundled")));var utilities={},regExpFlags={global:"g",multiline:"m",ignoreCase:"i",sticky:"y",unicode:"u"},formatTypes=["boolean","bool","integer","int","float","number","string","object","array","date","regex","regexp","regularexpression","function","func"],stringCaseFunctions={camel:changeCase.camelCase,capital:changeCase.capitalCase,constant:changeCase.constantCase,dot:changeCase.dotCase,header:changeCase.headerCase,lower:changeCase.lowerCase,lowerFirst:changeCase.lowerCaseFirst,no:changeCase.noCase,param:changeCase.paramCase,pascal:changeCase.pascalCase,path:changeCase.pathCase,sentence:changeCase.sentenceCase,snake:changeCase.snakeCase,sponge:changeCase.spongeCase,swap:changeCase.swapCase,title:changeCase.titleCase,upper:changeCase.upperCase,upperFirst:changeCase.upperCaseFirst};return utilities.isValid=function(value){return null!=value},utilities.isInvalid=function(value){return null==value},utilities.isBoolean=function(value,allowObjects){return!0===value||!1===value||!!allowObjects&&value instanceof Boolean},utilities.isValidNumber=function(value){return"number"==typeof value&&!isNaN(value)&&value!==-1/0&&value!==1/0},utilities.isInvalidNumber=function(value){return"number"!=typeof value||isNaN(value)||value===-1/0||value===1/0},utilities.isEmptyString=function(value,trim){return"string"!=typeof value||(utilities.parseBoolean(trim,!0)?0===value.trim().length:0===value.length)},utilities.isNonEmptyString=function(value,trim){return"string"==typeof value&&(utilities.parseBoolean(trim,!0)?0!==value.trim().length:0!==value.length)},utilities.isObject=function(value,strict){return void 0!==value&&(strict?null!==value&&value.constructor===Object:value instanceof Object&&!(value instanceof Function))},utilities.isObjectStrict=function(value){return null!=value&&value.constructor===Object},utilities.isEmptyObject=function(value){return null!=value&&value.constructor===Object&&0===Object.keys(value).length},utilities.isNonEmptyObject=function(value){return null!=value&&value.constructor===Object&&0!==Object.keys(value).length},utilities.isEmptyArray=function(value){return!Array.isArray(value)||0===value.length},utilities.isNonEmptyArray=function(value){return Array.isArray(value)&&0!==value.length},utilities.isDate=function(value){return value instanceof Date},utilities.isError=function(value){return value instanceof Error},utilities.isRegularExpression=function(value){return value instanceof RegExp},utilities.isFunction=function(value){return value instanceof Function},utilities.isComment=function(value,comment){if(utilities.isEmptyString(value))return!1;utilities.isEmptyString(comment)&&(comment="//");for(var commentStartIndex=-1,i=0;i=comment.length);i++)if(value[i]!=comment[i-commentStartIndex])return!1;return!0},utilities.isVisible=function(element){return!!utilities.isObject(element)&&(utilities.isBoolean(element.visible)?element.visible:utilities.isFunction(element.visible)?element.visible():utilities.isBoolean(element.hidden)?!element.hidden:!utilities.isFunction(element.hidden)||!element.hidden())},utilities.isHidden=function(element){return!utilities.isObject(element)||(utilities.isBoolean(element.visible)?!element.visible:utilities.isFunction(element.visible)?!element.visible():utilities.isBoolean(element.hidden)?element.hidden:!!utilities.isFunction(element.hidden)&&element.hidden())},utilities.isEnabled=function(element){return!!utilities.isObject(element)&&(utilities.isBoolean(element.enabled)?element.enabled:utilities.isFunction(element.enabled)?element.enabled():utilities.isBoolean(element.disabled)?!element.disabled:!utilities.isFunction(element.disabled)||!element.disabled())},utilities.isDisabled=function(element){return!utilities.isObject(element)||(utilities.isBoolean(element.enabled)?!element.enabled:utilities.isFunction(element.enabled)?!element.enabled():utilities.isBoolean(element.disabled)?element.disabled:!!utilities.isFunction(element.disabled)&&element.disabled())},utilities.equalsIgnoreCase=function(stringA,stringB){return"string"==typeof stringA&&"string"==typeof stringB&&0===stringA.localeCompare(stringB,void 0,{sensitivity:"accent"})},utilities.parseBoolean=function(value,defaultValue){if(utilities.isBoolean(value))return value;if(utilities.isBoolean(value,!0))return value.valueOf();if(utilities.isBoolean(defaultValue)||(defaultValue=null),utilities.isInvalid(value))return defaultValue;if(0===value)return!1;if(1===value)return!0;if("string"!=typeof value)return defaultValue;var formattedValue=value.trim().toLowerCase();if(0===formattedValue.length)return defaultValue;if(1!==formattedValue.length)return"true"===formattedValue||"yes"===formattedValue||"on"===formattedValue||"false"!==formattedValue&&"no"!==formattedValue&&"off"!==formattedValue&&defaultValue;var character=formattedValue.charAt(0);return"t"===character||"y"===character||"f"!==character&&"n"!==character&&("0"!==character&&("1"===character||defaultValue))},utilities.parseInteger=function(value,defaultValue){var newValue=NaN;return("number"==typeof value||"string"==typeof value&&validator.isFloat(value))&&(newValue=parseInt(value)),utilities.isInvalidNumber(newValue)?(defaultValue=parseInt(defaultValue),utilities.isValidNumber(defaultValue)?defaultValue:NaN):newValue},utilities.parseFloatingPointNumber=function(value,defaultValue){var newValue=NaN;return"number"==typeof value?newValue=value:"string"==typeof value&&validator.isFloat(value)&&(newValue=parseFloat(value)),utilities.isInvalidNumber(newValue)?utilities.isValidNumber(defaultValue)?defaultValue:NaN:newValue},utilities.parseDate=function(value,defaultValue){if(utilities.isDate(defaultValue)||(defaultValue=null),"number"==typeof value)return utilities.isInvalidNumber(value)||!Number.isInteger(value)?defaultValue:new Date(parseInt(value));if("string"!=typeof value)return value instanceof Date?value:defaultValue;var formattedValue=value.trim();if(0===formattedValue.length)return defaultValue;var timestamp=null;return timestamp=validator.isInt(formattedValue)?parseInt(formattedValue):Date.parse(formattedValue),utilities.isInvalidNumber(timestamp)?defaultValue:new Date(timestamp)},utilities.parseTime=function(value,throwErrors){if(throwErrors=utilities.parseBoolean(throwErrors),utilities.isEmptyString(value)){if(throwErrors)throw new Error("Invalid or empty time value.");return null}var formattedValue=value.trim(),hour=null,minutes=null,regularTime=formattedValue.match(/^[ \t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \t]*([ap]m))[ \t]*$/i);if(regularTime){var regularHour=utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));if(utilities.isInvalidNumber(regularHour)){if(throwErrors)throw new Error('Invalid regular hour: "'+regularTime[2]+'".');return null}minutes=utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4])),utilities.isInvalidNumber(minutes)&&(minutes=0);var morning="AM"===(period=regularTime[5].toUpperCase())||"PM"!==period&&null;if(null===morning){if(throwErrors)throw new Error('Invalid period: "'+regularTime[5]+'".');return null}24===(hour=morning?regularHour+(12===regularHour?12:0):regularHour+(12===regularHour?0:12))&&(hour=0)}else{var militaryTime=formattedValue.match(/^[ \t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \t]*$/i);if(!militaryTime){if(throwErrors)throw new Error('Invalid time: "'+formattedValue+'".');return null}var militaryHour=militaryTime[3],militaryMinutes=militaryTime[6];if((utilities.isInvalid(militaryHour)||utilities.isInvalid(militaryMinutes))&&(militaryHour=militaryTime[8],utilities.isNonEmptyString(militaryTime[9])&&(militaryMinutes=militaryTime[9])),utilities.isInvalid(militaryHour)||utilities.isInvalid(militaryMinutes)){if(throwErrors)throw new Error('Invalid military time: "'+formattedValue+'".');return null}if(hour=utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour)),utilities.isInvalidNumber(hour)){if(throwErrors)throw new Error('Invalid military time hour: "'+militaryHour+'".');return null}if(minutes=utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes)),utilities.isInvalidNumber(minutes)){if(throwErrors)throw new Error('Invalid military time minutes: "'+militaryMinutes+'".');return null}24===hour&&0===minutes&&(hour=0)}if(hour<0||23=v1.length){if(v1.length===v2.length)return 0;for(var i=index;i=v2.length){for(i=index;i=comment.length);i++)if(value[i]!=comment[i-commentStartIndex])return!1;return!0},utilities.isVisible=function(element){return!!utilities.isObject(element)&&(utilities.isBoolean(element.visible)?element.visible:utilities.isFunction(element.visible)?element.visible():utilities.isBoolean(element.hidden)?!element.hidden:!utilities.isFunction(element.hidden)||!element.hidden())},utilities.isHidden=function(element){return!utilities.isObject(element)||(utilities.isBoolean(element.visible)?!element.visible:utilities.isFunction(element.visible)?!element.visible():utilities.isBoolean(element.hidden)?element.hidden:!!utilities.isFunction(element.hidden)&&element.hidden())},utilities.isEnabled=function(element){return!!utilities.isObject(element)&&(utilities.isBoolean(element.enabled)?element.enabled:utilities.isFunction(element.enabled)?element.enabled():utilities.isBoolean(element.disabled)?!element.disabled:!utilities.isFunction(element.disabled)||!element.disabled())},utilities.isDisabled=function(element){return!utilities.isObject(element)||(utilities.isBoolean(element.enabled)?!element.enabled:utilities.isFunction(element.enabled)?!element.enabled():utilities.isBoolean(element.disabled)?element.disabled:!!utilities.isFunction(element.disabled)&&element.disabled())},utilities.equalsIgnoreCase=function(stringA,stringB){return"string"==typeof stringA&&"string"==typeof stringB&&0===stringA.localeCompare(stringB,void 0,{sensitivity:"accent"})},utilities.parseBoolean=function(value,defaultValue){if(utilities.isBoolean(value))return value;if(utilities.isBoolean(value,!0))return value.valueOf();if(utilities.isBoolean(defaultValue)||(defaultValue=null),utilities.isInvalid(value))return defaultValue;if(0===value)return!1;if(1===value)return!0;if("string"!=typeof value)return defaultValue;var formattedValue=value.trim().toLowerCase();if(0===formattedValue.length)return defaultValue;if(1!==formattedValue.length)return"true"===formattedValue||"yes"===formattedValue||"on"===formattedValue||"false"!==formattedValue&&"no"!==formattedValue&&"off"!==formattedValue&&defaultValue;var character=formattedValue.charAt(0);return"t"===character||"y"===character||"f"!==character&&"n"!==character&&("0"!==character&&("1"===character||defaultValue))},utilities.parseInteger=function(value,defaultValue){var newValue=NaN;return"number"==typeof value?newValue=parseInt(value):"string"==typeof value?utilities.isFloat(value)&&(newValue=parseInt(value)):value instanceof Number&&(newValue=parseInt(value.valueOf())),utilities.isInvalidNumber(newValue)?(defaultValue=parseInt(defaultValue),utilities.isValidNumber(defaultValue)?defaultValue:NaN):newValue},utilities.parseFloat=function(value,defaultValue){var newValue=NaN;return"number"==typeof value?newValue=value:"string"==typeof value?utilities.isFloat(value)&&(newValue=parseFloat(value)):value instanceof Number&&(newValue=value.valueOf()),utilities.isInvalidNumber(newValue)?utilities.isValidNumber(defaultValue)?defaultValue:NaN:newValue},utilities.parseFloatingPointNumber=utilities.parseFloat,utilities.parseDate=function(value,defaultValue){if(utilities.isDate(defaultValue)||(defaultValue=null),"number"==typeof value)return utilities.isInvalidNumber(value)||!Number.isInteger(value)||value<0?defaultValue:new Date(parseInt(value));if("string"!=typeof value)return value instanceof Date?value:defaultValue;var formattedValue=value.trim();if(0===formattedValue.length)return defaultValue;var timestamp=null;return timestamp=utilities.isInteger(formattedValue)?parseInt(formattedValue):Date.parse(formattedValue),utilities.isInvalidNumber(timestamp)?defaultValue:new Date(timestamp)},utilities.parseTime=function(value){if(utilities.isEmptyString(value))throw new Error("Invalid or empty time value.");var formattedValue=value.trim(),hour=null,minutes=null,regularTime=formattedValue.match(/^[ \t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \t]*([ap]m))[ \t]*$/i);if(regularTime){var regularHour=utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));if(utilities.isInvalidNumber(regularHour))throw new Error('Invalid regular hour: "'+regularTime[2]+'".');minutes=utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4])),utilities.isInvalidNumber(minutes)&&(minutes=0);var morning="AM"===(period=regularTime[5].toUpperCase())||"PM"!==period&&null;if(null===morning)throw new Error('Invalid period: "'+regularTime[5]+'".');24===(hour=morning?regularHour+(12===regularHour?12:0):regularHour+(12===regularHour?0:12))&&(hour=0)}else{var militaryTime=formattedValue.match(/^[ \t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \t]*$/i);if(!militaryTime)throw new Error('Invalid time: "'+formattedValue+'".');var militaryHour=militaryTime[3],militaryMinutes=militaryTime[6];if((utilities.isInvalid(militaryHour)||utilities.isInvalid(militaryMinutes))&&(militaryHour=militaryTime[8],utilities.isNonEmptyString(militaryTime[9])&&(militaryMinutes=militaryTime[9])),utilities.isInvalid(militaryHour)||utilities.isInvalid(militaryMinutes))throw new Error('Invalid military time: "'+formattedValue+'".');if(hour=utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour)),utilities.isInvalidNumber(hour))throw new Error('Invalid military time hour: "'+militaryHour+'".');if(minutes=utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes)),utilities.isInvalidNumber(minutes))throw new Error('Invalid military time minutes: "'+militaryMinutes+'".');24===hour&&0===minutes&&(hour=0)}if(hour<0||23=v1.length){if(v1.length===v2.length)return 0;for(var i=index;i=v2.length){for(i=index;i= comment.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(value[i] != comment[i - commentStartIndex]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isVisible = function isVisible(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn !element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn !element.hidden();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isHidden = function isHidden(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn !element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn !element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn element.hidden();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.isEnabled = function isEnabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn !element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn !element.disabled();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isDisabled = function isDisabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn !element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn !element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn element.disabled();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) {\n\t\tif(typeof stringA !== \"string\" || typeof stringB !== \"string\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn stringA.localeCompare(stringB, undefined, { sensitivity: \"accent\" }) === 0;\n\t};\n\n\tutilities.parseBoolean = function parseBoolean(value, defaultValue) {\n\t\tif(utilities.isBoolean(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isBoolean(value, true)) {\n\t\t\treturn value.valueOf();\n\t\t}\n\n\t\tif(!utilities.isBoolean(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(value === 0) {\n\t\t\treturn false;\n\t\t}\n\t\telse if(value === 1) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tvar formattedValue = value.trim().toLowerCase();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue.length === 1) {\n\t\t\tvar character = formattedValue.charAt(0);\n\n\t\t\tif(character === \"t\" || character === \"y\") {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if(character === \"f\" || character === \"n\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"0\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"1\") {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue === \"true\" || formattedValue === \"yes\" || formattedValue === \"on\") {\n\t\t\treturn true;\n\t\t}\n\t\telse if(formattedValue === \"false\" || formattedValue === \"no\" || formattedValue === \"off\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseInteger = function parseInteger(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = parseInt(value);\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(validator.isFloat(value)) {\n\t\t\t\tnewValue = parseInt(value);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\tdefaultValue = parseInt(defaultValue);\n\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseFloatingPointNumber = function parseFloatingPointNumber(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = value;\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(validator.isFloat(value)) {\n\t\t\t\tnewValue = parseFloat(value);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseDate = function parseDate(value, defaultValue) {\n\t\tif(!utilities.isDate(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(typeof value === \"number\") {\n\t\t\tif(utilities.isInvalidNumber(value) || !Number.isInteger(value)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(parseInt(value));\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tvar formattedValue = value.trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\tvar timestamp = null;\n\n\t\t\tif(validator.isInt(formattedValue)) {\n\t\t\t\ttimestamp = parseInt(formattedValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimestamp = Date.parse(formattedValue);\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(timestamp)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(timestamp);\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseTime = function parseTime(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors);\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid or empty time value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar hour = null;\n\t\tvar minutes = null;\n\t\tvar regularTime = formattedValue.match(/^[ \\t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \\t]*([ap]m))[ \\t]*$/i);\n\n\t\tif(regularTime) {\n\t\t\tvar regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));\n\n\t\t\tif(utilities.isInvalidNumber(regularHour)) {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid regular hour: \\\"\" + regularTime[2] + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4]));\n\n\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\tminutes = 0;\n\t\t\t}\n\n\t\t\tvar period = regularTime[5].toUpperCase();\n\t\t\tvar morning = period === \"AM\" ? true : (period === \"PM\" ? false : null);\n\n\t\t\tif(morning === null) {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid period: \\\"\" + regularTime[5] + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\thour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12);\n\n\t\t\tif(hour === 24) {\n\t\t\t\thour = 0;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tvar militaryTime = formattedValue.match(/^[ \\t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \\t]*$/i);\n\n\t\t\tif(militaryTime) {\n\t\t\t\tvar militaryHour = militaryTime[3];\n\t\t\t\tvar militaryMinutes = militaryTime[6];\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tmilitaryHour = militaryTime[8];\n\n\t\t\t\t\tif(utilities.isNonEmptyString(militaryTime[9])) {\n\t\t\t\t\t\tmilitaryMinutes = militaryTime[9];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\thour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour));\n\n\t\t\t\tif(utilities.isInvalidNumber(hour)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time hour: \\\"\" + militaryHour + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes));\n\n\t\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time minutes: \\\"\" + militaryMinutes + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif(hour === 24 && minutes === 0) {\n\t\t\t\t\thour = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tif(hour < 0 || hour > 23) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Time hour is out of range (0 - 23): \\\"\" + hour + \"\\\".\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\telse if(minutes < 0 || minutes > 59) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Time minutes is out of range (0 - 59): \\\"\" + minutes + \"\\\".\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12);\n\t\tvar period = hour < 12 ? \"AM\" : \"PM\";\n\n\t\treturn {\n\t\t\tregular: {\n\t\t\t\traw: regularHour + \":\" + utilities.addLeadingZeroes(minutes, 2) + \" \" + period,\n\t\t\t\thour: regularHour,\n\t\t\t\tminutes: minutes,\n\t\t\t\tperiod: period,\n\t\t\t\tmorning: hour < 12\n\t\t\t},\n\t\t\tmilitary: {\n\t\t\t\traw: utilities.addLeadingZeroes(hour, 2) + utilities.addLeadingZeroes(minutes, 2),\n\t\t\t\thour: hour,\n\t\t\t\tminutes: minutes\n\t\t\t}\n\t\t};\n\t};\n\n\tutilities.parseEmail = function parseEmail(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?(@.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailData) || emailData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailData[1] + emailData[3];\n\t};\n\n\tutilities.parseEmailDomain = function parseEmailDomain(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailDomainData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?@(.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailDomainData) || emailDomainData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailDomainData[3];\n\t};\n\n\tutilities.parseStringList = function parseStringList(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar data = value.split(/[;,]+/);\n\t\tvar formattedList = [];\n\t\tvar formattedValue = null;\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tformattedValue = data[i].trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tformattedList.push(formattedValue);\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.parseRegularExpression = function parseRegularExpression(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tif(utilities.isRegularExpression(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Regular expression cannot be empty.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regExpData = value.match(/\\s*\\/(.*)\\/(.*)\\s*/);\n\n\t\tif(!regExpData) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid regular expression value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(throwErrors) {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\t\tcatch(error) {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\tutilities.parseYouTubeLink = function parseYouTubeLink(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar linkData = formattedValue.match(/.*(?:youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=)([^#\\&\\?]*).*/i);\n\n\t\tif(linkData && linkData[1].length >= 11) {\n\t\t\treturn linkData[1];\n\t\t}\n\n\t\tif(formattedValue.match(/[A-Z0-9_-]{11,}/i)) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\treturn null;\n\t};\n\n\tutilities.formatValue = function formatValue(value, format, options) {\n\t\tif(utilities.isObjectStrict(options)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(options.throwErrors, false)\n\t\t\t};\n\n\t\t\toptions.verbose = utilities.parseBoolean(options.verbose, !options.throwErrors);\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: false,\n\t\t\t\tverbose: true\n\t\t\t};\n\t\t}\n\n\t\tif(!utilities.isObjectStrict(format)) {\n\t\t\treturn utilities.clone(value);\n\t\t}\n\n\t\tformat = utilities.clone(format);\n\n\t\tvar errorMessage = null;\n\n\t\tif(utilities.isEmptyString(format.type)) {\n\t\t\terrorMessage = \"Invalid required type format value - expected non-empty string.\";\n\t\t}\n\t\telse {\n\t\t\tvar originalType = format.type;\n\n\t\t\tformat.type = format.type.trim().toLowerCase();\n\n\t\t\tvar validFormatType = false;\n\n\t\t\tfor(var i = 0; i < formatTypes.length; i++) {\n\t\t\t\tif(format.type === formatTypes[i]) {\n\t\t\t\t\tvalidFormatType = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!validFormatType) {\n\t\t\t\terrorMessage = \"Invalid required type format value - expected one of \" + formatTypes.join(\", \") + \", received \\\"\" + utilities.toString(originalType) + \"\\\".\";\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(format.type === \"bool\") {\n\t\t\t\t\tformat.type = \"boolean\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"int\") {\n\t\t\t\t\tformat.type = \"integer\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"number\") {\n\t\t\t\t\tformat.type = \"float\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"string\") {\n\t\t\t\t\tif(format.trim !== undefined) {\n\t\t\t\t\t\tvar originalTrim = format.trim;\n\n\t\t\t\t\t\tformat.trim = utilities.parseBoolean(format.trim);\n\n\t\t\t\t\t\tif(format.trim === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional trim string format value - expected boolean, received \\\"\" + utilities.toString(originalTrim) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.case !== undefined) {\n\t\t\t\t\t\t\tif(utilities.isEmptyString(format.case)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional string case format value - expected non-empty string.\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar originalCase = format.case;\n\n\t\t\t\t\t\t\t\tformat.case = changeCase.camelCase(format.case.trim());\n\n\t\t\t\t\t\t\t\tif(!utilities.isFunction(stringCaseFunctions[format.case])) {\n\t\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional case format value - expected one of \" + Object.keys(stringCaseFunctions).join(\", \") + \", received \\\"\" + utilities.toString(originalCase) + \"\\\".\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"object\") {\n\t\t\t\t\tif(format.strict !== undefined) {\n\t\t\t\t\t\tvar originalStrict = format.strict;\n\n\t\t\t\t\t\tformat.strict = utilities.parseBoolean(format.strict);\n\n\t\t\t\t\t\tif(format.strict === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional strict object format value - expected boolean, received \\\"\" + utilities.toString(originalStrict) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.autopopulate !== undefined) {\n\t\t\t\t\t\t\tvar originalAutopopulate = format.autopopulate;\n\n\t\t\t\t\t\t\tformat.autopopulate = utilities.parseBoolean(format.autopopulate);\n\n\t\t\t\t\t\t\tif(format.autopopulate === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional autopopulate object format value - expected boolean, received \\\"\" + utilities.toString(originalAutopopulate) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.order !== undefined) {\n\t\t\t\t\t\t\tvar originalOrder = format.order;\n\n\t\t\t\t\t\t\tformat.order = utilities.parseBoolean(format.order);\n\n\t\t\t\t\t\t\tif(format.order === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional order object format value - expected boolean, received \\\"\" + utilities.toString(originalOrder) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.removeExtra !== undefined) {\n\t\t\t\t\t\t\tvar originalRemoveExtra = format.removeExtra;\n\n\t\t\t\t\t\t\tformat.removeExtra = utilities.parseBoolean(format.removeExtra);\n\n\t\t\t\t\t\t\tif(format.removeExtra === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional removeExtra object format value - expected boolean, received \\\"\" + utilities.toString(originalRemoveExtra) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"regexp\" || format.type === \"regularexpression\") {\n\t\t\t\t\tformat.type = \"regex\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"func\") {\n\t\t\t\t\tformat.type = \"function\";\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.format !== undefined && !utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional format format value - expected object, received \\\"\" + utilities.toString(format.format) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"string\" || format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.nonEmpty !== undefined) {\n\t\t\t\t\t\t\tvar originalNonEmpty = format.nonEmpty;\n\n\t\t\t\t\t\t\tformat.nonEmpty = utilities.parseBoolean(format.nonEmpty);\n\n\t\t\t\t\t\t\tif(format.nonEmpty === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional nonEmpty format value - expected boolean, received \\\"\" + utilities.toString(originalNonEmpty) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.nullable !== undefined) {\n\t\t\t\tvar originalNullable = format.nullable;\n\n\t\t\t\tformat.nullable = utilities.parseBoolean(format.nullable);\n\n\t\t\t\tif(format.nullable === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional nullable format value - expected boolean, received \\\"\" + utilities.toString(originalNullable) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.required !== undefined) {\n\t\t\t\tvar originalRequired = format.required;\n\n\t\t\t\tformat.required = utilities.parseBoolean(format.required);\n\n\t\t\t\tif(format.required === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional required format value - expected boolean, received \\\"\" + utilities.toString(originalRequired) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.parser !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.parser)) {\n\t\t\t\t\terrorMessage = \"Invalid optional parser format value - expected function, received \\\"\" + utilities.toString(format.parser) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.validator !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.validator)) {\n\t\t\t\t\terrorMessage = \"Invalid optional validator format value - expected function, received \\\"\" + utilities.toString(format.validator) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.formatter !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.formatter)) {\n\t\t\t\t\terrorMessage = \"Invalid optional formatter format value - expected function, received \\\"\" + utilities.toString(format.formatter) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isFunction(format.parser)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar formattedValue = undefined;\n\n\t\tif(value === undefined) {\n\t\t\tformattedValue = utilities.clone(format.default);\n\t\t}\n\t\telse if(value === null) {\n\t\t\tif(format.nullable) {\n\t\t\t\tformattedValue = null;\n\t\t\t}\n\t\t\telse if(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Value cannot be null!\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"boolean\") {\n\t\t\tformattedValue = utilities.parseBoolean(value);\n\n\t\t\tif(formattedValue === null) {\n\t\t\t\terrorMessage = \"Invalid boolean value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"integer\") {\n\t\t\tformattedValue = utilities.parseInteger(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid integer value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"float\") {\n\t\t\tformattedValue = utilities.parseFloatingPointNumber(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid float value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"string\") {\n\t\t\tformattedValue = typeof value === \"string\" ? value : utilities.toString(value);\n\n\t\t\tif(format.trim) {\n\t\t\t\tformattedValue = formattedValue.trim();\n\t\t\t}\n\n\t\t\tif(format.case !== undefined) {\n\t\t\t\tformattedValue = stringCaseFunctions[format.case](formattedValue);\n\t\t\t}\n\n\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\tvar message = \"String value cannot be empty.\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"array\") {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\tif(!Array.isArray(formattedValue)) {\n\t\t\t\t\t\terrorMessage = \"Invalid stringified array value type - expected array: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\terrorMessage = \"Invalid stringified array value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(Array.isArray(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Invalid value type - expected array or stringified array: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\tif(Array.isArray(formattedValue)) {\n\t\t\t\t\tvar formattedArray = [];\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\tvar formattedElement = null;\n\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, subOptions);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(formattedElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(utilities.clone(formattedValue[i]));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tformattedValue = formattedArray;\n\n\t\t\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\t\t\tvar message = \"Array value cannot be empty.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"date\") {\n\t\t\tformattedValue = utilities.parseDate(value);\n\n\t\t\tif(!utilities.isDate(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid date value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"regex\") {\n\t\t\tif(utilities.isRegularExpression(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\terrorMessage = error.message;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid regular expression value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"function\") {\n\t\t\tformattedValue = value;\n\n\t\t\tif(!utilities.isFunction(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid function value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.type === \"object\") {\n\t\t\t\tif(utilities.isValid(value)) {\n\t\t\t\t\tif(typeof value === \"string\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\t\t\tif(!utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(utilities.isObject(value, format.strict)) {\n\t\t\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\terrorMessage = \"Invalid value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object or stringified object: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\t\t\tif(format.autopopulate && !utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\tformattedValue = { };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format) && utilities.isObject(formattedValue)) {\n\t\t\t\t\t\tvar attribute = null;\n\t\t\t\t\t\tvar attributes = Object.keys(format.format);\n\n\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], options);\n\n\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], subOptions);\n\n\t\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.removeExtra) {\n\t\t\t\t\t\t\tvar newValue = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(utilities.isValid(format.format[attribute])) {\n\t\t\t\t\t\t\t\t\tnewValue[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = newValue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.order) {\n\t\t\t\t\t\t\tvar orderedObject = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(format.format);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(formattedValue[attribute] !== undefined) {\n\t\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\n\t\t\t\t\t\t\t\t\tdelete formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar extraAttributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < extraAttributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = extraAttributes[i];\n\n\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = orderedObject;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(format.nonEmpty && utilities.isEmptyObject(formattedValue)) {\n\t\t\t\t\t\tvar message = \"Object value must contain at least one attribute.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(formattedValue === undefined) {\n\t\t\tif(format.required) {\n\t\t\t\tvar message = \"Missing required value!\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.validator)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\tthrow new Error(\"Validation check failed!\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\t\tvar message = \"Validation check failed!\";\n\n\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.formatter)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.formatObject = function formatObject(object, format, removeExtra, throwErrors) {\n\t\tif(!utilities.isObjectStrict(object) && (!utilities.isObjectStrict(removeExtra) || !utilities.isFunction(removeExtra.parser))) {\n\t\t\treturn { };\n\t\t}\n\n\t\tvar options = null;\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(removeExtra.throwErrors, utilities.parseBoolean(throwErrors, false)),\n\t\t\t\tverbose: utilities.parseBoolean(removeExtra.verbose, false)\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(throwErrors, false),\n\t\t\t\tverbose: false\n\t\t\t};\n\t\t}\n\n\t\tvar subFormat = {\n\t\t\ttype: \"object\",\n\t\t\tstrict: false,\n\t\t\tautopopulate: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.autopopulate, false) : false,\n\t\t\torder: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.order, false) : false,\n\t\t\tremoveExtra: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.removeExtra, utilities.parseBoolean(removeExtra, false)) : utilities.parseBoolean(removeExtra, false),\n\t\t\tnullable: true,\n\t\t\trequired: false,\n\t\t\tformat: format\n\t\t};\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\tif(utilities.isFunction(removeExtra.parser)) {\n\t\t\t\tsubFormat.parser = removeExtra.parser;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.validator)) {\n\t\t\t\tsubFormat.validator = removeExtra.validator;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.formatter)) {\n\t\t\t\tsubFormat.formatter = removeExtra.formatter;\n\t\t\t}\n\t\t}\n\n\t\tvar formattedObject = null;\n\n\t\tif(options.throwErrors) {\n\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\tobject,\n\t\t\t\tsubFormat,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\tsubOptions.throwErrors = true;\n\n\t\t\ttry {\n\t\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\t\tobject,\n\t\t\t\t\tsubFormat,\n\t\t\t\t\tsubOptions\n\t\t\t\t);\n\t\t\t}\n\t\t\tcatch(error) {\n\t\t\t\tif(options.verbose) {\n\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn utilities.isObjectStrict(formattedObject) || (utilities.isObjectStrict(removeExtra) && utilities.isFunction(removeExtra.parser)) ? formattedObject : { };\n\t};\n\n\tutilities.formatStringList = function formatStringList(value, stringify) {\n\t\tvar data = null;\n\n\t\tif(utilities.isNonEmptyString(value)) {\n\t\t\tdata = utilities.parseStringList(value);\n\t\t}\n\t\telse if(utilities.isNonEmptyArray(value)) {\n\t\t\tdata = value;\n\t\t}\n\t\telse if(typeof value === \"string\" || Array.isArray(value)) {\n\t\t\treturn \"\";\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedList = \"\";\n\t\tvar formattedValue = null;\n\n\t\tstringify = utilities.parseBoolean(stringify);\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tif(typeof data[i] !== \"string\") {\n\t\t\t\tif(stringify === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if(stringify) {\n\t\t\t\t\tformattedValue = utilities.toString(data[i]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tformattedValue = data[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tformattedValue = data[i].trim();\n\t\t\t}\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(formattedList.length > 0) {\n\t\t\t\tformattedList += \", \";\n\t\t\t}\n\n\t\t\tformattedList += formattedValue;\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.leftShift = function leftShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number * Math.pow(2, bits);\n\t};\n\n\tutilities.rightShift = function rightShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number / Math.pow(2, bits);\n\t};\n\n\tutilities.trimString = function trimString(value, defaultValue) {\n\t\treturn typeof value === \"string\" ? value.trim() : (defaultValue === undefined ? null : defaultValue);\n\t};\n\n\tutilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue === undefined ? null : defaultValue;\n\t\t}\n\n\t\tvar nullTerminatorIndex = value.indexOf(\"\\0\");\n\n\t\tif(nullTerminatorIndex >= 0) {\n\t\t\treturn value.substr(0, nullTerminatorIndex);\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.trimWhitespace = function trimWhitespace(value, trimNewlines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar trimmedString = value.replace(/^[ \\t]+|[ \\t]+$/gm, \"\");\n\n\t\tif(utilities.parseBoolean(trimNewlines, false)) {\n\t\t\ttrimmedString = trimmedString.replace(/\\r\\n?|\\n/g, \"\");\n\t\t}\n\n\t\treturn trimmedString;\n\t};\n\n\tutilities.trimTrailingNewlines = function trimTrailingNewlines(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn value.replace(/[ \\t\\r\\n]+$/, \"\");\n\t};\n\n\tutilities.replaceNonBreakingSpaces = function replaceNonBreakingSpaces(value) {\n\t\treturn typeof value === \"string\" ? value.replace(/ /gi, \" \") : null;\n\t};\n\n\tutilities.indentText = function indentText(value, amount, indentation, clearEmptyLines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tclearEmptyLines = utilities.parseBoolean(clearEmptyLines, true);\n\n\t\tamount = utilities.parseInteger(amount, 1);\n\n\t\tif(amount < 0) {\n\t\t\tamount = 0;\n\t\t}\n\n\t\tindentation = typeof indentation === \"string\" ? indentation : \"\\t\";\n\n\t\tvar totalIndentation = \"\";\n\n\t\tfor(var i = 0; i < amount; i++) {\n\t\t\ttotalIndentation += indentation;\n\t\t}\n\n\t\tvar line = null;\n\t\tvar lines = value.split(/\\r\\n?|\\n/g);\n\t\tvar indentedParagraph = \"\";\n\n\t\tfor(var i = 0; i < lines.length; i++) {\n\t\t\tline = lines[i];\n\n\t\t\tindentedParagraph += (utilities.isEmptyString(line) && clearEmptyLines ? \"\" : totalIndentation + line) + ((i < lines.length - 1) ? \"\\n\" : \"\");\n\t\t}\n\n\t\treturn indentedParagraph;\n\t};\n\n\tutilities.trimLeadingZeroes = function trimLeadingZeroes(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\t\telse if(formattedValue.match(/^[0]+$/)) {\n\t\t\treturn \"0\";\n\t\t}\n\n\t\treturn formattedValue.replace(/^0+/, \"\");\n\t};\n\n\tutilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) {\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.toString();\n\t\texpectedLength = utilities.parseInteger(expectedLength);\n\n\t\tif(utilities.isInvalidNumber(expectedLength) || expectedLength < 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar numberOfZeroes = expectedLength - value.length;\n\n\t\tfor(var i = 0; i < numberOfZeroes; i++) {\n\t\t\tvalue = \"0\" + value;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.toString = function toString(value) {\n\t\tif(value === undefined) {\n\t\t\treturn \"undefined\";\n\t\t}\n\t\telse if(value === null) {\n\t\t\treturn \"null\";\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value === Infinity) {\n\t\t\treturn \"Infinity\";\n\t\t}\n\t\telse if(value === -Infinity) {\n\t\t\treturn \"-Infinity\";\n\t\t}\n\t\telse if(typeof value === \"number\" && isNaN(value)) {\n\t\t\treturn \"NaN\";\n\t\t}\n\t\telse if(utilities.isDate(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(utilities.isRegularExpression(value)) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn \"/\" + value.source + \"/\" + flags;\n\t\t}\n\t\telse if(utilities.isFunction(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(utilities.isError(value)) {\n\t\t\tvar error = { message: value.message };\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\terror[attribute] = value[attribute];\n\t\t\t}\n\n\t\t\treturn JSON.stringify(error);\n\t\t}\n\n\t\treturn JSON.stringify(value);\n\t};\n\n\tutilities.compareDates = function compareDates(a, b) {\n\t\ta = utilities.parseDate(a);\n\t\tb = utilities.parseDate(b);\n\n\t\tif(a === null && b === null) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tif(a === null) {\n\t\t\treturn -1;\n\t\t}\n\t\telse if(b === null) {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn a.getTime() - b.getTime();\n\t};\n\n\tutilities.compareCasePercentage = function compareCasePercentage(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar c = null;\n\t\tvar upper = 0;\n\t\tvar lower = 0;\n\t\tvar lowerA = \"a\".charCodeAt();\n\t\tvar lowerZ = \"z\".charCodeAt();\n\t\tvar upperA = \"A\".charCodeAt();\n\t\tvar upperZ = \"Z\".charCodeAt();\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tc = value.charCodeAt(i);\n\n\t\t\tif(c >= lowerA && c <= lowerZ) {\n\t\t\t\tlower++;\n\t\t\t}\n\t\t\telse if(c >= upperA && c <= upperZ) {\n\t\t\t\tupper++;\n\t\t\t}\n\t\t}\n\n\t\treturn upper - lower;\n\t};\n\n\tutilities.reverseString = function reverseString(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.replace(\n\t\t\t/([\\0-\\u02FF\\u0370-\\u1AAF\\u1B00-\\u1DBF\\u1E00-\\u20CF\\u2100-\\uD7FF\\uE000-\\uFE1F\\uFE30-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])([\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F]+)/g,\n\t\t\tfunction($0, $1, $2) {\n\t\t\t\treturn utilities.reverseString($2) + $1;\n\t\t\t}\n\t\t).replace(/([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])/g, \"$2$1\");\n\n\t\tvar reverse = \"\";\n\n\t\tfor(var i = value.length - 1; i >= 0; i--) {\n\t\t\treverse += value[i];\n\t\t}\n\n\t\treturn reverse;\n\t};\n\n\tutilities.createError = function createError(message, status) {\n\t\tvar error = new Error(message);\n\t\terror.status = utilities.parseInteger(status, 500);\n\t\treturn error;\n\t};\n\n\tutilities.clone = function clone(value) {\n\t\tif(!utilities.isObject(value)) {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value instanceof Boolean) {\n\t\t\treturn new Boolean(value.valueOf());\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\tvar copy = new Date();\n\t\t\tcopy.setTime(value.getTime());\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Array) {\n\t\t\tvar copy = [];\n\n\t\t\tfor(var i = 0, length = value.length; i < length; i++) {\n\t\t\t\tcopy[i] = utilities.clone(value[i]);\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Set) {\n\t\t\treturn new Set(value);\n\t\t}\n\t\telse if(value instanceof Map) {\n\t\t\treturn new Map(value);\n\t\t}\n\t\telse if(value instanceof RegExp) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new RegExp(value.source, flags);\n\t\t}\n\t\telse if(typeof Buffer !== \"undefined\" && value instanceof Buffer) {\n\t\t\treturn Buffer.from instanceof Function ? Buffer.from(value) : new Buffer(value);\n\t\t}\n\t\telse if(value instanceof Object) {\n\t\t\tvar copy = null;\n\n\t\t\tif(value instanceof Error) {\n\t\t\t\tcopy = new Error(value.message);\n\n\t\t\t\tcopy.stack = utilities.clone(value.stack);\n\n\t\t\t\tvar properties = Object.keys(value);\n\n\t\t\t\tfor(var i = 0; i < properties.length; i++) {\n\t\t\t\t\tcopy[properties[i]] = utilities.clone(value[properties[i]]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcopy = { };\n\t\t\t}\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\tif(Object.prototype.hasOwnProperty.call(value, attribute)) {\n\t\t\t\t\tcopy[attribute] = utilities.clone(value[attribute]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.merge = function merge(a, b, copy, deepMerge) {\n\t\tif(!utilities.isObject(a) || Array.isArray(a)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar newObject = null;\n\n\t\tcopy = utilities.parseBoolean(copy, true);\n\n\t\tif(copy) {\n\t\t\tnewObject = utilities.clone(a);\n\t\t}\n\t\telse {\n\t\t\tnewObject = a;\n\t\t}\n\n\t\tif(!utilities.isObject(a) || Array.isArray(a) || !utilities.isObject(b) || Array.isArray(b)) {\n\t\t\treturn newObject;\n\t\t}\n\n\t\tvar attribute = null;\n\t\tvar value = null;\n\t\tvar newValue = null;\n\t\tvar attributes = Object.keys(b);\n\n\t\tdeepMerge = utilities.parseBoolean(deepMerge, true);\n\n\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\tattribute = attributes[i];\n\t\t\tvalue = newObject[attribute];\n\n\t\t\tif(copy) {\n\t\t\t\tnewValue = utilities.clone(b[attribute]);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewValue = b[attribute];\n\t\t\t}\n\n\t\t\tif(deepMerge && utilities.isObject(value) && !Array.isArray(value) && utilities.isObject(newValue) && !Array.isArray(newValue)) {\n\t\t\t\tnewObject[attribute] = utilities.merge(value, newValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewObject[attribute] = newValue;\n\t\t\t}\n\t\t}\n\n\t\treturn newObject;\n\t};\n\n\tutilities.getFileName = function getFileName(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(i + 1, filePath.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn filePath;\n\t};\n\n\tutilities.getFilePath = function getFilePath(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.getFileExtension = function getFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(i + 1, fileName.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.fileHasExtension = function fileHasExtension(fileName, extension) {\n\t\tif(utilities.isEmptyString(fileName) || utilities.isEmptyString(extension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar actualFileExtension = utilities.getFileExtension(fileName);\n\n\t\tif(utilities.isEmptyString(actualFileExtension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn actualFileExtension.toLowerCase() === extension.trim().toLowerCase();\n\t};\n\n\tutilities.reverseFileExtension = function reverseFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = fileName.trim();\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i) + \".\" + utilities.reverseString(fileName.substring(i + 1, fileName.length));\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.truncateFileName = function truncateFileName(fileName, maxLength) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tif(utilities.isEmptyString(fileName)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tmaxLength = utilities.parseInteger(maxLength);\n\n\t\tif(utilities.isInvalidNumber(maxLength) || maxLength < 0) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tif(maxLength === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif(fileName.length <= maxLength) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tvar extension = \"\";\n\t\tvar originalFileName = fileName;\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\textension = fileName.substring(i + 1, fileName.length);\n\t\t\t\toriginalFileName = fileName.substring(0, i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(maxLength - (extension.length + (extension.length > 0 ? 1 : 0)) < 1) {\n\t\t\treturn originalFileName.substring(0, maxLength);\n\t\t}\n\n\t\treturn originalFileName.substring(0, maxLength - extension.length - (extension.length > 0 ? 1 : 0)) + (extension.length > 0 ? \".\" + extension : \"\");\n\t};\n\n\tutilities.prependSlash = function prependSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[0] !== \"/\" && formattedValue[0] !== \"\\\\\") {\n\t\t\tformattedValue = \"/\" + formattedValue;\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.appendSlash = function appendSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[formattedValue.length - 1] !== \"/\" && formattedValue[formattedValue.length - 1] !== \"\\\\\") {\n\t\t\tformattedValue += \"/\";\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.joinPaths = function joinPaths(base, path) {\n\t\tvar formattedBase = typeof base === \"string\" ? base.trim().replace(/[\\/\\\\]+$/, \"\") : null;\n\t\tvar formattedPath = typeof path === \"string\" ? path.trim().replace(/^[\\/\\\\]+/, \"\") : null;\n\t\tvar newPath = \"\";\n\n\t\tif(utilities.isNonEmptyString(formattedBase)) {\n\t\t\tnewPath += formattedBase;\n\n\t\t\tif(utilities.isNonEmptyString(formattedPath)) {\n\t\t\t\tnewPath += \"/\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isNonEmptyString(formattedPath)) {\n\t\t\tnewPath += formattedPath;\n\t\t}\n\n\t\treturn newPath;\n\t};\n\n\tutilities.createQueryString = function createQueryString(value, includeQuestionMark) {\n\t\tif(!utilities.isObjectStrict(value)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar parameters = Object.keys(value).map(function(key) {\n\t\t\treturn encodeURIComponent(key) + \"=\" + encodeURIComponent(utilities.toString(value[key]));\n\t\t}).join(\"&\");\n\n\t\tif(parameters.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\treturn (utilities.parseBoolean(includeQuestionMark, false) ? \"?\" : \"\") + parameters;\n\t};\n\n\tutilities.createRange = function createRange(start, end) {\n\t\tvar formattedStart = utilities.parseInteger(start);\n\t\tvar formattedEnd = utilities.parseInteger(end);\n\n\t\tif(arguments.length === 1) {\n\t\t\tformattedEnd = formattedStart;\n\t\t\tformattedStart = 0;\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(formattedStart) || utilities.isInvalidNumber(formattedEnd) || formattedStart > formattedEnd) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar range = [];\n\n\t\tfor(var i = formattedStart; i <= formattedEnd; i++) {\n\t\t\trange.push(i);\n\t\t}\n\n\t\treturn range;\n\t};\n\n\tutilities.futureMonths = function futureMonths(date, prependZero) {\n\t\tdate = utilities.parseDate(date);\n\n\t\tif(date === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar currentDate = new Date();\n\t\tvar month = 0;\n\n\t\tif(date.getFullYear() === currentDate.getFullYear()) {\n\t\t\tmonth = currentDate.getMonth();\n\t\t}\n\n\t\tvar months = [];\n\n\t\tprependZero = utilities.parseBoolean(prependZero, false);\n\n\t\tfor(var i = 0; i < 12; i++) {\n\t\t\tif(i >= month) {\n\t\t\t\tif(prependZero) {\n\t\t\t\t\tmonths.push((i <= 8 ? \"0\" : \"\") + (i + 1));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmonths.push(i + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn months;\n\t};\n\n\tutilities.visibleElements = function visibleElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar visibleElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isVisible(elements[i])) {\n\t\t\t\tvisibleElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn visibleElements;\n\t};\n\n\tutilities.hiddenElements = function hiddenElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar hiddenElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isHidden(elements[i])) {\n\t\t\t\thiddenElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn hiddenElements;\n\t};\n\n\tutilities.enabledElements = function enabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar enabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isEnabled(elements[i])) {\n\t\t\t\tenabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn enabledElements;\n\t};\n\n\tutilities.disabledElements = function disabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar disabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isDisabled(elements[i])) {\n\t\t\t\tdisabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn disabledElements;\n\t};\n\n\tutilities.elementsWithAttribute = function elementsWithAttribute(elements, attribute, hasAttribute) {\n\t\tif(!Array.isArray(elements) || utilities.isEmptyString(attribute)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar element = null;\n\t\tvar filteredElements = [];\n\n\t\tattribute = attribute.trim();\n\t\thasAttribute = utilities.parseBoolean(hasAttribute, true);\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\telement = elements[i];\n\n\t\t\tif(!utilities.isObject(element)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(elements[i][attribute])) {\n\t\t\t\tif(!hasAttribute) {\n\t\t\t\t\tfilteredElements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(hasAttribute) {\n\t\t\t\t\tfilteredElements.push(elements[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn filteredElements;\n\t};\n\n\tutilities.elementsWithoutAttribute = function elementsWithoutAttribute(elements, attribute) {\n\t\treturn utilities.elementsWithAttribute(elements, attribute, false);\n\t};\n\n\tutilities.matchAttribute = function matchAttribute(element, attribute, value) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(attribute)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn element[attribute.trim()] === value;\n\t};\n\n\tutilities.generateVersions = function generateVersions(version, prefix, suffix) {\n\t\tversion = utilities.parseVersion(version);\n\n\t\tif(version === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tprefix = utilities.trimString(prefix);\n\t\tsuffix = utilities.trimString(suffix);\n\n\t\tvar versions = [];\n\t\tvar value = null;\n\n\t\tfor(var i = 0; i < version.length; i++) {\n\t\t\tvalue = \"\";\n\n\t\t\tif(utilities.isNonEmptyString(prefix)) {\n\t\t\t\tvalue += prefix;\n\t\t\t}\n\n\t\t\tfor(var j = 0; j <= i; j++) {\n\t\t\t\tif(j > 0) {\n\t\t\t\t\tvalue += \"_\";\n\t\t\t\t}\n\n\t\t\t\tvalue += version[j];\n\t\t\t}\n\n\t\t\tif(utilities.isNonEmptyString(suffix)) {\n\t\t\t\tvalue += suffix;\n\t\t\t}\n\n\t\t\tversions.push(value);\n\t\t}\n\n\t\treturn versions;\n\t};\n\n\tutilities.parseVersion = function parseVersion(value, trimTrailingZeroes) {\n\t\tvar formattedValue = utilities.isValidNumber(value) ? value.toString() : value;\n\n\t\tif(typeof formattedValue !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar version = [];\n\t\tvar versionData = formattedValue.match(/[^. \\t]+/g);\n\n\t\tif(versionData === null || versionData.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar part = null;\n\n\t\tfor(var i = 0; i < versionData.length; i++) {\n\t\t\tif(validator.isInt(versionData[i])) {\n\t\t\t\tpart = utilities.parseInteger(versionData[i]);\n\n\t\t\t\tif(utilities.isInvalidNumber(part) || part < 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tversion.push(part.toString());\n\t\t\t}\n\t\t\telse {\n\t\t\t\tversion.push(versionData[i]);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.parseBoolean(trimTrailingZeroes, false)) {\n\t\t\twhile(true) {\n\t\t\t\tif(version.length <= 1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif(version[version.length - 1] === \"0\") {\n\t\t\t\t\tversion.pop();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn version.length === 0 ? null : version;\n\t};\n\n\tutilities.compareVersions = function compareVersions(v1, v2, caseSensitive, throwErrors) {\n\t\tcaseSensitive = utilities.parseBoolean(caseSensitive, false);\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tv1 = utilities.parseVersion(v1);\n\n\t\tif(v1 === null) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Cannot compare invalid or empty first version.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tv2 = utilities.parseVersion(v2);\n\n\t\tif(v2 === null) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Cannot compare invalid or empty second version.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar index = 0;\n\n\t\twhile(true) {\n\t\t\tif(index >= v1.length) {\n\t\t\t\tif(v1.length === v2.length) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tfor(var i = index; i < v2.length; i++) {\n\t\t\t\t\tif(v2[i] !== \"0\") {\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tif(index >= v2.length) {\n\t\t\t\tfor(var i = index; i < v1.length; i++) {\n\t\t\t\t\tif(v1[i] !== \"0\") {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tvar formattedA = utilities.parseInteger(v1[index]);\n\t\t\tvar formattedB = utilities.parseInteger(v2[index]);\n\n\t\t\tif(utilities.isInvalidNumber(formattedA)) {\n\t\t\t\tformattedA = caseSensitive ? v1[index] : v1[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(formattedB)) {\n\t\t\t\tformattedB = caseSensitive ? v2[index] : v2[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(Number.isInteger(formattedA)) {\n\t\t\t\tif(!Number.isInteger(formattedB)) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(Number.isInteger(formattedB)) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(formattedA > formattedB) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse if(formattedA < formattedB) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tindex++;\n\t\t}\n\t};\n\n\treturn utilities;\n\n}));\n\n//# sourceMappingURL=extra-utilities.js.map\n"]} \ No newline at end of file +{"version":3,"sources":["extra-utilities.min.js"],"names":["global","factory","exports","module","define","amd","utilities","this","require","validator","changeCase","regExpFlags","multiline","ignoreCase","sticky","unicode","formatTypes","stringCaseFunctions","camel","camelCase","capital","capitalCase","constant","constantCase","dot","dotCase","header","headerCase","lower","lowerCase","lowerFirst","lowerCaseFirst","no","noCase","param","paramCase","pascal","pascalCase","path","pathCase","sentence","sentenceCase","snake","snakeCase","sponge","spongeCase","swap","swapCase","title","titleCase","upper","upperCase","upperFirst","upperCaseFirst","isValid","value","isInvalid","isBoolean","allowObjects","Boolean","isValidNumber","isNaN","Infinity","isInvalidNumber","isEmptyString","trim","parseBoolean","length","isNonEmptyString","isObject","strict","undefined","constructor","Object","Function","isObjectStrict","isEmptyObject","keys","isNonEmptyObject","isEmptyArray","Array","isArray","isNonEmptyArray","isDate","Date","isError","Error","isRegularExpression","RegExp","isFunction","isComment","comment","commentStartIndex","i","isVisible","element","visible","hidden","isHidden","isEnabled","enabled","disabled","isDisabled","equalsIgnoreCase","stringA","stringB","localeCompare","sensitivity","defaultValue","valueOf","formattedValue","toLowerCase","character","charAt","parseInteger","newValue","NaN","isFloat","parseInt","parseFloatingPointNumber","parseFloat","parseDate","Number","isInteger","timestamp","isInt","parse","parseTime","throwErrors","hour","minutes","regularTime","match","regularHour","trimLeadingZeroes","morning","period","toUpperCase","militaryTime","militaryHour","militaryMinutes","regular","raw","addLeadingZeroes","military","parseEmail","emailData","parseEmailDomain","emailDomainData","parseStringList","data","split","formattedList","push","parseRegularExpression","regExpData","error","parseYouTubeLink","linkData","formatValue","format","options","verbose","clone","errorMessage","type","originalType","validFormatType","originalTrim","toString","case","originalCase","join","originalStrict","autopopulate","originalAutopopulate","order","originalOrder","removeExtra","originalRemoveExtra","nonEmpty","originalNonEmpty","nullable","originalNullable","required","originalRequired","parser","formatter","console","message","default","JSON","formattedArray","formattedElement","subOptions","attribute","attributes","formattedAttribute","orderedObject","extraAttributes","formatObject","object","subFormat","formattedObject","formatStringList","stringify","leftShift","number","bits","Math","pow","rightShift","trimString","trimNullTerminatedString","nullTerminatorIndex","indexOf","substr","trimWhitespace","trimNewlines","trimmedString","replace","trimTrailingNewlines","replaceNonBreakingSpaces","indentText","amount","indentation","clearEmptyLines","totalIndentation","line","lines","indentedParagraph","expectedLength","numberOfZeroes","flags","flag","source","compareDates","a","b","getTime","compareCasePercentage","c","lowerA","charCodeAt","lowerZ","upperA","upperZ","reverseString","reverse","$0","$1","$2","createError","status","copy","setTime","Set","Map","Buffer","from","stack","properties","prototype","hasOwnProperty","call","merge","deepMerge","newObject","getFileName","filePath","substring","getFilePath","getFileNameNoExtension","fileName","getFileExtension","fileHasExtension","extension","actualFileExtension","reverseFileExtension","truncateFileName","maxLength","originalFileName","prependSlash","appendSlash","joinPaths","base","formattedBase","formattedPath","newPath","createQueryString","includeQuestionMark","parameters","map","key","encodeURIComponent","createRange","start","end","formattedStart","formattedEnd","arguments","range","futureMonths","date","prependZero","currentDate","month","getFullYear","getMonth","months","visibleElements","elements","hiddenElements","enabledElements","disabledElements","elementsWithAttribute","hasAttribute","filteredElements","elementsWithoutAttribute","matchAttribute","generateVersions","version","prefix","suffix","parseVersion","versions","j","trimTrailingZeroes","versionData","part","pop","compareVersions","v1","v2","caseSensitive","index","formattedA","formattedB"],"mappings":"CAAC,SAASA,OAAQC,SACE,iBAAZC,SAA0C,oBAAXC,OAAyBA,OAAOD,QAAUD,UAC9D,mBAAXG,QAAyBA,OAAOC,IAAMD,OAAOH,SACnDD,OAAOM,UAAYL,UAHrB,CAIGM,KAAM,WAER,aAEsB,oBAAZC,UACe,oBAAdC,YACTT,OAAOS,UAAYD,QAAQ,cAGH,oBAAfE,aACTV,OAAOU,WAAaF,QAAQ,yBAO9B,IAAIF,UAAY,GAEZK,YAAc,CACjBX,OAAQ,IACRY,UAAW,IACXC,WAAY,IACZC,OAAQ,IACRC,QAAS,KAGNC,YAAc,CAAC,UAAW,OAAQ,UAAW,MAAO,QAAS,SAAU,SAAU,SAAU,QAAS,OAAQ,QAAS,SAAU,oBAAqB,WAAY,QAEhKC,oBAAsB,CACzBC,MAAOR,WAAWS,UAClBC,QAASV,WAAWW,YACpBC,SAAUZ,WAAWa,aACrBC,IAAKd,WAAWe,QAChBC,OAAQhB,WAAWiB,WACnBC,MAAOlB,WAAWmB,UAClBC,WAAYpB,WAAWqB,eACvBC,GAAItB,WAAWuB,OACfC,MAAOxB,WAAWyB,UAClBC,OAAQ1B,WAAW2B,WACnBC,KAAM5B,WAAW6B,SACjBC,SAAU9B,WAAW+B,aACrBC,MAAOhC,WAAWiC,UAClBC,OAAQlC,WAAWmC,WACnBC,KAAMpC,WAAWqC,SACjBC,MAAOtC,WAAWuC,UAClBC,MAAOxC,WAAWyC,UAClBC,WAAY1C,WAAW2C,gBA+wExB,OA/vEA/C,UAAUgD,QAAU,SAAiBC,OACpC,OAAOA,MAAAA,OAgBRjD,UAAUkD,UAAY,SAAmBD,OACxC,OAAOA,MAAAA,OAmBRjD,UAAUmD,UAAY,SAAmBF,MAAOG,cAC/C,OAAiB,IAAVH,QAA4B,IAAVA,SAAsBG,cAAgBH,iBAAiBI,SAGjFrD,UAAUsD,cAAgB,SAAuBL,OAChD,MAAwB,iBAAVA,QAAuBM,MAAMN,QAAUA,SAAWO,EAAAA,GAAYP,QAAUO,EAAAA,GAGvFxD,UAAUyD,gBAAkB,SAAyBR,OACpD,MAAwB,iBAAVA,OAAsBM,MAAMN,QAAUA,SAAWO,EAAAA,GAAYP,QAAUO,EAAAA,GAGtFxD,UAAU0D,cAAgB,SAAuBT,MAAOU,MACvD,MAAwB,iBAAVV,QAAuBjD,UAAU4D,aAAaD,MAAM,GAAgC,IAAxBV,MAAMU,OAAOE,OAAgC,IAAjBZ,MAAMY,SAG7G7D,UAAU8D,iBAAmB,SAA0Bb,MAAOU,MAC7D,MAAwB,iBAAVV,QAAuBjD,UAAU4D,aAAaD,MAAM,GAAgC,IAAxBV,MAAMU,OAAOE,OAAgC,IAAjBZ,MAAMY,SAG7G7D,UAAU+D,SAAW,SAAkBd,MAAOe,QAC7C,YAAiBC,IAAVhB,QAAwBe,OAAmB,OAAVf,OAAkBA,MAAMiB,cAAgBC,OAASlB,iBAAiBkB,UAAYlB,iBAAiBmB,YAGxIpE,UAAUqE,eAAiB,SAAwBpB,OAClD,OAAOA,MAAAA,OAAyCA,MAAMiB,cAAgBC,QAGvEnE,UAAUsE,cAAgB,SAAuBrB,OAChD,OAAOA,MAAAA,OAAyCA,MAAMiB,cAAgBC,QAAwC,IAA9BA,OAAOI,KAAKtB,OAAOY,QAGpG7D,UAAUwE,iBAAmB,SAA0BvB,OACtD,OAAOA,MAAAA,OAAyCA,MAAMiB,cAAgBC,QAAwC,IAA9BA,OAAOI,KAAKtB,OAAOY,QAGpG7D,UAAUyE,aAAe,SAAsBxB,OAC9C,OAAOyB,MAAMC,QAAQ1B,QAA0B,IAAjBA,MAAMY,QAGrC7D,UAAU4E,gBAAkB,SAAyB3B,OACpD,OAAOyB,MAAMC,QAAQ1B,QAA2B,IAAjBA,MAAMY,QAGtC7D,UAAU6E,OAAS,SAAgB5B,OAClC,OAAOA,iBAAiB6B,MAGzB9E,UAAU+E,QAAU,SAAiB9B,OACpC,OAAOA,iBAAiB+B,OAGzBhF,UAAUiF,oBAAsB,SAA6BhC,OAC5D,OAAOA,iBAAiBiC,QAGzBlF,UAAUmF,WAAa,SAAoBlC,OAC1C,OAAOA,iBAAiBmB,UAGzBpE,UAAUoF,UAAY,SAAmBnC,MAAOoC,SAC/C,GAAGrF,UAAU0D,cAAcT,OAC1B,OAAO,EAGLjD,UAAU0D,cAAc2B,WAC1BA,QAAU,MAKX,IAFA,IAAIC,mBAAqB,EAEjBC,EAAI,EAAGA,EAAItC,MAAMY,OAAQ0B,IAChC,GAAgB,MAAbtC,MAAMsC,IAA0B,MAAZtC,MAAMsC,GAA7B,CAIA,GAAGtC,MAAMsC,IAAMF,QAAQ,GAKtB,OAAO,EAJPC,kBAAoBC,EACpB,MAOF,GAAGD,kBAAoB,GAAKrC,MAAMY,OAASyB,kBAAoBD,QAAQxB,OACtE,OAAO,EAGR,IAAQ0B,EAAID,kBAAmBC,EAAItC,MAAMY,UACrC0B,EAAID,mBAAqBD,QAAQxB,QADY0B,IAKhD,GAAGtC,MAAMsC,IAAMF,QAAQE,EAAID,mBAC1B,OAAO,EAIT,OAAO,GAGRtF,UAAUwF,UAAY,SAAmBC,SACxC,QAAIzF,UAAU+D,SAAS0B,WAIpBzF,UAAUmD,UAAUsC,QAAQC,SACvBD,QAAQC,QAER1F,UAAUmF,WAAWM,QAAQC,SAC7BD,QAAQC,UAER1F,UAAUmD,UAAUsC,QAAQE,SAC3BF,QAAQE,QAET3F,UAAUmF,WAAWM,QAAQE,UAC5BF,QAAQE,WAMlB3F,UAAU4F,SAAW,SAAkBH,SACtC,OAAIzF,UAAU+D,SAAS0B,WAIpBzF,UAAUmD,UAAUsC,QAAQC,UACtBD,QAAQC,QAET1F,UAAUmF,WAAWM,QAAQC,UAC5BD,QAAQC,UAET1F,UAAUmD,UAAUsC,QAAQE,QAC5BF,QAAQE,SAER3F,UAAUmF,WAAWM,QAAQE,SAC7BF,QAAQE,WAMjB3F,UAAU6F,UAAY,SAAmBJ,SACxC,QAAIzF,UAAU+D,SAAS0B,WAIpBzF,UAAUmD,UAAUsC,QAAQK,SACvBL,QAAQK,QAER9F,UAAUmF,WAAWM,QAAQK,SAC7BL,QAAQK,UAER9F,UAAUmD,UAAUsC,QAAQM,WAC3BN,QAAQM,UAET/F,UAAUmF,WAAWM,QAAQM,YAC5BN,QAAQM,aAMlB/F,UAAUgG,WAAa,SAAoBP,SAC1C,OAAIzF,UAAU+D,SAAS0B,WAIpBzF,UAAUmD,UAAUsC,QAAQK,UACtBL,QAAQK,QAET9F,UAAUmF,WAAWM,QAAQK,UAC5BL,QAAQK,UAET9F,UAAUmD,UAAUsC,QAAQM,UAC5BN,QAAQM,WAER/F,UAAUmF,WAAWM,QAAQM,WAC7BN,QAAQM,aAMjB/F,UAAUiG,iBAAmB,SAA0BC,QAASC,SAC/D,MAAsB,iBAAZD,SAA2C,iBAAZC,SAIuC,IAAzED,QAAQE,cAAcD,aAASlC,EAAW,CAAEoC,YAAa,YAGjErG,UAAU4D,aAAe,SAAsBX,MAAOqD,cACrD,GAAGtG,UAAUmD,UAAUF,OACtB,OAAOA,MAGR,GAAGjD,UAAUmD,UAAUF,OAAO,GAC7B,OAAOA,MAAMsD,UAOd,GAJIvG,UAAUmD,UAAUmD,gBACvBA,aAAe,MAGbtG,UAAUkD,UAAUD,OACtB,OAAOqD,aAGR,GAAa,IAAVrD,MACF,OAAO,EAEH,GAAa,IAAVA,MACP,OAAO,EAGR,GAAoB,iBAAVA,MACT,OAAOqD,aAGR,IAAIE,eAAiBvD,MAAMU,OAAO8C,cAElC,GAA6B,IAA1BD,eAAe3C,OACjB,OAAOyC,aAGR,GAA6B,IAA1BE,eAAe3C,OAmBlB,MAAsB,SAAnB2C,gBAAgD,QAAnBA,gBAA+C,OAAnBA,gBAGjC,UAAnBA,gBAAiD,OAAnBA,gBAA8C,QAAnBA,gBAI1DF,aAzBN,IAAII,UAAYF,eAAeG,OAAO,GAEtC,MAAiB,MAAdD,WAAmC,MAAdA,WAGF,MAAdA,WAAmC,MAAdA,YAGP,MAAdA,YAGc,MAAdA,WAIDJ,gBAaTtG,UAAU4G,aAAe,SAAsB3D,MAAOqD,cACrD,IAAIO,SAAWC,IAWf,OAToB,iBAAV7D,OAGe,iBAAVA,OACX9C,UAAU4G,QAAQ9D,UAHrB4D,SAAWG,SAAS/D,QAQlBjD,UAAUyD,gBAAgBoD,WAC5BP,aAAeU,SAASV,cAEjBtG,UAAUsD,cAAcgD,cAAgBA,aAAeQ,KAGxDD,UAGR7G,UAAUiH,yBAA2B,SAAkChE,MAAOqD,cAC7E,IAAIO,SAAWC,IAWf,MAToB,iBAAV7D,MACT4D,SAAW5D,MAEa,iBAAVA,OACX9C,UAAU4G,QAAQ9D,SACpB4D,SAAWK,WAAWjE,QAIrBjD,UAAUyD,gBAAgBoD,UACrB7G,UAAUsD,cAAcgD,cAAgBA,aAAeQ,IAGxDD,UAGR7G,UAAUmH,UAAY,SAAmBlE,MAAOqD,cAK/C,GAJItG,UAAU6E,OAAOyB,gBACpBA,aAAe,MAGI,iBAAVrD,MACT,OAAGjD,UAAUyD,gBAAgBR,SAAWmE,OAAOC,UAAUpE,OACjDqD,aAGD,IAAIxB,KAAKkC,SAAS/D,QAErB,GAAoB,iBAAVA,MAsBV,OAAGA,iBAAiB6B,KACjB7B,MAGDqD,aAzBN,IAAIE,eAAiBvD,MAAMU,OAE3B,GAA6B,IAA1B6C,eAAe3C,OACjB,OAAOyC,aAGR,IAAIgB,UAAY,KAShB,OANCA,UADEnH,UAAUoH,MAAMf,gBACNQ,SAASR,gBAGT1B,KAAK0C,MAAMhB,gBAGrBxG,UAAUyD,gBAAgB6D,WACrBhB,aAGD,IAAIxB,KAAKwC,YASlBtH,UAAUyH,UAAY,SAAmBxE,MAAOyE,aAG/C,GAFAA,YAAc1H,UAAU4D,aAAa8D,aAElC1H,UAAU0D,cAAcT,OAAQ,CAClC,GAAGyE,YACF,MAAM,IAAI1C,MAAM,gCAGjB,OAAO,KAGR,IAAIwB,eAAiBvD,MAAMU,OACvBgE,KAAO,KACPC,QAAU,KACVC,YAAcrB,eAAesB,MAAM,mEAEvC,GAAGD,YAAa,CACf,IAAIE,YAAc/H,UAAU4G,aAAa5G,UAAUgI,kBAAkBH,YAAY,KAEjF,GAAG7H,UAAUyD,gBAAgBsE,aAAc,CAC1C,GAAGL,YACF,MAAM,IAAI1C,MAAM,0BAA6B6C,YAAY,GAAK,MAG/D,OAAO,KAGRD,QAAU5H,UAAU4G,aAAa5G,UAAUgI,kBAAkBH,YAAY,KAEtE7H,UAAUyD,gBAAgBmE,WAC5BA,QAAU,GAGX,IACIK,QAAqB,QADrBC,OAASL,YAAY,GAAGM,gBACuB,OAAXD,QAA0B,KAElE,GAAe,OAAZD,QAAkB,CACpB,GAAGP,YACF,MAAM,IAAI1C,MAAM,oBAAuB6C,YAAY,GAAK,MAGzD,OAAO,KAKI,MAFZF,KAAOM,QAAUF,aAA+B,KAAhBA,YAAqB,GAAK,GAAKA,aAA+B,KAAhBA,YAAqB,EAAI,OAGtGJ,KAAO,OAGJ,CACJ,IAAIS,aAAe5B,eAAesB,MAAM,yEAExC,IAAGM,aA4CE,CACJ,GAAGV,YACF,MAAM,IAAI1C,MAAM,kBAAqBwB,eAAiB,MAGvD,OAAO,KAhDP,IAAI6B,aAAeD,aAAa,GAC5BE,gBAAkBF,aAAa,GAUnC,IARGpI,UAAUkD,UAAUmF,eAAiBrI,UAAUkD,UAAUoF,oBAC3DD,aAAeD,aAAa,GAEzBpI,UAAU8D,iBAAiBsE,aAAa,MAC1CE,gBAAkBF,aAAa,KAI9BpI,UAAUkD,UAAUmF,eAAiBrI,UAAUkD,UAAUoF,iBAAkB,CAC7E,GAAGZ,YACF,MAAM,IAAI1C,MAAM,2BAA8BwB,eAAiB,MAGhE,OAAO,KAKR,GAFAmB,KAAO3H,UAAU4G,aAAa5G,UAAUgI,kBAAkBK,eAEvDrI,UAAUyD,gBAAgBkE,MAAO,CACnC,GAAGD,YACF,MAAM,IAAI1C,MAAM,gCAAmCqD,aAAe,MAGnE,OAAO,KAKR,GAFAT,QAAU5H,UAAU4G,aAAa5G,UAAUgI,kBAAkBM,kBAE1DtI,UAAUyD,gBAAgBmE,SAAU,CACtC,GAAGF,YACF,MAAM,IAAI1C,MAAM,mCAAsCsD,gBAAkB,MAGzE,OAAO,KAGI,KAATX,MAA2B,IAAZC,UACjBD,KAAO,GAYV,GAAGA,KAAO,GAAY,GAAPA,KAAW,CACzB,GAAGD,YACF,MAAM,IAAI1C,MAAM,wCAA2C2C,KAAO,MAGnE,OAAO,KAEH,GAAGC,QAAU,GAAe,GAAVA,QAAc,CACpC,GAAGF,YACF,MAAM,IAAI1C,MAAM,2CAA8C4C,QAAU,MAGzE,OAAO,KAGR,IACIM,OAASP,KAAO,GAAK,KAAO,KAEhC,MAAO,CACNY,QAAS,CACRC,KALET,YAAuB,IAATJ,KAAa,GAAMA,MAAQ,GAAKA,KAAOA,KAAO,IAK3C,IAAM3H,UAAUyI,iBAAiBb,QAAS,GAAK,IAAMM,OACxEP,KAAMI,YACNH,QAASA,QACTM,OAAQA,OACRD,QAASN,KAAO,IAEjBe,SAAU,CACTF,IAAKxI,UAAUyI,iBAAiBd,KAAM,GAAK3H,UAAUyI,iBAAiBb,QAAS,GAC/ED,KAAMA,KACNC,QAASA,WAKZ5H,UAAU2I,WAAa,SAAoB1F,OAC1C,GAAGjD,UAAU0D,cAAcT,OAC1B,OAAO,KAGR,IAAI2F,UAAY3F,MAAMU,OAAO8C,cAAcqB,MAAM,4BAEjD,OAAG9H,UAAUkD,UAAU0F,YAAcA,UAAU/E,OAAS,EAChD,KAGD+E,UAAU,GAAKA,UAAU,IAGjC5I,UAAU6I,iBAAmB,SAA0B5F,OACtD,GAAGjD,UAAU0D,cAAcT,OAC1B,OAAO,KAGR,IAAI6F,gBAAkB7F,MAAMU,OAAO8C,cAAcqB,MAAM,4BAEvD,OAAG9H,UAAUkD,UAAU4F,kBAAoBA,gBAAgBjF,OAAS,EAC5D,KAGDiF,gBAAgB,IAGxB9I,UAAU+I,gBAAkB,SAAyB9F,OACpD,GAAoB,iBAAVA,MACT,OAAO,KAGR,GAAoB,IAAjBA,MAAMY,OACR,MAAO,GAOR,IAJA,IAAImF,KAAO/F,MAAMgG,MAAM,SACnBC,cAAgB,GAChB1C,eAAiB,KAEbjB,EAAI,EAAGA,EAAIyD,KAAKnF,OAAQ0B,IAGF,KAF7BiB,eAAiBwC,KAAKzD,GAAG5B,QAEPE,QAIlBqF,cAAcC,KAAK3C,gBAGpB,OAAO0C,eAGRlJ,UAAUoJ,uBAAyB,SAAgCnG,MAAOyE,aAGzE,GAFAA,YAAc1H,UAAU4D,aAAa8D,aAAa,GAE/C1H,UAAUiF,oBAAoBhC,OAChC,OAAOA,MAGR,GAAGjD,UAAU0D,cAAcT,OAAQ,CAClC,GAAGyE,YACF,MAAM,IAAI1C,MAAM,uCAGjB,OAAO,KAGR,IAAIqE,WAAapG,MAAM6E,MAAM,sBAE7B,IAAIuB,WAAY,CACf,GAAG3B,YACF,MAAM,IAAI1C,MAAM,qCAGjB,OAAO,KAGR,GAAG0C,YACF,OAAO,IAAIxC,OAAOmE,WAAW,GAAIA,WAAW,IAG7C,IACC,OAAO,IAAInE,OAAOmE,WAAW,GAAIA,WAAW,IAE7C,MAAMC,OACL,OAAO,OAITtJ,UAAUuJ,iBAAmB,SAA0BtG,OACtD,GAAGjD,UAAU0D,cAAcT,OAC1B,OAAO,KAGR,IAAIuD,eAAiBvD,MAAMU,OACvB6F,SAAWhD,eAAesB,MAAM,gEAEpC,OAAG0B,UAAkC,IAAtBA,SAAS,GAAG3F,OACnB2F,SAAS,GAGdhD,eAAesB,MAAM,oBAChBtB,eAGD,MAGRxG,UAAUyJ,YAAc,SAAqBxG,MAAOyG,OAAQC,SAe3D,GAdG3J,UAAUqE,eAAesF,UAC3BA,QAAU,CACTjC,YAAa1H,UAAU4D,aAAa+F,QAAQjC,aAAa,KAGlDkC,QAAU5J,UAAU4D,aAAa+F,QAAQC,SAAUD,QAAQjC,aAGnEiC,QAAU,CACTjC,aAAa,EACbkC,SAAS,IAIP5J,UAAUqE,eAAeqF,QAC5B,OAAO1J,UAAU6J,MAAM5G,OAGxByG,OAAS1J,UAAU6J,MAAMH,QAEzB,IAAII,aAAe,KAEnB,GAAG9J,UAAU0D,cAAcgG,OAAOK,MACjCD,aAAe,sEAEX,CACJ,IAAIE,aAAeN,OAAOK,KAE1BL,OAAOK,KAAOL,OAAOK,KAAKpG,OAAO8C,cAIjC,IAFA,IAAIwD,iBAAkB,EAEd1E,EAAI,EAAGA,EAAI7E,YAAYmD,OAAQ0B,IACtC,GAAGmE,OAAOK,OAASrJ,YAAY6E,GAAI,CAClC0E,iBAAkB,EAClB,MAIF,GAAIA,gBAGC,CACJ,GAAmB,SAAhBP,OAAOK,KACTL,OAAOK,KAAO,eAEV,GAAmB,QAAhBL,OAAOK,KACdL,OAAOK,KAAO,eAEV,GAAmB,WAAhBL,OAAOK,KACdL,OAAOK,KAAO,aAEV,GAAmB,WAAhBL,OAAOK,KAAmB,CACjC,QAAmB9F,IAAhByF,OAAO/F,KAAoB,CAC7B,IAAIuG,aAAeR,OAAO/F,KAE1B+F,OAAO/F,KAAO3D,UAAU4D,aAAa8F,OAAO/F,MAEzB,OAAhB+F,OAAO/F,OACTmG,aAAe,2EAA8E9J,UAAUmK,SAASD,cAAgB,MAIlI,GAAGlK,UAAUkD,UAAU4G,oBACH7F,IAAhByF,OAAOU,KACT,GAAGpK,UAAU0D,cAAcgG,OAAOU,MACjCN,aAAe,6EAEX,CACJ,IAAIO,aAAeX,OAAOU,KAE1BV,OAAOU,KAAOhK,WAAWS,UAAU6I,OAAOU,KAAKzG,QAE3C3D,UAAUmF,WAAWxE,oBAAoB+I,OAAOU,SACnDN,aAAe,wDAA0D3F,OAAOI,KAAK5D,qBAAqB2J,KAAK,MAAQ,eAAkBtK,UAAUmK,SAASE,cAAgB,YAM5K,GAAmB,WAAhBX,OAAOK,KAAmB,CACjC,QAAqB9F,IAAlByF,OAAO1F,OAAsB,CAC/B,IAAIuG,eAAiBb,OAAO1F,OAE5B0F,OAAO1F,OAAShE,UAAU4D,aAAa8F,OAAO1F,QAEzB,OAAlB0F,OAAO1F,SACT8F,aAAe,6EAAgF9J,UAAUmK,SAASI,gBAAkB,MAItI,GAAGvK,UAAUkD,UAAU4G,oBACK7F,IAAxByF,OAAOc,aAA4B,CACrC,IAAIC,qBAAuBf,OAAOc,aAElCd,OAAOc,aAAexK,UAAU4D,aAAa8F,OAAOc,cAEzB,OAAxBd,OAAOc,eACTV,aAAe,mFAAsF9J,UAAUmK,SAASM,sBAAwB,MAKnJ,GAAGzK,UAAUkD,UAAU4G,oBACF7F,IAAjByF,OAAOgB,MAAqB,CAC9B,IAAIC,cAAgBjB,OAAOgB,MAE3BhB,OAAOgB,MAAQ1K,UAAU4D,aAAa8F,OAAOgB,OAEzB,OAAjBhB,OAAOgB,QACTZ,aAAe,4EAA+E9J,UAAUmK,SAASQ,eAAiB,MAKrI,GAAG3K,UAAUkD,UAAU4G,oBACI7F,IAAvByF,OAAOkB,YAA2B,CACpC,IAAIC,oBAAsBnB,OAAOkB,YAEjClB,OAAOkB,YAAc5K,UAAU4D,aAAa8F,OAAOkB,aAEzB,OAAvBlB,OAAOkB,cACTd,aAAe,kFAAqF9J,UAAUmK,SAASU,qBAAuB,WAK1H,WAAhBnB,OAAOK,MAAqC,sBAAhBL,OAAOK,KAC1CL,OAAOK,KAAO,QAES,SAAhBL,OAAOK,OACdL,OAAOK,KAAO,YAWf,GARG/J,UAAUkD,UAAU4G,gBACH,WAAhBJ,OAAOK,MAAqC,UAAhBL,OAAOK,WAChB9F,IAAlByF,OAAOA,QAAyB1J,UAAUqE,eAAeqF,OAAOA,UAClEI,aAAe,qEAAwE9J,UAAUmK,SAAST,OAAOA,QAAU,OAK3H1J,UAAUkD,UAAU4G,gBACH,WAAhBJ,OAAOK,MAAqC,WAAhBL,OAAOK,MAAqC,UAAhBL,OAAOK,YAC1C9F,IAApByF,OAAOoB,SAAwB,CACjC,IAAIC,iBAAmBrB,OAAOoB,SAE9BpB,OAAOoB,SAAW9K,UAAU4D,aAAa8F,OAAOoB,UAEzB,OAApBpB,OAAOoB,WACThB,aAAe,wEAA2E9J,UAAUmK,SAASY,kBAAoB,YA9GrIjB,aAAe,wDAA0DpJ,YAAY4J,KAAK,MAAQ,eAAkBtK,UAAUmK,SAASH,cAAgB,KAsHzJ,GAAGhK,UAAUkD,UAAU4G,oBACC7F,IAApByF,OAAOsB,SAAwB,CACjC,IAAIC,iBAAmBvB,OAAOsB,SAE9BtB,OAAOsB,SAAWhL,UAAU4D,aAAa8F,OAAOsB,UAEzB,OAApBtB,OAAOsB,WACTlB,aAAe,wEAA2E9J,UAAUmK,SAASc,kBAAoB,MAKpI,GAAGjL,UAAUkD,UAAU4G,oBACC7F,IAApByF,OAAOwB,SAAwB,CACjC,IAAIC,iBAAmBzB,OAAOwB,SAE9BxB,OAAOwB,SAAWlL,UAAU4D,aAAa8F,OAAOwB,UAEzB,OAApBxB,OAAOwB,WACTpB,aAAe,wEAA2E9J,UAAUmK,SAASgB,kBAAoB,MA6BpI,GAxBGnL,UAAUkD,UAAU4G,oBACD7F,IAAlByF,OAAO0B,SACLpL,UAAUmF,WAAWuE,OAAO0B,UAC/BtB,aAAe,uEAA0E9J,UAAUmK,SAAST,OAAO0B,QAAU,OAK7HpL,UAAUkD,UAAU4G,oBACE7F,IAArByF,OAAOvJ,YACLH,UAAUmF,WAAWuE,OAAOvJ,aAC/B2J,aAAe,0EAA6E9J,UAAUmK,SAAST,OAAOvJ,WAAa,OAKnIH,UAAUkD,UAAU4G,oBACE7F,IAArByF,OAAO2B,YACLrL,UAAUmF,WAAWuE,OAAO2B,aAC/BvB,aAAe,0EAA6E9J,UAAUmK,SAAST,OAAO2B,WAAa,OAKnIrL,UAAUgD,QAAQ8G,cAAe,CACnC,GAAGH,QAAQjC,YACV,MAAM,IAAI1C,MAAM8E,cAMjB,OAJQH,QAAQC,SACf0B,QAAQhC,MAAMQ,cAGR,KAGR,GAAG9J,UAAUmF,WAAWuE,OAAO0B,QAC9B,GAAGzB,QAAQjC,YACVzE,MAAQyG,OAAO0B,OAAOnI,MAAOyG,OAAQC,cAGrC,IACC1G,MAAQyG,OAAO0B,OAAOnI,MAAOyG,OAAQC,SAEtC,MAAML,OAKL,OAJGK,QAAQC,SACV0B,QAAQhC,MAAMA,MAAMiC,SAGd,KAKV,IAAI/E,oBAAiBvC,EAErB,QAAaA,IAAVhB,MACFuD,eAAiBxG,UAAU6J,MAAMH,OAAO8B,cAEpC,GAAa,OAAVvI,MACJyG,OAAOsB,SACTxE,eAAiB,UAESvC,IAAnByF,OAAO8B,QACdhF,eAAiBxG,UAAU6J,MAAMH,OAAO8B,SAGxC1B,aAAe,6BAGZ,GAAmB,YAAhBJ,OAAOK,KAGQ,QAFtBvD,eAAiBxG,UAAU4D,aAAaX,UAGvC6G,aAAe,2BAA8B9J,UAAUmK,SAASlH,OAAS,WAGtE,GAAmB,YAAhByG,OAAOK,KACdvD,eAAiBxG,UAAU4G,aAAa3D,OAErCjD,UAAUyD,gBAAgB+C,kBAC5BsD,aAAe,2BAA8B9J,UAAUmK,SAASlH,OAAS,WAGtE,GAAmB,UAAhByG,OAAOK,KACdvD,eAAiBxG,UAAUiH,yBAAyBhE,OAEjDjD,UAAUyD,gBAAgB+C,kBAC5BsD,aAAe,yBAA4B9J,UAAUmK,SAASlH,OAAS,WAGpE,GAAmB,WAAhByG,OAAOK,MAWd,GAVAvD,eAAkC,iBAAVvD,MAAqBA,MAAQjD,UAAUmK,SAASlH,OAErEyG,OAAO/F,OACT6C,eAAiBA,eAAe7C,aAGdM,IAAhByF,OAAOU,OACT5D,eAAiB7F,oBAAoB+I,OAAOU,MAAM5D,iBAGhDkD,OAAOoB,UAAsC,IAA1BtE,eAAe3C,OAAc,CAClD,IAAI0H,QAAU,gCAEd,GAAG5B,QAAQjC,YACV,MAAM,IAAI1C,MAAMuG,SAMjB,OAJQ5B,QAAQC,SACf0B,QAAQhC,MAAMiC,SAGR,WAGJ,GAAmB,UAAhB7B,OAAOK,KAAkB,CAChC,GAAoB,iBAAV9G,MACT,IACCuD,eAAiBiF,KAAKjE,MAAMvE,OAExByB,MAAMC,QAAQ6B,kBACjBsD,aAAe,2DAA8D9J,UAAUmK,SAASlH,OAAS,MAG3G,MAAMqG,OACLQ,aAAe,qCAAwC9J,UAAUmK,SAASlH,OAAS,UAG7EyB,MAAMC,QAAQ1B,OACrBuD,eAAiBxG,UAAU6J,MAAM5G,OAGjC6G,aAAe,8DAAiE9J,UAAUmK,SAASlH,OAAS,KAG7G,GAAGjD,UAAUkD,UAAU4G,eACnBpF,MAAMC,QAAQ6B,gBAAiB,CACjC,IAAIkF,eAAiB,GAErB,GAAG1L,UAAUqE,eAAeqF,OAAOA,QAClC,CAAA,IAAIiC,iBAAmB,KAEvB,IAAQpG,EAAI,EAAGA,EAAIiB,eAAe3C,OAAQ0B,IACzC,QAAyBtB,IAAtBuC,eAAejB,GAAlB,CAIA,GAAGoE,QAAQjC,YACViE,iBAAmB3L,UAAUyJ,YAAYjD,eAAejB,GAAImE,OAAOA,OAAQC,aAEvE,EACAiC,WAAa5L,UAAU6J,MAAMF,UAEtBjC,aAAc,EAEzB,IACCiE,iBAAmB3L,UAAUyJ,YAAYjD,eAAejB,GAAImE,OAAOA,OAAQkC,YAE5E,MAAMtC,OAKL,OAJGK,QAAQC,SACV0B,QAAQhC,MAAMA,MAAMiC,SAGd,MAITG,eAAevC,KAAKwC,wBAIrB,IAAQpG,EAAI,EAAGA,EAAIiB,eAAe3C,OAAQ0B,SAChBtB,IAAtBuC,eAAejB,IAIlBmG,eAAevC,KAAKnJ,UAAU6J,MAAMrD,eAAejB,KAMrD,GAFAiB,eAAiBkF,eAEdhC,OAAOoB,UAAsC,IAA1BtE,eAAe3C,OAAc,CAC9C0H,QAAU,+BAEd,GAAG5B,QAAQjC,YACV,MAAM,IAAI1C,MAAMuG,SAMjB,OAJQ5B,QAAQC,SACf0B,QAAQhC,MAAMiC,SAGR,YAKN,GAAmB,SAAhB7B,OAAOK,KACdvD,eAAiBxG,UAAUmH,UAAUlE,OAEjCjD,UAAU6E,OAAO2B,kBACpBsD,aAAe,wBAA2B9J,UAAUmK,SAASlH,OAAS,WAGnE,GAAmB,UAAhByG,OAAOK,KAAkB,CAChC,GAAG/J,UAAUiF,oBAAoBhC,OAChCuD,eAAiBxG,UAAU6J,MAAM5G,YAGjC,GAAG0G,QAAQjC,YACVlB,eAAiBxG,UAAUoJ,uBAAuBnG,OAAO,QAGzD,IACCuD,eAAiBxG,UAAUoJ,uBAAuBnG,OAAO,GAE1D,MAAMqG,OACLQ,aAAeR,MAAMiC,QAKrBvL,UAAUkD,UAAUsD,kBACtBsD,aAAe,sCAAyC9J,UAAUmK,SAASlH,OAAS,UAG9D,aAAhByG,OAAOK,OACdvD,eAAiBvD,MAEbjD,UAAUmF,WAAWqB,kBACxBsD,aAAe,4BAA+B9J,UAAUmK,SAASlH,OAAS,OAI5E,GAAGjD,UAAUkD,UAAU4G,eACH,WAAhBJ,OAAOK,KAAmB,CAC5B,GAAG/J,UAAUgD,QAAQC,OACpB,GAAoB,iBAAVA,MACT,IACCuD,eAAiBiF,KAAKjE,MAAMvE,OAExBjD,UAAU+D,SAASyC,eAAgBkD,OAAO1F,UAC7C8F,aAAe,qDAAuDJ,OAAO1F,OAAS,UAAY,IAAM,YAAehE,UAAUmK,SAASlH,OAAS,MAGrJ,MAAMqG,OACLQ,aAAe,sCAAyC9J,UAAUmK,SAASlH,OAAS,UAG9EjD,UAAU+D,SAASd,MAAOyG,OAAO1F,QACxCwC,eAAiBxG,UAAU6J,MAAM5G,OAGjC6G,aAAe,kCAAoCJ,OAAO1F,OAAS,UAAY,IAAM,kCAAqChE,UAAUmK,SAASlH,OAAS,KAIxJ,GAAGjD,UAAUkD,UAAU4G,cAAe,CAOrC,GANG9J,UAAUkD,UAAUsD,iBACnBkD,OAAOc,eAAiBxK,UAAU+D,SAASyC,eAAgBkD,OAAO1F,UACpEwC,eAAiB,IAIhBxG,UAAUqE,eAAeqF,OAAOA,SAAW1J,UAAU+D,SAASyC,gBAAiB,CACjF,IAAIqF,UAAY,KACZC,WAAa3H,OAAOI,KAAKmF,OAAOA,QAEpC,IAAQnE,EAAI,EAAGA,EAAIuG,WAAWjI,OAAQ0B,IAGrC,GAFAsG,UAAYC,WAAWvG,GAEpBoE,QAAQjC,YAAa,MAGGzD,KAFtB8H,mBAAqB/L,UAAUyJ,YAAYjD,eAAeqF,WAAYnC,OAAOA,OAAOmC,WAAYlC,YAGnGnD,eAAeqF,WAAaE,wBAGzB,CACJ,IAAIH,YAAAA,WAAa5L,UAAU6J,MAAMF,UAEtBjC,aAAc,EAEzB,IACC,IAAIqE,wBAEsB9H,KAFtB8H,mBAAqB/L,UAAUyJ,YAAYjD,eAAeqF,WAAYnC,OAAOA,OAAOmC,WAAYD,eAGnGpF,eAAeqF,WAAaE,oBAG9B,MAAMzC,OAKL,OAJGK,QAAQC,SACV0B,QAAQhC,MAAMA,MAAMiC,SAGd,MAKV,GAAG7B,OAAOkB,YAAa,CACtB,IAAI/D,SAAW,GAEfiF,WAAa3H,OAAOI,KAAKiC,gBAEzB,IAAQjB,EAAI,EAAGA,EAAIuG,WAAWjI,OAAQ0B,IACrCsG,UAAYC,WAAWvG,GAEpBvF,UAAUgD,QAAQ0G,OAAOA,OAAOmC,cAClChF,SAASgF,WAAarF,eAAeqF,YAIvCrF,eAAiBK,SAGlB,GAAG6C,OAAOgB,MAAO,CAChB,IAAIsB,cAAgB,GAEpBF,WAAa3H,OAAOI,KAAKmF,OAAOA,QAEhC,IAAQnE,EAAI,EAAGA,EAAIuG,WAAWjI,OAAQ0B,SAGJtB,IAA9BuC,eAFHqF,UAAYC,WAAWvG,MAGtByG,cAAcH,WAAarF,eAAeqF,kBAEnCrF,eAAeqF,YAIxB,IAAII,gBAAkB9H,OAAOI,KAAKiC,gBAElC,IAAQjB,EAAI,EAAGA,EAAI0G,gBAAgBpI,OAAQ0B,IAG1CyG,cAFAH,UAAYI,gBAAgB1G,IAEDiB,eAAeqF,WAG3CrF,eAAiBwF,eAInB,GAAGtC,OAAOoB,UAAY9K,UAAUsE,cAAckC,gBAAiB,CAC1D+E,QAAU,oDAEd,GAAG5B,QAAQjC,YACV,MAAM,IAAI1C,MAAMuG,SAMjB,OAJQ5B,QAAQC,SACf0B,QAAQhC,MAAMiC,SAGR,OAMX,GAAGvL,UAAUgD,QAAQ8G,cAAe,CACnC,GAAGH,QAAQjC,YACV,MAAM,IAAI1C,MAAM8E,cAMjB,OAJQH,QAAQC,SACf0B,QAAQhC,MAAMQ,cAGR,KAGR,QAAsB7F,IAAnBuC,eAA8B,CAChC,GAAGkD,OAAOwB,SAAU,CACfK,QAAU,0BAEd,GAAG5B,QAAQjC,YACV,MAAM,IAAI1C,MAAMuG,SAMjB,OAJQ5B,QAAQC,SACf0B,QAAQhC,MAAMiC,SAGR,UAGctH,IAAnByF,OAAO8B,UACThF,eAAiBxG,UAAU6J,MAAMH,OAAO8B,UAI1C,GAAGxL,UAAUmF,WAAWuE,OAAOvJ,WAC9B,GAAGwJ,QAAQjC,aACV,IAAIgC,OAAOvJ,UAAUqG,eAAgBkD,OAAQC,SAC5C,MAAM,IAAI3E,MAAM,iCAIjB,IACC,IAAI0E,OAAOvJ,UAAUqG,eAAgBkD,OAAQC,SAAU,CAClD4B,QAAU,2BAMd,OAJG5B,QAAQC,SACV0B,QAAQhC,MAAMiC,SAGR,MAGT,MAAMjC,OAKL,OAJGK,QAAQC,SACV0B,QAAQhC,MAAMA,MAAMiC,SAGd,KAKV,GAAGvL,UAAUmF,WAAWuE,OAAO2B,WAC9B,GAAG1B,QAAQjC,YACVlB,eAAiBkD,OAAO2B,UAAU7E,eAAgBkD,OAAQC,cAG1D,IACCnD,eAAiBkD,OAAO2B,UAAU7E,eAAgBkD,OAAQC,SAE3D,MAAML,OAKL,OAJGK,QAAQC,SACV0B,QAAQhC,MAAMA,MAAMiC,SAGd,KAKV,OAAO/E,gBAGRxG,UAAUkM,aAAe,SAAsBC,OAAQzC,OAAQkB,YAAalD,aAC3E,KAAI1H,UAAUqE,eAAe8H,SAAanM,UAAUqE,eAAeuG,cAAiB5K,UAAUmF,WAAWyF,YAAYQ,SACpH,MAAO,GAGR,IAAIzB,QAAU,KAGbA,QADE3J,UAAUqE,eAAeuG,aACjB,CACTlD,YAAa1H,UAAU4D,aAAagH,YAAYlD,YAAa1H,UAAU4D,aAAa8D,aAAa,IACjGkC,QAAS5J,UAAU4D,aAAagH,YAAYhB,SAAS,IAI5C,CACTlC,YAAa1H,UAAU4D,aAAa8D,aAAa,GACjDkC,SAAS,GAIX,IAAIwC,UAAY,CACfrC,KAAM,SACN/F,QAAQ,EACRwG,eAAcxK,UAAUqE,eAAeuG,cAAe5K,UAAU4D,aAAagH,YAAYJ,cAAc,GACvGE,QAAO1K,UAAUqE,eAAeuG,cAAe5K,UAAU4D,aAAagH,YAAYF,OAAO,GACzFE,YAAa5K,UAAUqE,eAAeuG,aAAe5K,UAAU4D,aAAagH,YAAYA,YAAa5K,UAAU4D,aAAagH,aAAa,IAAU5K,UAAU4D,aAAagH,aAAa,GACvLI,UAAU,EACVE,UAAU,EACVxB,OAAQA,QAGN1J,UAAUqE,eAAeuG,eACxB5K,UAAUmF,WAAWyF,YAAYQ,UACnCgB,UAAUhB,OAASR,YAAYQ,QAG7BpL,UAAUmF,WAAWyF,YAAYzK,aACnCiM,UAAUjM,UAAYyK,YAAYzK,WAGhCH,UAAUmF,WAAWyF,YAAYS,aACnCe,UAAUf,UAAYT,YAAYS,YAIpC,IAAIgB,gBAAkB,KAEtB,GAAG1C,QAAQjC,YACV2E,gBAAkBrM,UAAUyJ,YAC3B0C,OACAC,UACAzC,aAGG,CACJ,IAAIiC,WAAa5L,UAAU6J,MAAMF,SAEjCiC,WAAWlE,aAAc,EAEzB,IACC2E,gBAAkBrM,UAAUyJ,YAC3B0C,OACAC,UACAR,YAGF,MAAMtC,OAKL,OAJGK,QAAQC,SACV0B,QAAQhC,MAAMA,MAAMiC,SAGd,MAIT,OAAOvL,UAAUqE,eAAegI,kBAAqBrM,UAAUqE,eAAeuG,cAAgB5K,UAAUmF,WAAWyF,YAAYQ,QAAWiB,gBAAkB,IAG7JrM,UAAUsM,iBAAmB,SAA0BrJ,MAAOsJ,WAC7D,IAAIvD,KAAO,KAEX,GAAGhJ,UAAU8D,iBAAiBb,OAC7B+F,KAAOhJ,UAAU+I,gBAAgB9F,WAE7B,CAAA,IAAGjD,UAAU4E,gBAAgB3B,OAG7B,MAAoB,iBAAVA,OAAsByB,MAAMC,QAAQ1B,OAC3C,GAGA,KANP+F,KAAO/F,MASR,IAAIiG,cAAgB,GAChB1C,eAAiB,KAErB+F,UAAYvM,UAAU4D,aAAa2I,WAEnC,IAAI,IAAIhH,EAAI,EAAGA,EAAIyD,KAAKnF,OAAQ0B,IAAK,CACpC,GAAsB,iBAAZyD,KAAKzD,GAAiB,CAC/B,GAAiB,OAAdgH,UACF,SAGA/F,eADO+F,UACUvM,UAAUmK,SAASnB,KAAKzD,IAGxByD,KAAKzD,QAIvBiB,eAAiBwC,KAAKzD,GAAG5B,OAGG,IAA1B6C,eAAe3C,SAIQ,EAAvBqF,cAAcrF,SAChBqF,eAAiB,MAGlBA,eAAiB1C,gBAGlB,OAAO0C,eAGRlJ,UAAUwM,UAAY,SAAmBC,OAAQC,MAChD,OAAItF,OAAOC,UAAUoF,SAAYrF,OAAOC,UAAUqF,MAI3CD,OAASE,KAAKC,IAAI,EAAGF,MAHpB5F,KAMT9G,UAAU6M,WAAa,SAAoBJ,OAAQC,MAClD,OAAItF,OAAOC,UAAUoF,SAAYrF,OAAOC,UAAUqF,MAI3CD,OAASE,KAAKC,IAAI,EAAGF,MAHpB5F,KAMT9G,UAAU8M,WAAa,SAAoB7J,MAAOqD,cACjD,MAAwB,iBAAVrD,MAAqBA,MAAMU,YAA2BM,IAAjBqC,aAA6B,KAAOA,cAGxFtG,UAAU+M,yBAA2B,SAAkC9J,MAAOqD,cAC7E,GAAoB,iBAAVrD,MACT,YAAwBgB,IAAjBqC,aAA6B,KAAOA,aAG5C,IAAI0G,oBAAsB/J,MAAMgK,QAAQ,MAExC,OAA0B,GAAvBD,oBACK/J,MAAMiK,OAAO,EAAGF,qBAGjB/J,OAGRjD,UAAUmN,eAAiB,SAAwBlK,MAAOmK,cACzD,GAAoB,iBAAVnK,MACT,OAAO,KAGR,IAAIoK,cAAgBpK,MAAMqK,QAAQ,oBAAqB,IAMvD,OAJGtN,UAAU4D,aAAawJ,cAAc,KACvCC,cAAgBA,cAAcC,QAAQ,YAAa,KAG7CD,eAGRrN,UAAUuN,qBAAuB,SAA8BtK,OAC9D,MAAoB,iBAAVA,MACF,KAGLjD,UAAU0D,cAAcT,OACnBA,MAGDA,MAAMqK,QAAQ,cAAe,KAGrCtN,UAAUwN,yBAA2B,SAAkCvK,OACtE,MAAwB,iBAAVA,MAAqBA,MAAMqK,QAAQ,WAAY,KAAO,MAGrEtN,UAAUyN,WAAa,SAAoBxK,MAAOyK,OAAQC,YAAaC,iBACtE,GAAoB,iBAAV3K,MACT,OAAO,KAGR2K,gBAAkB5N,UAAU4D,aAAagK,iBAAiB,IAE1DF,OAAS1N,UAAU4G,aAAa8G,OAAQ,IAE5B,IACXA,OAAS,GAGVC,YAAqC,iBAAhBA,YAA2BA,YAAc,KAI9D,IAFA,IAAIE,iBAAmB,GAEftI,EAAI,EAAGA,EAAImI,OAAQnI,IAC1BsI,kBAAoBF,YAGrB,IAAIG,KAAO,KACPC,MAAQ9K,MAAMgG,MAAM,aACpB+E,kBAAoB,GAExB,IAAQzI,EAAI,EAAGA,EAAIwI,MAAMlK,OAAQ0B,IAChCuI,KAAOC,MAAMxI,GAEbyI,oBAAsBhO,UAAU0D,cAAcoK,OAASF,gBAAkB,GAAKC,iBAAmBC,OAAUvI,EAAIwI,MAAMlK,OAAS,EAAK,KAAO,IAG3I,OAAOmK,mBAGRhO,UAAUgI,kBAAoB,SAA2B/E,OACxD,GAAoB,iBAAVA,MACT,OAAO,KAGR,GAAoB,IAAjBA,MAAMY,OACR,OAAOZ,MAGR,IAAIuD,eAAiBvD,MAAMU,OAE3B,OAA6B,IAA1B6C,eAAe3C,OACV2C,eAEAA,eAAesB,MAAM,UACrB,IAGDtB,eAAe8G,QAAQ,MAAO,KAGtCtN,UAAUyI,iBAAmB,SAA0BxF,MAAOgL,gBAC7D,GAAGjO,UAAUkD,UAAUD,OACtB,OAAO,KAMR,GAHAA,MAAQA,MAAMkH,WACd8D,eAAiBjO,UAAU4G,aAAaqH,gBAErCjO,UAAUyD,gBAAgBwK,iBAAmBA,eAAiB,EAChE,OAAOhL,MAKR,IAFA,IAAIiL,eAAiBD,eAAiBhL,MAAMY,OAEpC0B,EAAI,EAAGA,EAAI2I,eAAgB3I,IAClCtC,MAAQ,IAAMA,MAGf,OAAOA,OAGRjD,UAAUmK,SAAW,SAAkBlH,OACtC,QAAagB,IAAVhB,MACF,MAAO,YAEH,GAAa,OAAVA,MACP,MAAO,OAEH,GAAoB,iBAAVA,MACd,OAAOA,MAEH,GAAGA,QAAUO,EAAAA,EACjB,MAAO,WAEH,GAAGP,SAAWO,EAAAA,EAClB,MAAO,YAEH,GAAoB,iBAAVP,OAAsBM,MAAMN,OAC1C,MAAO,MAEH,GAAGjD,UAAU6E,OAAO5B,OACxB,OAAOA,MAAMkH,WAET,GAAGnK,UAAUiF,oBAAoBhC,OAAQ,CAC7C,IAAIkL,MAAQ,GAEZ,IAAI,IAAIC,QAAQ/N,YACZ4C,MAAMmL,QACRD,OAAS9N,YAAY+N,OAIvB,MAAO,IAAMnL,MAAMoL,OAAS,IAAMF,MAE9B,GAAGnO,UAAUmF,WAAWlC,OAC5B,OAAOA,MAAMkH,WAET,GAAGnK,UAAU+E,QAAQ9B,OAAQ,CACjC,IAAIqG,MAAQ,CAAEiC,QAAStI,MAAMsI,SAE7B,IAAI,IAAIM,aAAa5I,MACpBqG,MAAMuC,WAAa5I,MAAM4I,WAG1B,OAAOJ,KAAKc,UAAUjD,OAGvB,OAAOmC,KAAKc,UAAUtJ,QAGvBjD,UAAUsO,aAAe,SAAsBC,EAAGC,GAIjD,OAHAD,EAAIvO,UAAUmH,UAAUoH,GACxBC,EAAIxO,UAAUmH,UAAUqH,GAEf,OAAND,GAAoB,OAANC,EACT,EAGC,OAAND,GACM,EAEK,OAANC,EACA,EAGDD,EAAEE,UAAYD,EAAEC,WAGxBzO,UAAU0O,sBAAwB,SAA+BzL,OAChE,GAAGjD,UAAU0D,cAAcT,OAC1B,OAAO,EAWR,IARA,IAAI0L,EAAI,KACJ/L,MAAQ,EACRtB,MAAQ,EACRsN,OAAS,IAAIC,aACbC,OAAS,IAAID,aACbE,OAAS,IAAIF,aACbG,OAAS,IAAIH,aAETtJ,EAAI,EAAGA,EAAItC,MAAMY,OAAQ0B,IAGxBqJ,SAFRD,EAAI1L,MAAM4L,WAAWtJ,KAEHoJ,GAAKG,OACtBxN,QAEYyN,QAALJ,GAAeA,GAAKK,QAC3BpM,QAIF,OAAOA,MAAQtB,OAGhBtB,UAAUiP,cAAgB,SAAuBhM,OAChD,GAAoB,iBAAVA,MACT,OAAO,KAYR,IAFA,IAAIiM,QAAU,GAEN3J,GATRtC,MAAQA,MAAMqK,QACb,6QACA,SAAS6B,GAAIC,GAAIC,IAChB,OAAOrP,UAAUiP,cAAcI,IAAMD,KAErC9B,QAAQ,sCAAuC,SAI/BzJ,OAAS,EAAQ,GAAL0B,EAAQA,IACrC2J,SAAWjM,MAAMsC,GAGlB,OAAO2J,SAGRlP,UAAUsP,YAAc,SAAqB/D,QAASgE,QACrD,IAAIjG,MAAQ,IAAItE,MAAMuG,SAEtB,OADAjC,MAAMiG,OAASvP,UAAU4G,aAAa2I,OAAQ,KACvCjG,OAGRtJ,UAAU6J,MAAQ,SAAe5G,OAChC,IAAIjD,UAAU+D,SAASd,OACtB,OAAOA,MAEH,GAAGA,iBAAiBI,QACxB,OAAO,IAAIA,QAAQJ,MAAMsD,WAErB,GAAGtD,iBAAiB6B,KAIxB,OAHI0K,KAAO,IAAI1K,MACV2K,QAAQxM,MAAMwL,WAEZe,KAEH,GAAGvM,iBAAiByB,MAAO,CAG/B,IAFA,IAAI8K,KAAO,GAEHjK,EAAI,EAAG1B,OAASZ,MAAMY,OAAQ0B,EAAI1B,OAAQ0B,IACjDiK,KAAKjK,GAAKvF,UAAU6J,MAAM5G,MAAMsC,IAGjC,OAAOiK,KAEH,GAAGvM,iBAAiByM,IACxB,OAAO,IAAIA,IAAIzM,OAEX,GAAGA,iBAAiB0M,IACxB,OAAO,IAAIA,IAAI1M,OAEX,GAAGA,iBAAiBiC,OAAQ,CAChC,IAAIiJ,MAAQ,GAEZ,IAAI,IAAIC,QAAQ/N,YACZ4C,MAAMmL,QACRD,OAAS9N,YAAY+N,OAIvB,OAAO,IAAIlJ,OAAOjC,MAAMoL,OAAQF,OAE5B,GAAqB,oBAAXyB,QAA0B3M,iBAAiB2M,OACzD,OAAOA,OAAOC,gBAAgBzL,SAAWwL,OAAOC,KAAK5M,OAAS,IAAI2M,OAAO3M,OAErE,GAAGA,iBAAiBkB,OAAQ,CAC5BqL,KAAO,KAEX,GAAGvM,iBAAiB+B,MAAO,EAC1BwK,KAAO,IAAIxK,MAAM/B,MAAMsI,UAElBuE,MAAQ9P,UAAU6J,MAAM5G,MAAM6M,OAEnC,IAAIC,WAAa5L,OAAOI,KAAKtB,OAE7B,IAAQsC,EAAI,EAAGA,EAAIwK,WAAWlM,OAAQ0B,IACrCiK,KAAKO,WAAWxK,IAAMvF,UAAU6J,MAAM5G,MAAM8M,WAAWxK,UAIxDiK,KAAO,GAGR,IAAI,IAAI3D,aAAa5I,MACjBkB,OAAO6L,UAAUC,eAAeC,KAAKjN,MAAO4I,aAC9C2D,KAAK3D,WAAa7L,UAAU6J,MAAM5G,MAAM4I,aAI1C,OAAO2D,KAGR,OAAOvM,OAGRjD,UAAUmQ,MAAQ,SAAe5B,EAAGC,EAAGgB,KAAMY,WAC5C,IAAIpQ,UAAU+D,SAASwK,IAAM7J,MAAMC,QAAQ4J,GAC1C,OAAO,KAGR,IAAI8B,UAAY,KAWhB,GANCA,WAHDb,KAAOxP,UAAU4D,aAAa4L,MAAM,IAGvBxP,UAAU6J,MAAM0E,GAGhBA,GAGTvO,UAAU+D,SAASwK,IAAM7J,MAAMC,QAAQ4J,KAAOvO,UAAU+D,SAASyK,IAAM9J,MAAMC,QAAQ6J,GACxF,OAAO6B,UAGR,IAAIxE,UAAY,KACZ5I,MAAQ,KACR4D,SAAW,KACXiF,WAAa3H,OAAOI,KAAKiK,GAE7B4B,UAAYpQ,UAAU4D,aAAawM,WAAW,GAE9C,IAAI,IAAI7K,EAAI,EAAGA,EAAIuG,WAAWjI,OAAQ0B,IAErCtC,MAAQoN,UADRxE,UAAYC,WAAWvG,IAItBsB,SADE2I,KACSxP,UAAU6J,MAAM2E,EAAE3C,YAGlB2C,EAAE3C,WAGXuE,WAAapQ,UAAU+D,SAASd,SAAWyB,MAAMC,QAAQ1B,QAAUjD,UAAU+D,SAAS8C,YAAcnC,MAAMC,QAAQkC,UACpHwJ,UAAUxE,WAAa7L,UAAUmQ,MAAMlN,MAAO4D,UAG9CwJ,UAAUxE,WAAahF,SAIzB,OAAOwJ,WAGRrQ,UAAUsQ,YAAc,SAAqBC,UAC5C,GAAuB,iBAAbA,SACT,OAAO,KAKR,IAAI,IAAIhL,GAFRgL,SAAWA,SAAS5M,QAECE,OAAS,EAAQ,GAAL0B,EAAQA,IACxC,GAAmB,MAAhBgL,SAAShL,IAA8B,OAAhBgL,SAAShL,GAClC,OAAOgL,SAASC,UAAUjL,EAAI,EAAGgL,SAAS1M,QAAQF,OAIpD,OAAO4M,UAGRvQ,UAAUyQ,YAAc,SAAqBF,UAC5C,GAAuB,iBAAbA,SACT,OAAO,KAKR,IAAI,IAAIhL,GAFRgL,SAAWA,SAAS5M,QAECE,OAAS,EAAQ,GAAL0B,EAAQA,IACxC,GAAmB,MAAhBgL,SAAShL,IAA8B,OAAhBgL,SAAShL,GAClC,OAAOgL,SAASC,UAAU,EAAGjL,GAAG5B,OAIlC,MAAO,IAGR3D,UAAU0Q,uBAAyB,SAAgCC,UAClE,GAAuB,iBAAbA,SACT,OAAO,KAKR,IAAI,IAAIpL,GAFRoL,SAAW3Q,UAAUsQ,YAAYK,WAEZ9M,OAAS,EAAQ,GAAL0B,EAAQA,IACxC,GAAmB,MAAhBoL,SAASpL,GACX,OAAOoL,SAASH,UAAU,EAAGjL,GAAG5B,OAIlC,OAAOgN,UAGR3Q,UAAU4Q,iBAAmB,SAA0BD,UACtD,GAAuB,iBAAbA,SACT,OAAO,KAKR,IAAI,IAAIpL,GAFRoL,SAAW3Q,UAAUsQ,YAAYK,WAEZ9M,OAAS,EAAQ,GAAL0B,EAAQA,IACxC,GAAmB,MAAhBoL,SAASpL,GACX,OAAOoL,SAASH,UAAUjL,EAAI,EAAGoL,SAAS9M,QAAQF,OAIpD,MAAO,IAGR3D,UAAU6Q,iBAAmB,SAA0BF,SAAUG,WAChE,GAAG9Q,UAAU0D,cAAciN,WAAa3Q,UAAU0D,cAAcoN,WAC/D,OAAO,EAGR,IAAIC,oBAAsB/Q,UAAU4Q,iBAAiBD,UAErD,OAAG3Q,UAAU0D,cAAcqN,sBAIpBA,oBAAoBtK,gBAAkBqK,UAAUnN,OAAO8C,eAG/DzG,UAAUgR,qBAAuB,SAA8BL,UAC9D,GAAuB,iBAAbA,SACT,OAAO,KAKR,IAAI,IAAIpL,GAFRoL,SAAWA,SAAShN,QAECE,OAAS,EAAQ,GAAL0B,EAAQA,IACxC,GAAmB,MAAhBoL,SAASpL,GACX,OAAOoL,SAASH,UAAU,EAAGjL,GAAK,IAAMvF,UAAUiP,cAAc0B,SAASH,UAAUjL,EAAI,EAAGoL,SAAS9M,SAIrG,OAAO8M,UAGR3Q,UAAUiR,iBAAmB,SAA0BN,SAAUO,WAChE,GAAuB,iBAAbP,SACT,OAAO,KAKR,GAFAA,SAAW3Q,UAAUsQ,YAAYK,UAE9B3Q,UAAU0D,cAAciN,UAC1B,MAAO,GAKR,GAFAO,UAAYlR,UAAU4G,aAAasK,WAEhClR,UAAUyD,gBAAgByN,YAAcA,UAAY,EACtD,OAAOP,SAGR,GAAiB,IAAdO,UACF,MAAO,GAGR,GAAGP,SAAS9M,QAAUqN,UACrB,OAAOP,SAMR,IAHA,IAAIG,UAAY,GACZK,iBAAmBR,SAEfpL,EAAIoL,SAAS9M,OAAS,EAAQ,GAAL0B,EAAQA,IACxC,GAAmB,MAAhBoL,SAASpL,GAAY,CACvBuL,UAAYH,SAASH,UAAUjL,EAAI,EAAGoL,SAAS9M,QAC/CsN,iBAAmBR,SAASH,UAAU,EAAGjL,GACzC,MAIF,OAAG2L,WAAaJ,UAAUjN,QAA6B,EAAnBiN,UAAUjN,OAAa,EAAI,IAAM,EAC7DsN,iBAAiBX,UAAU,EAAGU,WAG/BC,iBAAiBX,UAAU,EAAGU,UAAYJ,UAAUjN,QAA6B,EAAnBiN,UAAUjN,OAAa,EAAI,KAA0B,EAAnBiN,UAAUjN,OAAa,IAAMiN,UAAY,KAGjJ9Q,UAAUoR,aAAe,SAAsBnO,OAC9C,GAAoB,iBAAVA,MACT,OAAO,KAGR,IAAIuD,eAAiBvD,MAAMU,OAE3B,OAA6B,IAA1B6C,eAAe3C,QAIO,MAAtB2C,eAAe,IAAoC,OAAtBA,eAAe,KAC9CA,eAAiB,IAAMA,gBAJhBA,gBAUTxG,UAAUqR,YAAc,SAAqBpO,OAC5C,GAAoB,iBAAVA,MACT,OAAO,KAGR,IAAIuD,eAAiBvD,MAAMU,OAE3B,OAA6B,IAA1B6C,eAAe3C,QAI+B,MAA9C2C,eAAeA,eAAe3C,OAAS,IAA4D,OAA9C2C,eAAeA,eAAe3C,OAAS,KAC9F2C,gBAAkB,KAJXA,gBAUTxG,UAAUsR,UAAY,SAAmBC,KAAMvP,MAC9C,IAAIwP,cAAgC,iBAATD,KAAoBA,KAAK5N,OAAO2J,QAAQ,WAAY,IAAM,KACjFmE,cAAgC,iBAATzP,KAAoBA,KAAK2B,OAAO2J,QAAQ,WAAY,IAAM,KACjFoE,QAAU,GAcd,OAZG1R,UAAU8D,iBAAiB0N,iBAC7BE,SAAWF,cAERxR,UAAU8D,iBAAiB2N,iBAC7BC,SAAW,MAIV1R,UAAU8D,iBAAiB2N,iBAC7BC,SAAWD,eAGLC,SAGR1R,UAAU2R,kBAAoB,SAA2B1O,MAAO2O,qBAC/D,IAAI5R,UAAUqE,eAAepB,OAC5B,MAAO,GAGR,IAAI4O,WAAa1N,OAAOI,KAAKtB,OAAO6O,IAAI,SAASC,KAChD,OAAOC,mBAAmBD,KAAO,IAAMC,mBAAmBhS,UAAUmK,SAASlH,MAAM8O,SACjFzH,KAAK,KAER,OAAyB,IAAtBuH,WAAWhO,OACN,IAGA7D,UAAU4D,aAAagO,qBAAqB,GAAS,IAAM,IAAMC,YAG1E7R,UAAUiS,YAAc,SAAqBC,MAAOC,KACnD,IAAIC,eAAiBpS,UAAU4G,aAAasL,OACxCG,aAAerS,UAAU4G,aAAauL,KAO1C,GALwB,IAArBG,UAAUzO,SACZwO,aAAeD,eACfA,eAAiB,GAGfpS,UAAUyD,gBAAgB2O,iBAAmBpS,UAAUyD,gBAAgB4O,eAAkCA,aAAjBD,eAC1F,MAAO,GAKR,IAFA,IAAIG,MAAQ,GAEJhN,EAAI6M,eAAgB7M,GAAK8M,aAAc9M,IAC9CgN,MAAMpJ,KAAK5D,GAGZ,OAAOgN,OAGRvS,UAAUwS,aAAe,SAAsBC,KAAMC,aAGpD,GAAY,QAFZD,KAAOzS,UAAUmH,UAAUsL,OAG1B,OAAO,KAGR,IAAIE,YAAc,IAAI7N,KAClB8N,MAAQ,EAETH,KAAKI,gBAAkBF,YAAYE,gBACrCD,MAAQD,YAAYG,YAGrB,IAAIC,OAAS,GAEbL,YAAc1S,UAAU4D,aAAa8O,aAAa,GAElD,IAAI,IAAInN,EAAI,EAAGA,EAAI,GAAIA,IACdqN,OAALrN,IACCmN,YACFK,OAAO5J,MAAM5D,GAAK,EAAI,IAAM,KAAOA,EAAI,IAGvCwN,OAAO5J,KAAK5D,EAAI,IAKnB,OAAOwN,QAGR/S,UAAUgT,gBAAkB,SAAyBC,UACpD,IAAIvO,MAAMC,QAAQsO,UACjB,MAAO,GAKR,IAFA,IAAID,gBAAkB,GAEdzN,EAAI,EAAGA,EAAI0N,SAASpP,OAAQ0B,IAChCvF,UAAUwF,UAAUyN,SAAS1N,KAC/ByN,gBAAgB7J,KAAK8J,SAAS1N,IAIhC,OAAOyN,iBAGRhT,UAAUkT,eAAiB,SAAwBD,UAClD,IAAIvO,MAAMC,QAAQsO,UACjB,MAAO,GAKR,IAFA,IAAIC,eAAiB,GAEb3N,EAAI,EAAGA,EAAI0N,SAASpP,OAAQ0B,IAChCvF,UAAU4F,SAASqN,SAAS1N,KAC9B2N,eAAe/J,KAAK8J,SAAS1N,IAI/B,OAAO2N,gBAGRlT,UAAUmT,gBAAkB,SAAyBF,UACpD,IAAIvO,MAAMC,QAAQsO,UACjB,MAAO,GAKR,IAFA,IAAIE,gBAAkB,GAEd5N,EAAI,EAAGA,EAAI0N,SAASpP,OAAQ0B,IAChCvF,UAAU6F,UAAUoN,SAAS1N,KAC/B4N,gBAAgBhK,KAAK8J,SAAS1N,IAIhC,OAAO4N,iBAGRnT,UAAUoT,iBAAmB,SAA0BH,UACtD,IAAIvO,MAAMC,QAAQsO,UACjB,MAAO,GAKR,IAFA,IAAIG,iBAAmB,GAEf7N,EAAI,EAAGA,EAAI0N,SAASpP,OAAQ0B,IAChCvF,UAAUgG,WAAWiN,SAAS1N,KAChC6N,iBAAiBjK,KAAK8J,SAAS1N,IAIjC,OAAO6N,kBAGRpT,UAAUqT,sBAAwB,SAA+BJ,SAAUpH,UAAWyH,cACrF,IAAI5O,MAAMC,QAAQsO,WAAajT,UAAU0D,cAAcmI,WACtD,MAAO,GAGR,IAAIpG,QAAU,KACV8N,iBAAmB,GAEvB1H,UAAYA,UAAUlI,OACtB2P,aAAetT,UAAU4D,aAAa0P,cAAc,GAEpD,IAAI,IAAI/N,EAAI,EAAGA,EAAI0N,SAASpP,OAAQ0B,IACnCE,QAAUwN,SAAS1N,GAEfvF,UAAU+D,SAAS0B,WAIpBzF,UAAUkD,UAAU+P,SAAS1N,GAAGsG,YAC9ByH,cACHC,iBAAiBpK,KAAK1D,SAIpB6N,cACFC,iBAAiBpK,KAAK8J,SAAS1N,KAKlC,OAAOgO,kBAGRvT,UAAUwT,yBAA2B,SAAkCP,SAAUpH,WAChF,OAAO7L,UAAUqT,sBAAsBJ,SAAUpH,WAAW,IAG7D7L,UAAUyT,eAAiB,SAAwBhO,QAASoG,UAAW5I,OACtE,QAAIjD,UAAU+D,SAAS0B,aAIpBzF,UAAU0D,cAAcmI,YAIpBpG,QAAQoG,UAAUlI,UAAYV,QAGtCjD,UAAU0T,iBAAmB,SAA0BC,QAASC,OAAQC,QAGvE,GAAe,QAFfF,QAAU3T,UAAU8T,aAAaH,UAGhC,OAAO,KAGRC,OAAS5T,UAAU8M,WAAW8G,QAC9BC,OAAS7T,UAAU8M,WAAW+G,QAK9B,IAHA,IAAIE,SAAW,GACX9Q,MAAQ,KAEJsC,EAAI,EAAGA,EAAIoO,QAAQ9P,OAAQ0B,IAAK,CACvCtC,MAAQ,GAELjD,UAAU8D,iBAAiB8P,UAC7B3Q,OAAS2Q,QAGV,IAAI,IAAII,EAAI,EAAGA,GAAKzO,EAAGyO,IACf,EAAJA,IACF/Q,OAAS,KAGVA,OAAS0Q,QAAQK,GAGfhU,UAAU8D,iBAAiB+P,UAC7B5Q,OAAS4Q,QAGVE,SAAS5K,KAAKlG,OAGf,OAAO8Q,UAGR/T,UAAU8T,aAAe,SAAsB7Q,MAAOgR,oBACrD,IAAIzN,eAAiBxG,UAAUsD,cAAcL,OAASA,MAAMkH,WAAalH,MAEzE,GAA6B,iBAAnBuD,eACT,OAAO,KAGR,IAAImN,QAAU,GACVO,YAAc1N,eAAesB,MAAM,aAEvC,GAAmB,OAAhBoM,aAA+C,IAAvBA,YAAYrQ,OACtC,OAAO,KAKR,IAFA,IAAIsQ,KAAO,KAEH5O,EAAI,EAAGA,EAAI2O,YAAYrQ,OAAQ0B,IACtC,GAAGpF,UAAUoH,MAAM2M,YAAY3O,IAAK,CAGnC,GAFA4O,KAAOnU,UAAU4G,aAAasN,YAAY3O,IAEvCvF,UAAUyD,gBAAgB0Q,OAASA,KAAO,EAC5C,SAGDR,QAAQxK,KAAKgL,KAAKhK,iBAGlBwJ,QAAQxK,KAAK+K,YAAY3O,IAI3B,GAAGvF,UAAU4D,aAAaqQ,oBAAoB,GAC7C,OACIN,QAAQ9P,QAAU,IAIc,MAAhC8P,QAAQA,QAAQ9P,OAAS,IAC3B8P,QAAQS,MAQX,OAA0B,IAAnBT,QAAQ9P,OAAe,KAAO8P,SAGtC3T,UAAUqU,gBAAkB,SAAyBC,GAAIC,GAAIC,cAAe9M,aAM3E,GALA8M,cAAgBxU,UAAU4D,aAAa4Q,eAAe,GACtD9M,YAAc1H,UAAU4D,aAAa8D,aAAa,GAIxC,QAFV4M,GAAKtU,UAAU8T,aAAaQ,KAEZ,CACf,GAAG5M,YACF,MAAM,IAAI1C,MAAM,kDAGjB,OAAO,KAKR,GAAU,QAFVuP,GAAKvU,UAAU8T,aAAaS,KAEZ,CACf,GAAG7M,YACF,MAAM,IAAI1C,MAAM,mDAGjB,OAAO,KAKR,IAFA,IAAIyP,MAAQ,IAEA,CACX,GAAGA,OAASH,GAAGzQ,OAAQ,CACtB,GAAGyQ,GAAGzQ,SAAW0Q,GAAG1Q,OACnB,OAAO,EAGR,IAAI,IAAI0B,EAAIkP,MAAOlP,EAAIgP,GAAG1Q,OAAQ0B,IACjC,GAAa,MAAVgP,GAAGhP,GACL,OAAQ,EAIV,OAAO,EAGR,GAAGkP,OAASF,GAAG1Q,OAAQ,CACtB,IAAQ0B,EAAIkP,MAAOlP,EAAI+O,GAAGzQ,OAAQ0B,IACjC,GAAa,MAAV+O,GAAG/O,GACL,OAAO,EAIT,OAAO,EAGR,IAAImP,WAAa1U,UAAU4G,aAAa0N,GAAGG,QACvCE,WAAa3U,UAAU4G,aAAa2N,GAAGE,QAU3C,GARGzU,UAAUyD,gBAAgBiR,cAC5BA,WAAaF,cAAgBF,GAAGG,OAASH,GAAGG,OAAOtM,eAGjDnI,UAAUyD,gBAAgBkR,cAC5BA,WAAaH,cAAgBD,GAAGE,OAASF,GAAGE,OAAOtM,eAGjDf,OAAOC,UAAUqN,aACnB,IAAItN,OAAOC,UAAUsN,YACpB,OAAQ,OAIT,GAAGvN,OAAOC,UAAUsN,YACnB,OAAO,EAIT,GAAgBA,WAAbD,WACF,OAAO,EAEH,GAAGA,WAAaC,WACpB,OAAQ,EAGTF,UAIKzU","file":"extra-utilities.min.js","sourcesContent":["(function(global, factory) {\n\ttypeof exports === \"object\" && typeof module !== \"undefined\" ? module.exports = factory() :\n\ttypeof define === \"function\" && define.amd ? define(factory) :\n\t(global.utilities = factory());\n} (this, function() {\n\n\t\"use strict\";\n\n\tif(typeof require !== \"undefined\") {\n\t\tif(typeof validator === \"undefined\") {\n\t\t\tglobal.validator = require(\"validator\");\n\t\t}\n\n\t\tif(typeof changeCase === \"undefined\") {\n\t\t\tglobal.changeCase = require(\"change-case-bundled\");\n\t\t}\n\t}\n\n\t/**\n\t * @module utilities\n\t */\n\tvar utilities = { };\n\n\tvar regExpFlags = {\n\t\tglobal: \"g\",\n\t\tmultiline: \"m\",\n\t\tignoreCase: \"i\",\n\t\tsticky: \"y\",\n\t\tunicode: \"u\"\n\t};\n\n\tvar formatTypes = [\"boolean\", \"bool\", \"integer\", \"int\", \"float\", \"number\", \"string\", \"object\", \"array\", \"date\", \"regex\", \"regexp\", \"regularexpression\", \"function\", \"func\"];\n\n\tvar stringCaseFunctions = {\n\t\tcamel: changeCase.camelCase,\n\t\tcapital: changeCase.capitalCase,\n\t\tconstant: changeCase.constantCase,\n\t\tdot: changeCase.dotCase,\n\t\theader: changeCase.headerCase,\n\t\tlower: changeCase.lowerCase,\n\t\tlowerFirst: changeCase.lowerCaseFirst,\n\t\tno: changeCase.noCase,\n\t\tparam: changeCase.paramCase,\n\t\tpascal: changeCase.pascalCase,\n\t\tpath: changeCase.pathCase,\n\t\tsentence: changeCase.sentenceCase,\n\t\tsnake: changeCase.snakeCase,\n\t\tsponge: changeCase.spongeCase,\n\t\tswap: changeCase.swapCase,\n\t\ttitle: changeCase.titleCase,\n\t\tupper: changeCase.upperCase,\n\t\tupperFirst: changeCase.upperCaseFirst\n\t};\n\n\t/**\n\t * Verifies that the specified value is not null or undefined.\n\t *\n\t * @name isValid\n\t * @method\n\t * @param {any} value - The variable check.\n\t * @returns true if the specified value is not null or undefined.\n\t * @memberOf module:utilities\n\t * @category utilities\n\t * @example\n\t * console.log(utilities.isValid(42)); // true\n\t * console.log(utilities.isValid(null)); // false\n\t */\n\tutilities.isValid = function isValid(value) {\n\t\treturn value !== undefined && value !== null;\n\t};\n\n\t/**\n\t * Verifies that the specified value is null or undefined.\n\t *\n\t * @name isInvalid\n\t * @method\n\t * @param {any} value - The variable check.\n\t * @returns true if the specified value is null or undefined.\n\t * @memberOf module:utilities\n\t * @category utilities\n\t * @example\n\t * console.log(utilities.isInvalid(69)); // false\n\t * console.log(utilities.isInvalid(undefined)); // true\n\t */\n\tutilities.isInvalid = function isInvalid(value) {\n\t\treturn value === undefined || value === null;\n\t};\n\n\t/**\n\t * Verifies that the specified value is a boolean.\n\t *\n\t * @name isBoolean\n\t * @method\n\t * @param {any} value - The variable check.\n\t * @param {boolean} allowObjects - Will allow Boolean objects to be treated as valid values.\n\t * @returns true if the specified value is a boolean.\n\t * @memberOf module:utilities\n\t * @category utilities\n\t * @example\n\t * console.log(utilities.isBoolean(false)); // true\n\t * console.log(utilities.isBoolean(8675309)); // false\n\t * console.log(utilities.isBoolean(new Boolean(true))); // false\n\t * console.log(utilities.isBoolean(new Boolean(false), true)); // true\n\t */\n\tutilities.isBoolean = function isBoolean(value, allowObjects) {\n\t\treturn value === true || value === false || (!!allowObjects && value instanceof Boolean);\n\t};\n\n\tutilities.isValidNumber = function isValidNumber(value) {\n\t\treturn typeof value === \"number\" && !isNaN(value) && value !== -Infinity && value !== Infinity;\n\t};\n\n\tutilities.isInvalidNumber = function isInvalidNumber(value) {\n\t\treturn typeof value !== \"number\" || isNaN(value) || value === -Infinity || value === Infinity;\n\t};\n\n\tutilities.isEmptyString = function isEmptyString(value, trim) {\n\t\treturn typeof value !== \"string\" || (utilities.parseBoolean(trim, true) ? value.trim().length === 0 : value.length === 0);\n\t};\n\n\tutilities.isNonEmptyString = function isNonEmptyString(value, trim) {\n\t\treturn typeof value === \"string\" && (utilities.parseBoolean(trim, true) ? value.trim().length !== 0 : value.length !== 0);\n\t};\n\n\tutilities.isObject = function isObject(value, strict) {\n\t\treturn value !== undefined && (strict ? value !== null && value.constructor === Object : value instanceof Object && !(value instanceof Function));\n\t};\n\n\tutilities.isObjectStrict = function isObjectStrict(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object;\n\t};\n\n\tutilities.isEmptyObject = function isEmptyObject(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length === 0;\n\t};\n\n\tutilities.isNonEmptyObject = function isNonEmptyObject(value) {\n\t\treturn value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length !== 0;\n\t};\n\n\tutilities.isEmptyArray = function isEmptyArray(value) {\n\t\treturn Array.isArray(value) ? value.length === 0 : true;\n\t};\n\n\tutilities.isNonEmptyArray = function isNonEmptyArray(value) {\n\t\treturn Array.isArray(value) && value.length !== 0;\n\t};\n\n\tutilities.isDate = function isDate(value) {\n\t\treturn value instanceof Date;\n\t};\n\n\tutilities.isError = function isError(value) {\n\t\treturn value instanceof Error;\n\t};\n\n\tutilities.isRegularExpression = function isRegularExpression(value) {\n\t\treturn value instanceof RegExp;\n\t};\n\n\tutilities.isFunction = function isFunction(value) {\n\t\treturn value instanceof Function;\n\t};\n\n\tutilities.isComment = function isComment(value, comment) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(comment)) {\n\t\t\tcomment = \"//\";\n\t\t}\n\n\t\tvar commentStartIndex = -1;\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tif(value[i] === \" \" || value[i] == \"\\t\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(value[i] == comment[0]) {\n\t\t\t\tcommentStartIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif(commentStartIndex < 0 || value.length - commentStartIndex < comment.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor(var i = commentStartIndex; i < value.length; i++) {\n\t\t\tif(i - commentStartIndex >= comment.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(value[i] != comment[i - commentStartIndex]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isVisible = function isVisible(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn !element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn !element.hidden();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isHidden = function isHidden(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.visible)) {\n\t\t\treturn !element.visible;\n\t\t}\n\t\telse if(utilities.isFunction(element.visible)) {\n\t\t\treturn !element.visible();\n\t\t}\n\t\telse if(utilities.isBoolean(element.hidden)) {\n\t\t\treturn element.hidden;\n\t\t}\n\t\telse if(utilities.isFunction(element.hidden)) {\n\t\t\treturn element.hidden();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.isEnabled = function isEnabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn !element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn !element.disabled();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tutilities.isDisabled = function isDisabled(element) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(utilities.isBoolean(element.enabled)) {\n\t\t\treturn !element.enabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.enabled)) {\n\t\t\treturn !element.enabled();\n\t\t}\n\t\telse if(utilities.isBoolean(element.disabled)) {\n\t\t\treturn element.disabled;\n\t\t}\n\t\telse if(utilities.isFunction(element.disabled)) {\n\t\t\treturn element.disabled();\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tutilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) {\n\t\tif(typeof stringA !== \"string\" || typeof stringB !== \"string\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn stringA.localeCompare(stringB, undefined, { sensitivity: \"accent\" }) === 0;\n\t};\n\n\tutilities.parseBoolean = function parseBoolean(value, defaultValue) {\n\t\tif(utilities.isBoolean(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isBoolean(value, true)) {\n\t\t\treturn value.valueOf();\n\t\t}\n\n\t\tif(!utilities.isBoolean(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(value === 0) {\n\t\t\treturn false;\n\t\t}\n\t\telse if(value === 1) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tvar formattedValue = value.trim().toLowerCase();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue.length === 1) {\n\t\t\tvar character = formattedValue.charAt(0);\n\n\t\t\tif(character === \"t\" || character === \"y\") {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if(character === \"f\" || character === \"n\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"0\") {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if(character === \"1\") {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tif(formattedValue === \"true\" || formattedValue === \"yes\" || formattedValue === \"on\") {\n\t\t\treturn true;\n\t\t}\n\t\telse if(formattedValue === \"false\" || formattedValue === \"no\" || formattedValue === \"off\") {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseInteger = function parseInteger(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = parseInt(value);\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(validator.isFloat(value)) {\n\t\t\t\tnewValue = parseInt(value);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\tdefaultValue = parseInt(defaultValue);\n\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseFloatingPointNumber = function parseFloatingPointNumber(value, defaultValue) {\n\t\tvar newValue = NaN;\n\n\t\tif(typeof value === \"number\") {\n\t\t\tnewValue = value;\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tif(validator.isFloat(value)) {\n\t\t\t\tnewValue = parseFloat(value);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(newValue)) {\n\t\t\treturn utilities.isValidNumber(defaultValue) ? defaultValue : NaN;\n\t\t}\n\n\t\treturn newValue;\n\t};\n\n\tutilities.parseDate = function parseDate(value, defaultValue) {\n\t\tif(!utilities.isDate(defaultValue)) {\n\t\t\tdefaultValue = null;\n\t\t}\n\n\t\tif(typeof value === \"number\") {\n\t\t\tif(utilities.isInvalidNumber(value) || !Number.isInteger(value)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(parseInt(value));\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\tvar formattedValue = value.trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\tvar timestamp = null;\n\n\t\t\tif(validator.isInt(formattedValue)) {\n\t\t\t\ttimestamp = parseInt(formattedValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimestamp = Date.parse(formattedValue);\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(timestamp)) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\n\t\t\treturn new Date(timestamp);\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn defaultValue;\n\t};\n\n\tutilities.parseTime = function parseTime(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors);\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid or empty time value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar hour = null;\n\t\tvar minutes = null;\n\t\tvar regularTime = formattedValue.match(/^[ \\t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \\t]*([ap]m))[ \\t]*$/i);\n\n\t\tif(regularTime) {\n\t\t\tvar regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));\n\n\t\t\tif(utilities.isInvalidNumber(regularHour)) {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid regular hour: \\\"\" + regularTime[2] + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4]));\n\n\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\tminutes = 0;\n\t\t\t}\n\n\t\t\tvar period = regularTime[5].toUpperCase();\n\t\t\tvar morning = period === \"AM\" ? true : (period === \"PM\" ? false : null);\n\n\t\t\tif(morning === null) {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid period: \\\"\" + regularTime[5] + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\thour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12);\n\n\t\t\tif(hour === 24) {\n\t\t\t\thour = 0;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tvar militaryTime = formattedValue.match(/^[ \\t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \\t]*$/i);\n\n\t\t\tif(militaryTime) {\n\t\t\t\tvar militaryHour = militaryTime[3];\n\t\t\t\tvar militaryMinutes = militaryTime[6];\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tmilitaryHour = militaryTime[8];\n\n\t\t\t\t\tif(utilities.isNonEmptyString(militaryTime[9])) {\n\t\t\t\t\t\tmilitaryMinutes = militaryTime[9];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\thour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour));\n\n\t\t\t\tif(utilities.isInvalidNumber(hour)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time hour: \\\"\" + militaryHour + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tminutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes));\n\n\t\t\t\tif(utilities.isInvalidNumber(minutes)) {\n\t\t\t\t\tif(throwErrors) {\n\t\t\t\t\t\tthrow new Error(\"Invalid military time minutes: \\\"\" + militaryMinutes + \"\\\".\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif(hour === 24 && minutes === 0) {\n\t\t\t\t\thour = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(throwErrors) {\n\t\t\t\t\tthrow new Error(\"Invalid time: \\\"\" + formattedValue + \"\\\".\");\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tif(hour < 0 || hour > 23) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Time hour is out of range (0 - 23): \\\"\" + hour + \"\\\".\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\telse if(minutes < 0 || minutes > 59) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Time minutes is out of range (0 - 59): \\\"\" + minutes + \"\\\".\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12);\n\t\tvar period = hour < 12 ? \"AM\" : \"PM\";\n\n\t\treturn {\n\t\t\tregular: {\n\t\t\t\traw: regularHour + \":\" + utilities.addLeadingZeroes(minutes, 2) + \" \" + period,\n\t\t\t\thour: regularHour,\n\t\t\t\tminutes: minutes,\n\t\t\t\tperiod: period,\n\t\t\t\tmorning: hour < 12\n\t\t\t},\n\t\t\tmilitary: {\n\t\t\t\traw: utilities.addLeadingZeroes(hour, 2) + utilities.addLeadingZeroes(minutes, 2),\n\t\t\t\thour: hour,\n\t\t\t\tminutes: minutes\n\t\t\t}\n\t\t};\n\t};\n\n\tutilities.parseEmail = function parseEmail(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?(@.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailData) || emailData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailData[1] + emailData[3];\n\t};\n\n\tutilities.parseEmailDomain = function parseEmailDomain(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar emailDomainData = value.trim().toLowerCase().match(/([^+@]+)(\\+.*)?@(.+\\..+)/);\n\n\t\tif(utilities.isInvalid(emailDomainData) || emailDomainData.length < 4) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn emailDomainData[3];\n\t};\n\n\tutilities.parseStringList = function parseStringList(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar data = value.split(/[;,]+/);\n\t\tvar formattedList = [];\n\t\tvar formattedValue = null;\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tformattedValue = data[i].trim();\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tformattedList.push(formattedValue);\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.parseRegularExpression = function parseRegularExpression(value, throwErrors) {\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tif(utilities.isRegularExpression(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Regular expression cannot be empty.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar regExpData = value.match(/\\s*\\/(.*)\\/(.*)\\s*/);\n\n\t\tif(!regExpData) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Invalid regular expression value.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(throwErrors) {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new RegExp(regExpData[1], regExpData[2]);\n\t\t}\n\t\tcatch(error) {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\tutilities.parseYouTubeLink = function parseYouTubeLink(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\t\tvar linkData = formattedValue.match(/.*(?:youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=)([^#\\&\\?]*).*/i);\n\n\t\tif(linkData && linkData[1].length >= 11) {\n\t\t\treturn linkData[1];\n\t\t}\n\n\t\tif(formattedValue.match(/[A-Z0-9_-]{11,}/i)) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\treturn null;\n\t};\n\n\tutilities.formatValue = function formatValue(value, format, options) {\n\t\tif(utilities.isObjectStrict(options)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(options.throwErrors, false)\n\t\t\t};\n\n\t\t\toptions.verbose = utilities.parseBoolean(options.verbose, !options.throwErrors);\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: false,\n\t\t\t\tverbose: true\n\t\t\t};\n\t\t}\n\n\t\tif(!utilities.isObjectStrict(format)) {\n\t\t\treturn utilities.clone(value);\n\t\t}\n\n\t\tformat = utilities.clone(format);\n\n\t\tvar errorMessage = null;\n\n\t\tif(utilities.isEmptyString(format.type)) {\n\t\t\terrorMessage = \"Invalid required type format value - expected non-empty string.\";\n\t\t}\n\t\telse {\n\t\t\tvar originalType = format.type;\n\n\t\t\tformat.type = format.type.trim().toLowerCase();\n\n\t\t\tvar validFormatType = false;\n\n\t\t\tfor(var i = 0; i < formatTypes.length; i++) {\n\t\t\t\tif(format.type === formatTypes[i]) {\n\t\t\t\t\tvalidFormatType = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!validFormatType) {\n\t\t\t\terrorMessage = \"Invalid required type format value - expected one of \" + formatTypes.join(\", \") + \", received \\\"\" + utilities.toString(originalType) + \"\\\".\";\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(format.type === \"bool\") {\n\t\t\t\t\tformat.type = \"boolean\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"int\") {\n\t\t\t\t\tformat.type = \"integer\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"number\") {\n\t\t\t\t\tformat.type = \"float\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"string\") {\n\t\t\t\t\tif(format.trim !== undefined) {\n\t\t\t\t\t\tvar originalTrim = format.trim;\n\n\t\t\t\t\t\tformat.trim = utilities.parseBoolean(format.trim);\n\n\t\t\t\t\t\tif(format.trim === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional trim string format value - expected boolean, received \\\"\" + utilities.toString(originalTrim) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.case !== undefined) {\n\t\t\t\t\t\t\tif(utilities.isEmptyString(format.case)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional string case format value - expected non-empty string.\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar originalCase = format.case;\n\n\t\t\t\t\t\t\t\tformat.case = changeCase.camelCase(format.case.trim());\n\n\t\t\t\t\t\t\t\tif(!utilities.isFunction(stringCaseFunctions[format.case])) {\n\t\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional case format value - expected one of \" + Object.keys(stringCaseFunctions).join(\", \") + \", received \\\"\" + utilities.toString(originalCase) + \"\\\".\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"object\") {\n\t\t\t\t\tif(format.strict !== undefined) {\n\t\t\t\t\t\tvar originalStrict = format.strict;\n\n\t\t\t\t\t\tformat.strict = utilities.parseBoolean(format.strict);\n\n\t\t\t\t\t\tif(format.strict === null) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional strict object format value - expected boolean, received \\\"\" + utilities.toString(originalStrict) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.autopopulate !== undefined) {\n\t\t\t\t\t\t\tvar originalAutopopulate = format.autopopulate;\n\n\t\t\t\t\t\t\tformat.autopopulate = utilities.parseBoolean(format.autopopulate);\n\n\t\t\t\t\t\t\tif(format.autopopulate === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional autopopulate object format value - expected boolean, received \\\"\" + utilities.toString(originalAutopopulate) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.order !== undefined) {\n\t\t\t\t\t\t\tvar originalOrder = format.order;\n\n\t\t\t\t\t\t\tformat.order = utilities.parseBoolean(format.order);\n\n\t\t\t\t\t\t\tif(format.order === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional order object format value - expected boolean, received \\\"\" + utilities.toString(originalOrder) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\t\tif(format.removeExtra !== undefined) {\n\t\t\t\t\t\t\tvar originalRemoveExtra = format.removeExtra;\n\n\t\t\t\t\t\t\tformat.removeExtra = utilities.parseBoolean(format.removeExtra);\n\n\t\t\t\t\t\t\tif(format.removeExtra === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional removeExtra object format value - expected boolean, received \\\"\" + utilities.toString(originalRemoveExtra) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"regexp\" || format.type === \"regularexpression\") {\n\t\t\t\t\tformat.type = \"regex\";\n\t\t\t\t}\n\t\t\t\telse if(format.type === \"func\") {\n\t\t\t\t\tformat.type = \"function\";\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.format !== undefined && !utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid optional format format value - expected object, received \\\"\" + utilities.toString(format.format) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(format.type === \"string\" || format.type === \"object\" || format.type === \"array\") {\n\t\t\t\t\t\tif(format.nonEmpty !== undefined) {\n\t\t\t\t\t\t\tvar originalNonEmpty = format.nonEmpty;\n\n\t\t\t\t\t\t\tformat.nonEmpty = utilities.parseBoolean(format.nonEmpty);\n\n\t\t\t\t\t\t\tif(format.nonEmpty === null) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid optional nonEmpty format value - expected boolean, received \\\"\" + utilities.toString(originalNonEmpty) + \"\\\".\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.nullable !== undefined) {\n\t\t\t\tvar originalNullable = format.nullable;\n\n\t\t\t\tformat.nullable = utilities.parseBoolean(format.nullable);\n\n\t\t\t\tif(format.nullable === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional nullable format value - expected boolean, received \\\"\" + utilities.toString(originalNullable) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.required !== undefined) {\n\t\t\t\tvar originalRequired = format.required;\n\n\t\t\t\tformat.required = utilities.parseBoolean(format.required);\n\n\t\t\t\tif(format.required === null) {\n\t\t\t\t\terrorMessage = \"Invalid optional required format value - expected boolean, received \\\"\" + utilities.toString(originalRequired) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.parser !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.parser)) {\n\t\t\t\t\terrorMessage = \"Invalid optional parser format value - expected function, received \\\"\" + utilities.toString(format.parser) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.validator !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.validator)) {\n\t\t\t\t\terrorMessage = \"Invalid optional validator format value - expected function, received \\\"\" + utilities.toString(format.validator) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.formatter !== undefined) {\n\t\t\t\tif(!utilities.isFunction(format.formatter)) {\n\t\t\t\t\terrorMessage = \"Invalid optional formatter format value - expected function, received \\\"\" + utilities.toString(format.formatter) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isFunction(format.parser)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tvalue = format.parser(value, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar formattedValue = undefined;\n\n\t\tif(value === undefined) {\n\t\t\tformattedValue = utilities.clone(format.default);\n\t\t}\n\t\telse if(value === null) {\n\t\t\tif(format.nullable) {\n\t\t\t\tformattedValue = null;\n\t\t\t}\n\t\t\telse if(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Value cannot be null!\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"boolean\") {\n\t\t\tformattedValue = utilities.parseBoolean(value);\n\n\t\t\tif(formattedValue === null) {\n\t\t\t\terrorMessage = \"Invalid boolean value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"integer\") {\n\t\t\tformattedValue = utilities.parseInteger(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid integer value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"float\") {\n\t\t\tformattedValue = utilities.parseFloatingPointNumber(value);\n\n\t\t\tif(utilities.isInvalidNumber(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid float value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"string\") {\n\t\t\tformattedValue = typeof value === \"string\" ? value : utilities.toString(value);\n\n\t\t\tif(format.trim) {\n\t\t\t\tformattedValue = formattedValue.trim();\n\t\t\t}\n\n\t\t\tif(format.case !== undefined) {\n\t\t\t\tformattedValue = stringCaseFunctions[format.case](formattedValue);\n\t\t\t}\n\n\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\tvar message = \"String value cannot be empty.\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"array\") {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\tif(!Array.isArray(formattedValue)) {\n\t\t\t\t\t\terrorMessage = \"Invalid stringified array value type - expected array: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\terrorMessage = \"Invalid stringified array value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(Array.isArray(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\terrorMessage = \"Invalid value type - expected array or stringified array: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\tif(Array.isArray(formattedValue)) {\n\t\t\t\t\tvar formattedArray = [];\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format)) {\n\t\t\t\t\t\tvar formattedElement = null;\n\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, options);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tformattedElement = utilities.formatValue(formattedValue[i], format.format, subOptions);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(formattedElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor(var i = 0; i < formattedValue.length; i++) {\n\t\t\t\t\t\t\tif(formattedValue[i] === undefined) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedArray.push(utilities.clone(formattedValue[i]));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tformattedValue = formattedArray;\n\n\t\t\t\t\tif(format.nonEmpty && formattedValue.length === 0) {\n\t\t\t\t\t\tvar message = \"Array value cannot be empty.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"date\") {\n\t\t\tformattedValue = utilities.parseDate(value);\n\n\t\t\tif(!utilities.isDate(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid date value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"regex\") {\n\t\t\tif(utilities.isRegularExpression(value)) {\n\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tformattedValue = utilities.parseRegularExpression(value, true);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\terrorMessage = error.message;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid regular expression value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\t\telse if(format.type === \"function\") {\n\t\t\tformattedValue = value;\n\n\t\t\tif(!utilities.isFunction(formattedValue)) {\n\t\t\t\terrorMessage = \"Invalid function value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\tif(format.type === \"object\") {\n\t\t\t\tif(utilities.isValid(value)) {\n\t\t\t\t\tif(typeof value === \"string\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tformattedValue = JSON.parse(value);\n\n\t\t\t\t\t\t\tif(!utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object: \\\"\" + utilities.toString(value) + \"\\\".\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\terrorMessage = \"Invalid stringified object value: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if(utilities.isObject(value, format.strict)) {\n\t\t\t\t\t\tformattedValue = utilities.clone(value);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\terrorMessage = \"Invalid value type - expected \" + (format.strict ? \"strict \" : \"\") + \"object or stringified object: \\\"\" + utilities.toString(value) + \"\\\".\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(utilities.isInvalid(errorMessage)) {\n\t\t\t\t\tif(utilities.isInvalid(formattedValue)) {\n\t\t\t\t\t\tif(format.autopopulate && !utilities.isObject(formattedValue, format.strict)) {\n\t\t\t\t\t\t\tformattedValue = { };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(utilities.isObjectStrict(format.format) && utilities.isObject(formattedValue)) {\n\t\t\t\t\t\tvar attribute = null;\n\t\t\t\t\t\tvar attributes = Object.keys(format.format);\n\n\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], options);\n\n\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\t\t\t\t\t\tsubOptions.throwErrors = true;\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tvar formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], subOptions);\n\n\t\t\t\t\t\t\t\t\tif(formattedAttribute !== undefined) {\n\t\t\t\t\t\t\t\t\t\tformattedValue[attribute] = formattedAttribute;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch(error) {\n\t\t\t\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.removeExtra) {\n\t\t\t\t\t\t\tvar newValue = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(utilities.isValid(format.format[attribute])) {\n\t\t\t\t\t\t\t\t\tnewValue[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = newValue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(format.order) {\n\t\t\t\t\t\t\tvar orderedObject = { };\n\n\t\t\t\t\t\t\tattributes = Object.keys(format.format);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = attributes[i];\n\n\t\t\t\t\t\t\t\tif(formattedValue[attribute] !== undefined) {\n\t\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\n\t\t\t\t\t\t\t\t\tdelete formattedValue[attribute];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar extraAttributes = Object.keys(formattedValue);\n\n\t\t\t\t\t\t\tfor(var i = 0; i < extraAttributes.length; i++) {\n\t\t\t\t\t\t\t\tattribute = extraAttributes[i];\n\n\t\t\t\t\t\t\t\torderedObject[attribute] = formattedValue[attribute];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tformattedValue = orderedObject;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(format.nonEmpty && utilities.isEmptyObject(formattedValue)) {\n\t\t\t\t\t\tvar message = \"Object value must contain at least one attribute.\";\n\n\t\t\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\t\t\tthrow new Error(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isValid(errorMessage)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tthrow new Error(errorMessage);\n\t\t\t}\n\t\t\telse if(options.verbose) {\n\t\t\t\tconsole.error(errorMessage);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tif(formattedValue === undefined) {\n\t\t\tif(format.required) {\n\t\t\t\tvar message = \"Missing required value!\";\n\n\t\t\t\tif(options.throwErrors) {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t}\n\t\t\t\telse if(options.verbose) {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif(format.default !== undefined) {\n\t\t\t\tformattedValue = utilities.clone(format.default);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.validator)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\tthrow new Error(\"Validation check failed!\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tif(!format.validator(formattedValue, format, options)) {\n\t\t\t\t\t\tvar message = \"Validation check failed!\";\n\n\t\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\t\tconsole.error(message);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isFunction(format.formatter)) {\n\t\t\tif(options.throwErrors) {\n\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tformattedValue = format.formatter(formattedValue, format, options);\n\t\t\t\t}\n\t\t\t\tcatch(error) {\n\t\t\t\t\tif(options.verbose) {\n\t\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.formatObject = function formatObject(object, format, removeExtra, throwErrors) {\n\t\tif(!utilities.isObjectStrict(object) && (!utilities.isObjectStrict(removeExtra) || !utilities.isFunction(removeExtra.parser))) {\n\t\t\treturn { };\n\t\t}\n\n\t\tvar options = null;\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(removeExtra.throwErrors, utilities.parseBoolean(throwErrors, false)),\n\t\t\t\tverbose: utilities.parseBoolean(removeExtra.verbose, false)\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\toptions = {\n\t\t\t\tthrowErrors: utilities.parseBoolean(throwErrors, false),\n\t\t\t\tverbose: false\n\t\t\t};\n\t\t}\n\n\t\tvar subFormat = {\n\t\t\ttype: \"object\",\n\t\t\tstrict: false,\n\t\t\tautopopulate: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.autopopulate, false) : false,\n\t\t\torder: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.order, false) : false,\n\t\t\tremoveExtra: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.removeExtra, utilities.parseBoolean(removeExtra, false)) : utilities.parseBoolean(removeExtra, false),\n\t\t\tnullable: true,\n\t\t\trequired: false,\n\t\t\tformat: format\n\t\t};\n\n\t\tif(utilities.isObjectStrict(removeExtra)) {\n\t\t\tif(utilities.isFunction(removeExtra.parser)) {\n\t\t\t\tsubFormat.parser = removeExtra.parser;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.validator)) {\n\t\t\t\tsubFormat.validator = removeExtra.validator;\n\t\t\t}\n\n\t\t\tif(utilities.isFunction(removeExtra.formatter)) {\n\t\t\t\tsubFormat.formatter = removeExtra.formatter;\n\t\t\t}\n\t\t}\n\n\t\tvar formattedObject = null;\n\n\t\tif(options.throwErrors) {\n\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\tobject,\n\t\t\t\tsubFormat,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tvar subOptions = utilities.clone(options);\n\n\t\t\tsubOptions.throwErrors = true;\n\n\t\t\ttry {\n\t\t\t\tformattedObject = utilities.formatValue(\n\t\t\t\t\tobject,\n\t\t\t\t\tsubFormat,\n\t\t\t\t\tsubOptions\n\t\t\t\t);\n\t\t\t}\n\t\t\tcatch(error) {\n\t\t\t\tif(options.verbose) {\n\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn utilities.isObjectStrict(formattedObject) || (utilities.isObjectStrict(removeExtra) && utilities.isFunction(removeExtra.parser)) ? formattedObject : { };\n\t};\n\n\tutilities.formatStringList = function formatStringList(value, stringify) {\n\t\tvar data = null;\n\n\t\tif(utilities.isNonEmptyString(value)) {\n\t\t\tdata = utilities.parseStringList(value);\n\t\t}\n\t\telse if(utilities.isNonEmptyArray(value)) {\n\t\t\tdata = value;\n\t\t}\n\t\telse if(typeof value === \"string\" || Array.isArray(value)) {\n\t\t\treturn \"\";\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedList = \"\";\n\t\tvar formattedValue = null;\n\n\t\tstringify = utilities.parseBoolean(stringify);\n\n\t\tfor(var i = 0; i < data.length; i++) {\n\t\t\tif(typeof data[i] !== \"string\") {\n\t\t\t\tif(stringify === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if(stringify) {\n\t\t\t\t\tformattedValue = utilities.toString(data[i]);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tformattedValue = data[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tformattedValue = data[i].trim();\n\t\t\t}\n\n\t\t\tif(formattedValue.length === 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(formattedList.length > 0) {\n\t\t\t\tformattedList += \", \";\n\t\t\t}\n\n\t\t\tformattedList += formattedValue;\n\t\t}\n\n\t\treturn formattedList;\n\t};\n\n\tutilities.leftShift = function leftShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number * Math.pow(2, bits);\n\t};\n\n\tutilities.rightShift = function rightShift(number, bits) {\n\t\tif(!Number.isInteger(number) || !Number.isInteger(bits)) {\n\t\t\treturn NaN;\n\t\t}\n\n\t\treturn number / Math.pow(2, bits);\n\t};\n\n\tutilities.trimString = function trimString(value, defaultValue) {\n\t\treturn typeof value === \"string\" ? value.trim() : (defaultValue === undefined ? null : defaultValue);\n\t};\n\n\tutilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn defaultValue === undefined ? null : defaultValue;\n\t\t}\n\n\t\tvar nullTerminatorIndex = value.indexOf(\"\\0\");\n\n\t\tif(nullTerminatorIndex >= 0) {\n\t\t\treturn value.substr(0, nullTerminatorIndex);\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.trimWhitespace = function trimWhitespace(value, trimNewlines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar trimmedString = value.replace(/^[ \\t]+|[ \\t]+$/gm, \"\");\n\n\t\tif(utilities.parseBoolean(trimNewlines, false)) {\n\t\t\ttrimmedString = trimmedString.replace(/\\r\\n?|\\n/g, \"\");\n\t\t}\n\n\t\treturn trimmedString;\n\t};\n\n\tutilities.trimTrailingNewlines = function trimTrailingNewlines(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn value.replace(/[ \\t\\r\\n]+$/, \"\");\n\t};\n\n\tutilities.replaceNonBreakingSpaces = function replaceNonBreakingSpaces(value) {\n\t\treturn typeof value === \"string\" ? value.replace(/ /gi, \" \") : null;\n\t};\n\n\tutilities.indentText = function indentText(value, amount, indentation, clearEmptyLines) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tclearEmptyLines = utilities.parseBoolean(clearEmptyLines, true);\n\n\t\tamount = utilities.parseInteger(amount, 1);\n\n\t\tif(amount < 0) {\n\t\t\tamount = 0;\n\t\t}\n\n\t\tindentation = typeof indentation === \"string\" ? indentation : \"\\t\";\n\n\t\tvar totalIndentation = \"\";\n\n\t\tfor(var i = 0; i < amount; i++) {\n\t\t\ttotalIndentation += indentation;\n\t\t}\n\n\t\tvar line = null;\n\t\tvar lines = value.split(/\\r\\n?|\\n/g);\n\t\tvar indentedParagraph = \"\";\n\n\t\tfor(var i = 0; i < lines.length; i++) {\n\t\t\tline = lines[i];\n\n\t\t\tindentedParagraph += (utilities.isEmptyString(line) && clearEmptyLines ? \"\" : totalIndentation + line) + ((i < lines.length - 1) ? \"\\n\" : \"\");\n\t\t}\n\n\t\treturn indentedParagraph;\n\t};\n\n\tutilities.trimLeadingZeroes = function trimLeadingZeroes(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tif(value.length === 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\t\telse if(formattedValue.match(/^[0]+$/)) {\n\t\t\treturn \"0\";\n\t\t}\n\n\t\treturn formattedValue.replace(/^0+/, \"\");\n\t};\n\n\tutilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) {\n\t\tif(utilities.isInvalid(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.toString();\n\t\texpectedLength = utilities.parseInteger(expectedLength);\n\n\t\tif(utilities.isInvalidNumber(expectedLength) || expectedLength < 0) {\n\t\t\treturn value;\n\t\t}\n\n\t\tvar numberOfZeroes = expectedLength - value.length;\n\n\t\tfor(var i = 0; i < numberOfZeroes; i++) {\n\t\t\tvalue = \"0\" + value;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.toString = function toString(value) {\n\t\tif(value === undefined) {\n\t\t\treturn \"undefined\";\n\t\t}\n\t\telse if(value === null) {\n\t\t\treturn \"null\";\n\t\t}\n\t\telse if(typeof value === \"string\") {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value === Infinity) {\n\t\t\treturn \"Infinity\";\n\t\t}\n\t\telse if(value === -Infinity) {\n\t\t\treturn \"-Infinity\";\n\t\t}\n\t\telse if(typeof value === \"number\" && isNaN(value)) {\n\t\t\treturn \"NaN\";\n\t\t}\n\t\telse if(utilities.isDate(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(utilities.isRegularExpression(value)) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn \"/\" + value.source + \"/\" + flags;\n\t\t}\n\t\telse if(utilities.isFunction(value)) {\n\t\t\treturn value.toString();\n\t\t}\n\t\telse if(utilities.isError(value)) {\n\t\t\tvar error = { message: value.message };\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\terror[attribute] = value[attribute];\n\t\t\t}\n\n\t\t\treturn JSON.stringify(error);\n\t\t}\n\n\t\treturn JSON.stringify(value);\n\t};\n\n\tutilities.compareDates = function compareDates(a, b) {\n\t\ta = utilities.parseDate(a);\n\t\tb = utilities.parseDate(b);\n\n\t\tif(a === null && b === null) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tif(a === null) {\n\t\t\treturn -1;\n\t\t}\n\t\telse if(b === null) {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn a.getTime() - b.getTime();\n\t};\n\n\tutilities.compareCasePercentage = function compareCasePercentage(value) {\n\t\tif(utilities.isEmptyString(value)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar c = null;\n\t\tvar upper = 0;\n\t\tvar lower = 0;\n\t\tvar lowerA = \"a\".charCodeAt();\n\t\tvar lowerZ = \"z\".charCodeAt();\n\t\tvar upperA = \"A\".charCodeAt();\n\t\tvar upperZ = \"Z\".charCodeAt();\n\n\t\tfor(var i = 0; i < value.length; i++) {\n\t\t\tc = value.charCodeAt(i);\n\n\t\t\tif(c >= lowerA && c <= lowerZ) {\n\t\t\t\tlower++;\n\t\t\t}\n\t\t\telse if(c >= upperA && c <= upperZ) {\n\t\t\t\tupper++;\n\t\t\t}\n\t\t}\n\n\t\treturn upper - lower;\n\t};\n\n\tutilities.reverseString = function reverseString(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value.replace(\n\t\t\t/([\\0-\\u02FF\\u0370-\\u1AAF\\u1B00-\\u1DBF\\u1E00-\\u20CF\\u2100-\\uD7FF\\uE000-\\uFE1F\\uFE30-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])([\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F]+)/g,\n\t\t\tfunction($0, $1, $2) {\n\t\t\t\treturn utilities.reverseString($2) + $1;\n\t\t\t}\n\t\t).replace(/([\\uD800-\\uDBFF])([\\uDC00-\\uDFFF])/g, \"$2$1\");\n\n\t\tvar reverse = \"\";\n\n\t\tfor(var i = value.length - 1; i >= 0; i--) {\n\t\t\treverse += value[i];\n\t\t}\n\n\t\treturn reverse;\n\t};\n\n\tutilities.createError = function createError(message, status) {\n\t\tvar error = new Error(message);\n\t\terror.status = utilities.parseInteger(status, 500);\n\t\treturn error;\n\t};\n\n\tutilities.clone = function clone(value) {\n\t\tif(!utilities.isObject(value)) {\n\t\t\treturn value;\n\t\t}\n\t\telse if(value instanceof Boolean) {\n\t\t\treturn new Boolean(value.valueOf());\n\t\t}\n\t\telse if(value instanceof Date) {\n\t\t\tvar copy = new Date();\n\t\t\tcopy.setTime(value.getTime());\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Array) {\n\t\t\tvar copy = [];\n\n\t\t\tfor(var i = 0, length = value.length; i < length; i++) {\n\t\t\t\tcopy[i] = utilities.clone(value[i]);\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\t\telse if(value instanceof Set) {\n\t\t\treturn new Set(value);\n\t\t}\n\t\telse if(value instanceof Map) {\n\t\t\treturn new Map(value);\n\t\t}\n\t\telse if(value instanceof RegExp) {\n\t\t\tvar flags = \"\";\n\n\t\t\tfor(var flag in regExpFlags) {\n\t\t\t\tif(value[flag]) {\n\t\t\t\t\tflags += regExpFlags[flag]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new RegExp(value.source, flags);\n\t\t}\n\t\telse if(typeof Buffer !== \"undefined\" && value instanceof Buffer) {\n\t\t\treturn Buffer.from instanceof Function ? Buffer.from(value) : new Buffer(value);\n\t\t}\n\t\telse if(value instanceof Object) {\n\t\t\tvar copy = null;\n\n\t\t\tif(value instanceof Error) {\n\t\t\t\tcopy = new Error(value.message);\n\n\t\t\t\tcopy.stack = utilities.clone(value.stack);\n\n\t\t\t\tvar properties = Object.keys(value);\n\n\t\t\t\tfor(var i = 0; i < properties.length; i++) {\n\t\t\t\t\tcopy[properties[i]] = utilities.clone(value[properties[i]]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcopy = { };\n\t\t\t}\n\n\t\t\tfor(var attribute in value) {\n\t\t\t\tif(Object.prototype.hasOwnProperty.call(value, attribute)) {\n\t\t\t\t\tcopy[attribute] = utilities.clone(value[attribute]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn copy;\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tutilities.merge = function merge(a, b, copy, deepMerge) {\n\t\tif(!utilities.isObject(a) || Array.isArray(a)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar newObject = null;\n\n\t\tcopy = utilities.parseBoolean(copy, true);\n\n\t\tif(copy) {\n\t\t\tnewObject = utilities.clone(a);\n\t\t}\n\t\telse {\n\t\t\tnewObject = a;\n\t\t}\n\n\t\tif(!utilities.isObject(a) || Array.isArray(a) || !utilities.isObject(b) || Array.isArray(b)) {\n\t\t\treturn newObject;\n\t\t}\n\n\t\tvar attribute = null;\n\t\tvar value = null;\n\t\tvar newValue = null;\n\t\tvar attributes = Object.keys(b);\n\n\t\tdeepMerge = utilities.parseBoolean(deepMerge, true);\n\n\t\tfor(var i = 0; i < attributes.length; i++) {\n\t\t\tattribute = attributes[i];\n\t\t\tvalue = newObject[attribute];\n\n\t\t\tif(copy) {\n\t\t\t\tnewValue = utilities.clone(b[attribute]);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewValue = b[attribute];\n\t\t\t}\n\n\t\t\tif(deepMerge && utilities.isObject(value) && !Array.isArray(value) && utilities.isObject(newValue) && !Array.isArray(newValue)) {\n\t\t\t\tnewObject[attribute] = utilities.merge(value, newValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewObject[attribute] = newValue;\n\t\t\t}\n\t\t}\n\n\t\treturn newObject;\n\t};\n\n\tutilities.getFileName = function getFileName(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(i + 1, filePath.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn filePath;\n\t};\n\n\tutilities.getFilePath = function getFilePath(filePath) {\n\t\tif(typeof filePath !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfilePath = filePath.trim();\n\n\t\tfor(var i = filePath.length - 1; i >= 0; i--) {\n\t\t\tif(filePath[i] === \"/\" || filePath[i] === \"\\\\\") {\n\t\t\t\treturn filePath.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.getFileExtension = function getFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(i + 1, fileName.length).trim();\n\t\t\t}\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\tutilities.fileHasExtension = function fileHasExtension(fileName, extension) {\n\t\tif(utilities.isEmptyString(fileName) || utilities.isEmptyString(extension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar actualFileExtension = utilities.getFileExtension(fileName);\n\n\t\tif(utilities.isEmptyString(actualFileExtension)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn actualFileExtension.toLowerCase() === extension.trim().toLowerCase();\n\t};\n\n\tutilities.reverseFileExtension = function reverseFileExtension(fileName) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = fileName.trim();\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\treturn fileName.substring(0, i) + \".\" + utilities.reverseString(fileName.substring(i + 1, fileName.length));\n\t\t\t}\n\t\t}\n\n\t\treturn fileName;\n\t};\n\n\tutilities.truncateFileName = function truncateFileName(fileName, maxLength) {\n\t\tif(typeof fileName !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tfileName = utilities.getFileName(fileName);\n\n\t\tif(utilities.isEmptyString(fileName)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tmaxLength = utilities.parseInteger(maxLength);\n\n\t\tif(utilities.isInvalidNumber(maxLength) || maxLength < 0) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tif(maxLength === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif(fileName.length <= maxLength) {\n\t\t\treturn fileName;\n\t\t}\n\n\t\tvar extension = \"\";\n\t\tvar originalFileName = fileName;\n\n\t\tfor(var i = fileName.length - 1; i >= 0; i--) {\n\t\t\tif(fileName[i] === \".\") {\n\t\t\t\textension = fileName.substring(i + 1, fileName.length);\n\t\t\t\toriginalFileName = fileName.substring(0, i);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif(maxLength - (extension.length + (extension.length > 0 ? 1 : 0)) < 1) {\n\t\t\treturn originalFileName.substring(0, maxLength);\n\t\t}\n\n\t\treturn originalFileName.substring(0, maxLength - extension.length - (extension.length > 0 ? 1 : 0)) + (extension.length > 0 ? \".\" + extension : \"\");\n\t};\n\n\tutilities.prependSlash = function prependSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[0] !== \"/\" && formattedValue[0] !== \"\\\\\") {\n\t\t\tformattedValue = \"/\" + formattedValue;\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.appendSlash = function appendSlash(value) {\n\t\tif(typeof value !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar formattedValue = value.trim();\n\n\t\tif(formattedValue.length === 0) {\n\t\t\treturn formattedValue;\n\t\t}\n\n\t\tif(formattedValue[formattedValue.length - 1] !== \"/\" && formattedValue[formattedValue.length - 1] !== \"\\\\\") {\n\t\t\tformattedValue += \"/\";\n\t\t}\n\n\t\treturn formattedValue;\n\t};\n\n\tutilities.joinPaths = function joinPaths(base, path) {\n\t\tvar formattedBase = typeof base === \"string\" ? base.trim().replace(/[\\/\\\\]+$/, \"\") : null;\n\t\tvar formattedPath = typeof path === \"string\" ? path.trim().replace(/^[\\/\\\\]+/, \"\") : null;\n\t\tvar newPath = \"\";\n\n\t\tif(utilities.isNonEmptyString(formattedBase)) {\n\t\t\tnewPath += formattedBase;\n\n\t\t\tif(utilities.isNonEmptyString(formattedPath)) {\n\t\t\t\tnewPath += \"/\";\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.isNonEmptyString(formattedPath)) {\n\t\t\tnewPath += formattedPath;\n\t\t}\n\n\t\treturn newPath;\n\t};\n\n\tutilities.createQueryString = function createQueryString(value, includeQuestionMark) {\n\t\tif(!utilities.isObjectStrict(value)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar parameters = Object.keys(value).map(function(key) {\n\t\t\treturn encodeURIComponent(key) + \"=\" + encodeURIComponent(utilities.toString(value[key]));\n\t\t}).join(\"&\");\n\n\t\tif(parameters.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\treturn (utilities.parseBoolean(includeQuestionMark, false) ? \"?\" : \"\") + parameters;\n\t};\n\n\tutilities.createRange = function createRange(start, end) {\n\t\tvar formattedStart = utilities.parseInteger(start);\n\t\tvar formattedEnd = utilities.parseInteger(end);\n\n\t\tif(arguments.length === 1) {\n\t\t\tformattedEnd = formattedStart;\n\t\t\tformattedStart = 0;\n\t\t}\n\n\t\tif(utilities.isInvalidNumber(formattedStart) || utilities.isInvalidNumber(formattedEnd) || formattedStart > formattedEnd) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar range = [];\n\n\t\tfor(var i = formattedStart; i <= formattedEnd; i++) {\n\t\t\trange.push(i);\n\t\t}\n\n\t\treturn range;\n\t};\n\n\tutilities.futureMonths = function futureMonths(date, prependZero) {\n\t\tdate = utilities.parseDate(date);\n\n\t\tif(date === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar currentDate = new Date();\n\t\tvar month = 0;\n\n\t\tif(date.getFullYear() === currentDate.getFullYear()) {\n\t\t\tmonth = currentDate.getMonth();\n\t\t}\n\n\t\tvar months = [];\n\n\t\tprependZero = utilities.parseBoolean(prependZero, false);\n\n\t\tfor(var i = 0; i < 12; i++) {\n\t\t\tif(i >= month) {\n\t\t\t\tif(prependZero) {\n\t\t\t\t\tmonths.push((i <= 8 ? \"0\" : \"\") + (i + 1));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmonths.push(i + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn months;\n\t};\n\n\tutilities.visibleElements = function visibleElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar visibleElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isVisible(elements[i])) {\n\t\t\t\tvisibleElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn visibleElements;\n\t};\n\n\tutilities.hiddenElements = function hiddenElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar hiddenElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isHidden(elements[i])) {\n\t\t\t\thiddenElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn hiddenElements;\n\t};\n\n\tutilities.enabledElements = function enabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar enabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isEnabled(elements[i])) {\n\t\t\t\tenabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn enabledElements;\n\t};\n\n\tutilities.disabledElements = function disabledElements(elements) {\n\t\tif(!Array.isArray(elements)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar disabledElements = [];\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\tif(utilities.isDisabled(elements[i])) {\n\t\t\t\tdisabledElements.push(elements[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn disabledElements;\n\t};\n\n\tutilities.elementsWithAttribute = function elementsWithAttribute(elements, attribute, hasAttribute) {\n\t\tif(!Array.isArray(elements) || utilities.isEmptyString(attribute)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tvar element = null;\n\t\tvar filteredElements = [];\n\n\t\tattribute = attribute.trim();\n\t\thasAttribute = utilities.parseBoolean(hasAttribute, true);\n\n\t\tfor(var i = 0; i < elements.length; i++) {\n\t\t\telement = elements[i];\n\n\t\t\tif(!utilities.isObject(element)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(utilities.isInvalid(elements[i][attribute])) {\n\t\t\t\tif(!hasAttribute) {\n\t\t\t\t\tfilteredElements.push(element);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(hasAttribute) {\n\t\t\t\t\tfilteredElements.push(elements[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn filteredElements;\n\t};\n\n\tutilities.elementsWithoutAttribute = function elementsWithoutAttribute(elements, attribute) {\n\t\treturn utilities.elementsWithAttribute(elements, attribute, false);\n\t};\n\n\tutilities.matchAttribute = function matchAttribute(element, attribute, value) {\n\t\tif(!utilities.isObject(element)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(utilities.isEmptyString(attribute)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn element[attribute.trim()] === value;\n\t};\n\n\tutilities.generateVersions = function generateVersions(version, prefix, suffix) {\n\t\tversion = utilities.parseVersion(version);\n\n\t\tif(version === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tprefix = utilities.trimString(prefix);\n\t\tsuffix = utilities.trimString(suffix);\n\n\t\tvar versions = [];\n\t\tvar value = null;\n\n\t\tfor(var i = 0; i < version.length; i++) {\n\t\t\tvalue = \"\";\n\n\t\t\tif(utilities.isNonEmptyString(prefix)) {\n\t\t\t\tvalue += prefix;\n\t\t\t}\n\n\t\t\tfor(var j = 0; j <= i; j++) {\n\t\t\t\tif(j > 0) {\n\t\t\t\t\tvalue += \"_\";\n\t\t\t\t}\n\n\t\t\t\tvalue += version[j];\n\t\t\t}\n\n\t\t\tif(utilities.isNonEmptyString(suffix)) {\n\t\t\t\tvalue += suffix;\n\t\t\t}\n\n\t\t\tversions.push(value);\n\t\t}\n\n\t\treturn versions;\n\t};\n\n\tutilities.parseVersion = function parseVersion(value, trimTrailingZeroes) {\n\t\tvar formattedValue = utilities.isValidNumber(value) ? value.toString() : value;\n\n\t\tif(typeof formattedValue !== \"string\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar version = [];\n\t\tvar versionData = formattedValue.match(/[^. \\t]+/g);\n\n\t\tif(versionData === null || versionData.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar part = null;\n\n\t\tfor(var i = 0; i < versionData.length; i++) {\n\t\t\tif(validator.isInt(versionData[i])) {\n\t\t\t\tpart = utilities.parseInteger(versionData[i]);\n\n\t\t\t\tif(utilities.isInvalidNumber(part) || part < 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tversion.push(part.toString());\n\t\t\t}\n\t\t\telse {\n\t\t\t\tversion.push(versionData[i]);\n\t\t\t}\n\t\t}\n\n\t\tif(utilities.parseBoolean(trimTrailingZeroes, false)) {\n\t\t\twhile(true) {\n\t\t\t\tif(version.length <= 1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif(version[version.length - 1] === \"0\") {\n\t\t\t\t\tversion.pop();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn version.length === 0 ? null : version;\n\t};\n\n\tutilities.compareVersions = function compareVersions(v1, v2, caseSensitive, throwErrors) {\n\t\tcaseSensitive = utilities.parseBoolean(caseSensitive, false);\n\t\tthrowErrors = utilities.parseBoolean(throwErrors, false);\n\n\t\tv1 = utilities.parseVersion(v1);\n\n\t\tif(v1 === null) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Cannot compare invalid or empty first version.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tv2 = utilities.parseVersion(v2);\n\n\t\tif(v2 === null) {\n\t\t\tif(throwErrors) {\n\t\t\t\tthrow new Error(\"Cannot compare invalid or empty second version.\");\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvar index = 0;\n\n\t\twhile(true) {\n\t\t\tif(index >= v1.length) {\n\t\t\t\tif(v1.length === v2.length) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\tfor(var i = index; i < v2.length; i++) {\n\t\t\t\t\tif(v2[i] !== \"0\") {\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tif(index >= v2.length) {\n\t\t\t\tfor(var i = index; i < v1.length; i++) {\n\t\t\t\t\tif(v1[i] !== \"0\") {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tvar formattedA = utilities.parseInteger(v1[index]);\n\t\t\tvar formattedB = utilities.parseInteger(v2[index]);\n\n\t\t\tif(utilities.isInvalidNumber(formattedA)) {\n\t\t\t\tformattedA = caseSensitive ? v1[index] : v1[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(utilities.isInvalidNumber(formattedB)) {\n\t\t\t\tformattedB = caseSensitive ? v2[index] : v2[index].toUpperCase();\n\t\t\t}\n\n\t\t\tif(Number.isInteger(formattedA)) {\n\t\t\t\tif(!Number.isInteger(formattedB)) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(Number.isInteger(formattedB)) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(formattedA > formattedB) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse if(formattedA < formattedB) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tindex++;\n\t\t}\n\t};\n\n\treturn utilities;\n\n}));\n\n//# sourceMappingURL=extra-utilities.js.map\n"]} \ No newline at end of file diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/extra-utilities.js.html b/docs/extra-utilities.js.html new file mode 100644 index 0000000..39f69aa --- /dev/null +++ b/docs/extra-utilities.js.html @@ -0,0 +1,3747 @@ + + + + + + extra-utilities.js - Documentation + + + + + + + + + + + + + + + + + + + +
+ +

extra-utilities.js

+ + + + + + + +
+
+
"use strict";
+
+if(typeof require !== "undefined") {
+	if(typeof changeCase === "undefined") {
+		global.changeCase = require("change-case-bundled");
+	}
+}
+
+/**
+ * @module utilities
+ */
+var utilities = { };
+
+var regExpFlags = {
+	global: "g",
+	multiline: "m",
+	ignoreCase: "i",
+	sticky: "y",
+	unicode: "u"
+};
+
+var formatTypes = ["boolean", "bool", "integer", "int", "float", "number", "string", "object", "array", "date", "regex", "regexp", "regularexpression", "function", "func"];
+
+var stringCaseFunctions = {
+	camel: changeCase.camelCase,
+	capital: changeCase.capitalCase,
+	constant: changeCase.constantCase,
+	dot: changeCase.dotCase,
+	header: changeCase.headerCase,
+	lower: changeCase.lowerCase,
+	lowerFirst: changeCase.lowerCaseFirst,
+	no: changeCase.noCase,
+	param: changeCase.paramCase,
+	pascal: changeCase.pascalCase,
+	path: changeCase.pathCase,
+	sentence: changeCase.sentenceCase,
+	snake: changeCase.snakeCase,
+	sponge: changeCase.spongeCase,
+	swap: changeCase.swapCase,
+	title: changeCase.titleCase,
+	upper: changeCase.upperCase,
+	upperFirst: changeCase.upperCaseFirst
+};
+
+/**
+ * Checks that the specified value is not null or undefined.
+ *
+ * @function isValid
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is not null or undefined, otherwise false.
+ * @see {@link module:utilities.isInvalid|isInvalid}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isValid(42)); // true
+ * console.log(utilities.isValid(null)); // false
+ */
+utilities.isValid = function isValid(value) {
+	return value !== undefined && value !== null;
+};
+
+/**
+ * Checks if the specified value is null or undefined.
+ *
+ * @function isInvalid
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is null or undefined, otherwise false.
+ * @see {@link module:utilities.isValid|isValid}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isInvalid(69)); // false
+ * console.log(utilities.isInvalid(undefined)); // true
+ */
+utilities.isInvalid = function isInvalid(value) {
+	return value === undefined || value === null;
+};
+
+/**
+ * Checks if the specified value is a boolean.
+ *
+ * @function isBoolean
+ * @param {any} value - The value to check.
+ * @param {boolean} [allowObjects=false] - Will allow Boolean objects to be treated as valid values.
+ * @returns {boolean} A value of true if the specified value is a boolean, otherwise false.
+ * @see {@link module:utilities.parseBoolean|parseBoolean}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isBoolean(false)); // true
+ * console.log(utilities.isBoolean(8675309)); // false
+ * console.log(utilities.isBoolean(new Boolean(true))); // false
+ * console.log(utilities.isBoolean(new Boolean(false), true)); // true
+ */
+utilities.isBoolean = function isBoolean(value, allowObjects) {
+	return value === true || value === false || (!!allowObjects && value instanceof Boolean);
+};
+
+/**
+ * Checks that that the specified value is a valid number.
+ * Values of NaN, +/- Infinity and Number objects are not considered to be valid numbers.
+ *
+ * @function isValidNumber
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is a valid number, otherwise false.
+ * @see {@link module:utilities.isInvalidNumber|isInvalidNumber}
+ * @see {@link module:utilities.parseInteger|parseInteger}
+ * @see {@link module:utilities.parseFloat|parseFloat}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isValidNumber(1337)); // true
+ * console.log(utilities.isValidNumber(-3.141592654)); // true
+ * console.log(utilities.isValidNumber("32767")); // false
+ * console.log(utilities.isValidNumber(new Number(65534))); // false
+ * console.log(utilities.isValidNumber(NaN)); // false
+ * console.log(utilities.isValidNumber(-Infinity)); // false
+ */
+utilities.isValidNumber = function isValidNumber(value) {
+	return typeof value === "number" && !isNaN(value) && value !== -Infinity && value !== Infinity;
+};
+
+/**
+ * Checks if the specified value is not a valid number.
+ * Values of NaN, +/- Infinity and Number objects are also not considered to be valid numbers.
+ *
+ * @function isInvalidNumber
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is not a valid number, otherwise false.
+ * @see {@link module:utilities.isValidNumber|isValidNumber}
+ * @see {@link module:utilities.parseInteger|parseInteger}
+ * @see {@link module:utilities.parseFloat|parseFloat}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isInvalidNumber(7331)); // false
+ * console.log(utilities.isInvalidNumber(-2.718281828459045)); // false
+ * console.log(utilities.isInvalidNumber("7")); // true
+ * console.log(utilities.isInvalidNumber(new Number(65534))); // true
+ * console.log(utilities.isInvalidNumber(NaN)); // true
+ * console.log(utilities.isInvalidNumber(Infinity)); // true
+ */
+utilities.isInvalidNumber = function isInvalidNumber(value) {
+	return typeof value !== "number" || isNaN(value) || value === -Infinity || value === Infinity;
+};
+
+/**
+ * Checks if the specified value is an integer either represented in a number type, string type or optionally a Number object.
+ *
+ * @function isInteger
+ * @param {any} value - The value to check.
+ * @param {boolean} [allowObjects=true] - Will allow Number objects to be treated as valid values.
+ * @returns {boolean} A value of true if the specified value is an integer, otherwise false.
+ * @see {@link module:utilities.isValidNumber|isValidNumber}
+ * @see {@link module:utilities.isInvalidNumber|isInvalidNumber}
+ * @see {@link module:utilities.isFloat|isFloat}
+ * @see {@link module:utilities.parseInteger|parseInteger}
+ * @see {@link module:utilities.parseFloat|parseFloat}
+ * @since 1.3.7
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isInteger(7)); // true
+ * console.log(utilities.isInteger(133.7)); // false
+ * console.log(utilities.isInteger("420")); // true
+ * console.log(utilities.isInteger("6.9")); // false
+ * console.log(utilities.isInteger(new Number(64))); // true
+ * console.log(utilities.isInteger(new Number(3.2))); // false
+ * console.log(utilities.isInteger(null)); // false
+ */
+utilities.isInteger = function isInteger(value, allowObjects) {
+	if(Number.isInteger(value)) {
+		return true;
+	}
+
+	if(value instanceof Number && utilities.parseBoolean(allowObjects, true)) {
+		return Number.isInteger(value.valueOf());
+	}
+
+	if(typeof value !== "string") {
+		return false;
+	}
+
+	return !!value.match(/^([+-]?[1-9][0-9]*|0)$/);
+};
+
+/**
+ * Checks if the specified value is a floating point number either represented in a number type, string type or optionally a Number object.
+ * Integer values are also considered to be floating point numbers.
+ *
+ * @function isFloat
+ * @param {any} value - The value to check.
+ * @param {boolean} [allowObjects=true] - Will allow Number objects to be treated as valid values.
+ * @returns {boolean} A value of true if the specified value is a floating point number, otherwise false.
+ * @see {@link module:utilities.isValidNumber|isValidNumber}
+ * @see {@link module:utilities.isInvalidNumber|isInvalidNumber}
+ * @see {@link module:utilities.isInteger|isInteger}
+ * @see {@link module:utilities.parseInteger|parseInteger}
+ * @see {@link module:utilities.parseFloat|parseFloat}
+ * @since 1.3.7
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isInteger(7)); // true
+ * console.log(utilities.isInteger(133.7)); // true
+ * console.log(utilities.isInteger("420")); // true
+ * console.log(utilities.isInteger("6.9")); // true
+ * console.log(utilities.isInteger(new Number(64))); // true
+ * console.log(utilities.isInteger(new Number(3.2))); // true
+ * console.log(utilities.isInteger(null)); // false
+ */
+utilities.isFloat =  function isFloat(value, allowObjects) {
+	if(typeof value === "number") {
+		return !isNaN(value) && isFinite(value);
+	}
+
+	if(value instanceof Number && utilities.parseBoolean(allowObjects, true)) {
+		return true;
+	}
+
+	if(typeof value !== "string") {
+		return false;
+	}
+
+	return !!value.match(/^([+-]?(((([1-9][0-9]*|0)?\.)[0-9]+)|([1-9][0-9]*|0)))$/);
+};
+
+/**
+ * Checks if the specified value is an empty string.
+ * By default this will also trim strings and consider values which only contain whitespace, as well as non-string values to also be empty strings.
+ *
+ * @function isEmptyString
+ * @param {any} value - The value to check.
+ * @param {boolean} [trim=true] - Determines if the value should be trimmed before checking if it is empty.
+ * @returns {boolean} A value of true if the specified value is not a string, or is a string and is empty or only contains whitespace characters if trim is set to true.
+ * @see {@link module:utilities.isNonEmptyString|isNonEmptyString}
+ * @see {@link module:utilities.trimString|trimString}
+ * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString}
+ * @see {@link module:utilities.trimWhitespace|trimWhitespace}
+ * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines}
+ * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isEmptyString("")); // true
+ * console.log(utilities.isEmptyString("\t")); // true
+ * console.log(utilities.isEmptyString("Door stuck!")); // false
+ * console.log(utilities.isEmptyString("   ", false)); // false
+ * console.log(utilities.isEmptyString(null)); // true
+ * console.log(utilities.isEmptyString([])); // true
+ * console.log(utilities.isEmptyString(NaN)); // true
+ */
+utilities.isEmptyString = function isEmptyString(value, trim) {
+	return typeof value !== "string" || (utilities.parseBoolean(trim, true) ? value.trim().length === 0 : value.length === 0);
+};
+
+/**
+ * Checks if the specified value is a non-empty string.
+ * By default this will also trim strings and consider values which only contain whitespace to be empty strings.
+ *
+ * @function isNonEmptyString
+ * @param {any} value - The value to check.
+ * @param {boolean} [trim=true] - Determines if the value should be trimmed before checking if it is not empty.
+ * @returns {boolean} A value of false if the specified value is not a string, or is a string and is empty or only contains whitespace characters if trim is set to true.
+ * @see {@link module:utilities.isEmptyString|isEmptyString}
+ * @see {@link module:utilities.trimString|trimString}
+ * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString}
+ * @see {@link module:utilities.trimWhitespace|trimWhitespace}
+ * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines}
+ * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isNonEmptyString("")); // false
+ * console.log(utilities.isNonEmptyString("\t")); // false
+ * console.log(utilities.isNonEmptyString("Door stuck!")); // true
+ * console.log(utilities.isNonEmptyString("   ", false)); // true
+ * console.log(utilities.isNonEmptyString(null)); // false
+ * console.log(utilities.isNonEmptyString([])); // false
+ * console.log(utilities.isNonEmptyString(NaN)); // false
+ */
+utilities.isNonEmptyString = function isNonEmptyString(value, trim) {
+	return typeof value === "string" && (utilities.parseBoolean(trim, true) ? value.trim().length !== 0 : value.length !== 0);
+};
+
+/**
+ * Checks if the specified value is an object.
+ * Functions and values of null are not considered to be real objects.
+ * Any object which inherits from object will yield a result of true unless strict is set to true.
+ *
+ * @function isObject
+ * @param {any} value - The value to check.
+ * @param {boolean} [strict=false] - Only consider values which have Object for a constructor as objects when checking the value.
+ * @returns {boolean} A value of true if the specified value is an object, otherwise false if it inhertis from object and strict is set to true, or it is any other value type.
+ * @see {@link module:utilities.isObjectStrict|isObjectStrict}
+ * @see {@link module:utilities.isEmptyObject|isEmptyObject}
+ * @see {@link module:utilities.isNonEmptyObject|isNonEmptyObject}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isObject({ please: "ignore" })); // true
+ * console.log(utilities.isObject(new Object())); // true
+ * console.log(utilities.isObject([1, 2, 3])); // true
+ * console.log(utilities.isObject(new Date())); // true
+ * console.log(utilities.isObject(new Date(), true)); // false
+ * console.log(utilities.isObject(function() { })); // false
+ * console.log(utilities.isObject(null)); // false
+ */
+utilities.isObject = function isObject(value, strict) {
+	return value !== undefined && (strict ? value !== null && value.constructor === Object : value instanceof Object && !(value instanceof Function));
+};
+
+/**
+ * Checks if the specified value is a strict object by checking that the value's constructor is Object.
+ * Functions and values of null are not considered to be strict objects.
+ * Any object which inherits from object will yield a result of false.
+ *
+ * @function isObjectStrict
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is an object and has Object for a constructor, otherwise false for any other value.
+ * @see {@link module:utilities.isObjectStrict|isObjectStrict}
+ * @see {@link module:utilities.isEmptyObject|isEmptyObject}
+ * @see {@link module:utilities.isNonEmptyObject|isNonEmptyObject}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isObjectStrict({ foo: "bar" })); // true
+ * console.log(utilities.isObjectStrict(new Object())); // true
+ * console.log(utilities.isObjectStrict(["a", "b", "c"])); // false
+ * console.log(utilities.isObjectStrict(new Error("?"))); // false
+ * console.log(utilities.isObjectStrict(function() { })); // false
+ * console.log(utilities.isObjectStrict(null)); // false
+ */
+utilities.isObjectStrict = function isObjectStrict(value) {
+	return value !== undefined && value !== null && value.constructor === Object;
+};
+
+/**
+ * Checks if the specified value is an object and does not contain any enumerable properties.
+ * Values which are not strict objects regardless of how many enumerable properties they have will always result in a value of false.
+ *
+ * @function isEmptyObject
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is a strict object with no enumerable properties, otherwise false for any other value.
+ * @see {@link module:utilities.isObject|isObject}
+ * @see {@link module:utilities.isObjectStrict|isObjectStrict}
+ * @see {@link module:utilities.isNonEmptyObject|isNonEmptyObject}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isEmptyObject({ })); // true
+ * console.log(utilities.isEmptyObject(new Object())); // true
+ * console.log(utilities.isEmptyObject({ example: "data" })); // false
+ * console.log(utilities.isEmptyObject(new Map())); // false
+ * console.log(utilities.isEmptyObject(new Error())); // false
+ * console.log(utilities.isEmptyObject(function() { })); // false
+ * console.log(utilities.isEmptyObject(null)); // false
+ */
+utilities.isEmptyObject = function isEmptyObject(value) {
+	return value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length === 0;
+};
+
+/**
+ * Checks if the specified value is an object and contains at least one enumerable property.
+ * Values which are not strict objects regardless of how many properties they have will always result in a value of false.
+ *
+ * @function isNonEmptyObject
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is a strict object with at least one enumerable property, otherwise false for any other value or strict object with no enumerable properties.
+ * @see {@link module:utilities.isObject|isObject}
+ * @see {@link module:utilities.isObjectStrict|isObjectStrict}
+ * @see {@link module:utilities.isEmptyObject|isEmptyObject}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isEmptyObject({ })); // false
+ * console.log(utilities.isEmptyObject(new Object())); // false
+ * console.log(utilities.isEmptyObject({ example: "data" })); // true
+ * console.log(utilities.isEmptyObject(new Map())); // false
+ * console.log(utilities.isEmptyObject(new Error())); // false
+ * console.log(utilities.isEmptyObject(function() { })); // false
+ * console.log(utilities.isEmptyObject(null)); // false
+ */
+utilities.isNonEmptyObject = function isNonEmptyObject(value) {
+	return value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length !== 0;
+};
+
+/**
+ * Checks if the specified value is an array and contains no items.
+ * Values which are not arrays will always result in a value of false.
+ *
+ * @function isEmptyArray
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value if true if the specified value is an array and does not contain any items, otherwise false for any other value.
+ * @see {@link module:utilities.isNonEmptyArray|isNonEmptyArray}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isEmptyArray([])); // true
+ * console.log(utilities.isEmptyArray(new Array())); // true
+ * console.log(utilities.isEmptyArray([null])); // false
+ * console.log(utilities.isEmptyArray({ })); // false
+ * console.log(utilities.isEmptyArray(null)); // false
+ */
+utilities.isEmptyArray = function isEmptyArray(value) {
+	return Array.isArray(value) ? value.length === 0 : true;
+};
+
+/**
+ * Checks if the specified value is an array and contains at least one item.
+ * Values which are not arrays will always result in a value of false.
+ *
+ * @function isNonEmptyArray
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value if true if the specified value is an array and contains at least one item, otherwise false for any other value.
+ * @see {@link module:utilities.isEmptyArray|isEmptyArray}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isEmptyArray([])); // false
+ * console.log(utilities.isEmptyArray(new Array())); // false
+ * console.log(utilities.isEmptyArray([null])); // true
+ * console.log(utilities.isEmptyArray([4, 2, 0])); // true
+ * console.log(utilities.isEmptyArray({ })); // false
+ * console.log(utilities.isEmptyArray(null)); // false
+ */
+utilities.isNonEmptyArray = function isNonEmptyArray(value) {
+	return Array.isArray(value) && value.length !== 0;
+};
+
+/**
+ * Checks if the specified value is an instance of the Date object.
+ *
+ * @function isDate
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is a Date object instance, otherwise false for any other value.
+ * @see {@link module:utilities.parseDate|parseDate}
+ * @see {@link module:utilities.compareDates|compateDates}
+ * @since 1.1.1
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isDate(new Date())); // true
+ * console.log(utilities.isDate("June 18")); // false
+ * console.log(utilities.isDate(null)); // false
+ */
+utilities.isDate = function isDate(value) {
+	return value instanceof Date;
+};
+
+/**
+ * Checks if the specified value is an instance of the Error object.
+ *
+ * @function isError
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is an Error object instance, otherwise false for any other value.
+ * @since 1.2.2
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isError(new Error("Oops."))); // true
+ * console.log(utilities.isError(new SyntaxError("Unknown!"))); // true
+ * console.log(utilities.isError(new DOMException("System failure.", "AbortError"))); // true
+ * console.log(utilities.isError({ message: "fake" })); // false
+ * console.log(utilities.isError(null)); // false
+ */
+utilities.isError = function isError(value) {
+	return value instanceof Error;
+};
+
+/**
+ * Checks if the specified value is an instance of the RegExp object.
+ *
+ * @function isRegularExpression
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is a RegExp object instance, otherwise false for any other value.
+ * @see {@link module:utilities.parseRegularExpression|parseRegularExpression}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isRegularExpression(/te|st/gmi)); // true
+ * console.log(utilities.isRegularExpression(new RegExp("https?"))); // true
+ * console.log(utilities.isRegularExpression("/hi/")); // false
+ * console.log(utilities.isRegularExpression({ }})); // false
+ * console.log(utilities.isRegularExpression(null)); // false
+ */
+utilities.isRegularExpression = function isRegularExpression(value) {
+	return value instanceof RegExp;
+};
+
+/**
+ * Checks if the specified value is an instance of the Function object.
+ *
+ * @function isFunction
+ * @param {any} value - The value to check.
+ * @returns {boolean} A value of true if the specified value is a Function object instance, otherwise false for any other value.
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isFunction(function() { })); // true
+ * console.log(utilities.isFunction(console.log)); // true
+ * console.log(utilities.isFunction({ })); // false
+ * console.log(utilities.isFunction({ })); // false
+ */
+utilities.isFunction = function isFunction(value) {
+	return value instanceof Function;
+};
+
+/**
+ * Checks if a specified string value starts with the corresponding comment notation.
+ * Any whitespace characters at the start of the string will be ignored.
+ * Empty and non-string values will always result in a value of false being returned.
+ *
+ * @function isComment
+ * @param {string} value - The value to check.
+ * @param {string} [comment="//"] - The comment notation string, can be one or more characters.
+ * @returns {boolean} A value of true if the specified value is a string and begins with the corresponding comment notation.
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isComment("// test comment, please ignore")); // true
+ * console.log(utilities.isComment("# another comment")); // false
+ * console.log(utilities.isComment("# valid comment", "#")); // true
+ * console.log(utilities.isComment("some text")); // false
+ * console.log(utilities.isComment("")); // false
+ * console.log(utilities.isComment(null)); // false
+ */
+utilities.isComment = function isComment(value, comment) {
+	if(utilities.isEmptyString(value)) {
+		return false;
+	}
+
+	if(utilities.isEmptyString(comment)) {
+		comment = "//";
+	}
+
+	var commentStartIndex = -1;
+
+	for(var i = 0; i < value.length; i++) {
+		if(value[i] === " " || value[i] == "\t") {
+			continue;
+		}
+
+		if(value[i] == comment[0]) {
+			commentStartIndex = i;
+			break;
+		}
+		else {
+			return false;
+		}
+	}
+
+	if(commentStartIndex < 0 || value.length - commentStartIndex < comment.length) {
+		return false;
+	}
+
+	for(var i = commentStartIndex; i < value.length; i++) {
+		if(i - commentStartIndex >= comment.length) {
+			break;
+		}
+
+		if(value[i] != comment[i - commentStartIndex]) {
+			return false;
+		}
+	}
+
+	return true;
+};
+
+/**
+ * Checks if an object is visible or not.
+ * A value which is not an object is not considered to be visible.
+ * A property named visible with a boolean value of true or function returning true is considered to be visible.
+ * If there is no property named visible, but a property named hidden is present with a boolean value of false or function returning false, the object is considered to be visible.
+ * If the value does not contain either a visible or hidden property, it is considered to be visible.
+ *
+ * @function isVisible
+ * @param {object} element - The element to check.
+ * @returns {boolean} Returns a value of true if the object is determined to be visible.
+ * @deprecated Determined to no longer be useful, will be removed in a future release.
+ * @see {@link module:utilities.isHidden|isHidden}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isVisible({ visible: true })); // true
+ * console.log(utilities.isVisible({ visible: function() { return true; } })); // true
+ * console.log(utilities.isVisible({ hidden: false })); // true
+ * console.log(utilities.isVisible({ hidden: function() { return false; } })); // true
+ * console.log(utilities.isVisible({ })); // false
+ * console.log(utilities.isVisible(null)); // false
+ */
+utilities.isVisible = function isVisible(element) {
+	if(!utilities.isObject(element)) {
+		return false;
+	}
+
+	if(utilities.isBoolean(element.visible)) {
+		return element.visible;
+	}
+	else if(utilities.isFunction(element.visible)) {
+		return element.visible();
+	}
+	else if(utilities.isBoolean(element.hidden)) {
+		return !element.hidden;
+	}
+	else if(utilities.isFunction(element.hidden)) {
+		return !element.hidden();
+	}
+
+	return true;
+};
+
+/**
+ * Checks if an object is hidden or not.
+ * A value which is not an object is considered to be hidden.
+ * A property named hidden with a boolean value of true or function returning true is considered to be hidden.
+ * If there is no property named hidden, but a property named hidden is present with a boolean value of false or function returning false, the object is considered to be hidden.
+ * If the value does not contain either a visible or hidden property, it is not considered to be hidden.
+ *
+ * @function isHidden
+ * @param {object} element - The element to check.
+ * @returns {boolean} Returns a value of true if the object is determined to be hidden.
+ * @deprecated Determined to no longer be useful, will be removed in a future release.
+ * @see {@link module:utilities.isVisible|isVisible}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isHidden({ hidden: true })); // true
+ * console.log(utilities.isHidden({ hidden: function() { return true; } })); // true
+ * console.log(utilities.isHidden({ visible: false })); // true
+ * console.log(utilities.isHidden({ visible: function() { return false; } })); // true
+ * console.log(utilities.isHidden({ })); // false
+ * console.log(utilities.isHidden(null)); // true
+ */
+utilities.isHidden = function isHidden(element) {
+	if(!utilities.isObject(element)) {
+		return true;
+	}
+
+	if(utilities.isBoolean(element.visible)) {
+		return !element.visible;
+	}
+	else if(utilities.isFunction(element.visible)) {
+		return !element.visible();
+	}
+	else if(utilities.isBoolean(element.hidden)) {
+		return element.hidden;
+	}
+	else if(utilities.isFunction(element.hidden)) {
+		return element.hidden();
+	}
+
+	return false;
+};
+
+/**
+ * Checks if an object is enabled or not.
+ * A value which is not an object is not considered to be enabled.
+ * A property named enabled with a boolean value of true or function returning true is considered to be enabled.
+ * If there is no property named enabled, but a property named disabled is present with a boolean value of false or function returning false, the object is considered to be enabled.
+ * If the value does not contain either a enabled or disabled property, it is considered to be enabled.
+ *
+ * @function isEnabled
+ * @param {object} element - The element to check.
+ * @returns {boolean} Returns a value of true if the object is determined to be enabled.
+ * @deprecated Determined to no longer be useful, will be removed in a future release.
+ * @see {@link module:utilities.isDisabled|isDisabled}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isEnabled({ enabled: true })); // true
+ * console.log(utilities.isEnabled({ enabled: function() { return true; } })); // true
+ * console.log(utilities.isEnabled({ disabled: false })); // true
+ * console.log(utilities.isEnabled({ disabled: function() { return false; } })); // true
+ * console.log(utilities.isEnabled({ })); // false
+ * console.log(utilities.isEnabled(null)); // false
+ */
+utilities.isEnabled = function isEnabled(element) {
+	if(!utilities.isObject(element)) {
+		return false;
+	}
+
+	if(utilities.isBoolean(element.enabled)) {
+		return element.enabled;
+	}
+	else if(utilities.isFunction(element.enabled)) {
+		return element.enabled();
+	}
+	else if(utilities.isBoolean(element.disabled)) {
+		return !element.disabled;
+	}
+	else if(utilities.isFunction(element.disabled)) {
+		return !element.disabled();
+	}
+
+	return true;
+};
+
+/**
+ * Checks if an object is disabled or not.
+ * A value which is not an object is considered to be disabled.
+ * A property named disabled with a boolean value of true or function returning true is considered to be disabled.
+ * If there is no property named disabled, but a property named disabled is present with a boolean value of false or function returning false, the object is considered to be disabled.
+ * If the value does not contain either a enabled or disabled property, it is not considered to be disabled.
+ *
+ * @function isDisabled
+ * @param {object} element - The element to check.
+ * @returns {boolean} Returns a value of true if the object is determined to be disabled.
+ * @deprecated Determined to no longer be useful, will be removed in a future release.
+ * @see {@link module:utilities.isEnabled|isEnabled}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.isDisabled({ disabled: true })); // true
+ * console.log(utilities.isDisabled({ disabled: function() { return true; } })); // true
+ * console.log(utilities.isDisabled({ enabled: false })); // true
+ * console.log(utilities.isDisabled({ enabled: function() { return false; } })); // true
+ * console.log(utilities.isDisabled({ })); // false
+ * console.log(utilities.isDisabled(null)); // true
+ */
+utilities.isDisabled = function isDisabled(element) {
+	if(!utilities.isObject(element)) {
+		return true;
+	}
+
+	if(utilities.isBoolean(element.enabled)) {
+		return !element.enabled;
+	}
+	else if(utilities.isFunction(element.enabled)) {
+		return !element.enabled();
+	}
+	else if(utilities.isBoolean(element.disabled)) {
+		return element.disabled;
+	}
+	else if(utilities.isFunction(element.disabled)) {
+		return element.disabled();
+	}
+
+	return false;
+};
+
+/**
+ * Case insensitively compares two strings to determine if they are equal.
+ *
+ * @function equalsIgnoreCase
+ * @param {string} stringA - The first string to compare.
+ * @param {string} stringB - The second string to compare against
+ * @returns {boolean} .A value of true if the strings are case insensitively equal, otherwise false.
+ * @since 1.3.2
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.equalsIgnoreCase("Test", "TEsT")); // true
+ * console.log(utilities.equalsIgnoreCase("lower", "lower")); // true
+ * console.log(utilities.equalsIgnoreCase("yes", "ye$")); // false
+ * console.log(utilities.equalsIgnoreCase(null, "unknown")); // false
+ */
+utilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) {
+	if(typeof stringA !== "string" || typeof stringB !== "string") {
+		return false;
+	}
+
+	return stringA.localeCompare(stringB, undefined, { sensitivity: "accent" }) === 0;
+};
+
+/**
+ * Parses a boolean from a given value.
+ * If no valid boolean value can be determined, defaultValue is returned instead which by default has a value of null.
+ * There are many possibilities for valid truthy boolean values including:
+ * - true
+ * - new Boolean(true)
+ * - 1
+ * - "1"
+ * - "true"
+ * - "yes"
+ * - "on"
+ * - "t"
+ * - "y"
+ *
+ * As well as a number of possibilities for valid falsey boolean values:
+ * - false
+ * - new Boolean(false)
+ * - 0
+ * - "0"
+ * - "false"
+ * - "no"
+ * - "off"
+ * - "f"
+ * - "n"
+ *
+ * @function parseBoolean
+ * @param {any} value - The value to parse into a boolean.
+ * @param {(boolean|null)} [defaultValue=null] - The value to return if no valid boolean value can be determined. Specifying a non-boolean value will result in null being used instead.
+ * @returns {(boolean|null)} A value of true if a valid truthy value was determined from the specified value, false if a valid falsey value was determined, otherwise the default value is returned. A value of null will be returned if the default value is not specified.
+ * @see {@link module:utilities.isBoolean|isBoolean}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseBoolean(true)); // true
+ * console.log(utilities.parseBoolean("false")); // false
+ * console.log(utilities.parseBoolean("yes")); // true
+ * console.log(utilities.parseBoolean(1)); // true
+ * console.log(utilities.parseBoolean(4)); // null
+ * console.log(utilities.parseBoolean("wat")); // null
+ * console.log(utilities.parseBoolean("wot", true)); // true
+ * console.log(utilities.parseBoolean("huh", 420)); // null
+ * console.log(utilities.parseBoolean(null)); // null
+ */
+utilities.parseBoolean = function parseBoolean(value, defaultValue) {
+	if(utilities.isBoolean(value)) {
+		return value;
+	}
+
+	if(utilities.isBoolean(value, true)) {
+		return value.valueOf();
+	}
+
+	if(!utilities.isBoolean(defaultValue)) {
+		defaultValue = null;
+	}
+
+	if(utilities.isInvalid(value)) {
+		return defaultValue;
+	}
+
+	if(value === 0) {
+		return false;
+	}
+	else if(value === 1) {
+		return true;
+	}
+
+	if(typeof value !== "string") {
+		return defaultValue;
+	}
+
+	var formattedValue = value.trim().toLowerCase();
+
+	if(formattedValue.length === 0) {
+		return defaultValue;
+	}
+
+	if(formattedValue.length === 1) {
+		var character = formattedValue.charAt(0);
+
+		if(character === "t" || character === "y") {
+			return true;
+		}
+		else if(character === "f" || character === "n") {
+			return false;
+		}
+		else if(character === "0") {
+			return false;
+		}
+		else if(character === "1") {
+			return true;
+		}
+
+		return defaultValue;
+	}
+
+	if(formattedValue === "true" || formattedValue === "yes" || formattedValue === "on") {
+		return true;
+	}
+	else if(formattedValue === "false" || formattedValue === "no" || formattedValue === "off") {
+		return false;
+	}
+
+	return defaultValue;
+};
+
+/**
+ * Parses an integer number from a given value.
+ * Accepts number, string and number object values.
+ * If no valid integer number can be determined from the specified value, the default value is returned instead.
+ *
+ * @function parseInteger
+ * @param {any} value - The value to parse into a integer number.
+ * @param {number} [defaultValue=NaN] - The default value to return if the specified value is not an integer or floating point number.
+ * @returns {number} An integer number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified.
+ * @see {@link module:utilities.isValidNumber|isValidNumber}
+ * @see {@link module:utilities.isInvalidNumber|isInvalidNumber}
+ * @see {@link module:utilities.parseFloat|parseFloat}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseInteger(88)); // 88
+ * console.log(utilities.parseInteger(-73.31)); // -73
+ * console.log(utilities.parseInteger("-15")); // -15
+ * console.log(utilities.parseInteger("3.141592654")); // 3
+ * console.log(utilities.parseInteger(new Number(4096))); // 4096
+ * console.log(utilities.parseInteger(new Number(3.333))); // 3
+ * console.log(utilities.parseInteger("wat", 11100101); // 11100101
+ * console.log(utilities.parseInteger(null); // NaN
+ */
+utilities.parseInteger = function parseInteger(value, defaultValue) {
+	var newValue = NaN;
+
+	if(typeof value === "number") {
+		newValue = parseInt(value);
+	}
+	else if(typeof value === "string") {
+		if(utilities.isFloat(value)) {
+			newValue = parseInt(value);
+		}
+	}
+	else if(value instanceof Number) {
+		newValue = parseInt(value.valueOf());
+	}
+
+	if(utilities.isInvalidNumber(newValue)) {
+		defaultValue = parseInt(defaultValue);
+
+		return utilities.isValidNumber(defaultValue) ? defaultValue : NaN;
+	}
+
+	return newValue;
+};
+
+/**
+ * Parses a floating point number from a given value.
+ * Accepts number, string and number object values.
+ * If no valid floating point number can be determined from the specified value, the default value is returned instead.
+ *
+ * @function parseFloat
+ * @param {any} value - The value to parse into a floating point number.
+ * @param {number} [defaultValue=NaN] - The default value to return if the specified value is not a floating point number.
+ * @returns {number} A floating point number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified.
+ * @see {@link module:utilities.isValidNumber|isValidNumber}
+ * @see {@link module:utilities.isInvalidNumber|isInvalidNumber}
+ * @see {@link module:utilities.parseInteger|parseInteger}
+ * @since 1.3.7
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseFloat(-999)); // -999
+ * console.log(utilities.parseFloat(13.37)); // 13.37
+ * console.log(utilities.parseFloat("51")); // 51
+ * console.log(utilities.parseFloat("-867.5309")); // -867.5309
+ * console.log(utilities.parseFloat(new Number(-4231))); // -4231
+ * console.log(utilities.parseFloat(new Number(9.999))); // 9.999
+ * console.log(utilities.parseFloat("wat", 10010101); // 10010101
+ * console.log(utilities.parseFloat(null); // NaN
+ */
+utilities.parseFloat = function parseFloatingPointNumber(value, defaultValue) {
+	var newValue = NaN;
+
+	if(typeof value === "number") {
+		newValue = value;
+	}
+	else if(typeof value === "string") {
+		if(utilities.isFloat(value)) {
+			newValue = parseFloat(value);
+		}
+	}
+	else if(value instanceof Number) {
+		newValue = value.valueOf();
+	}
+
+	if(utilities.isInvalidNumber(newValue)) {
+		return utilities.isValidNumber(defaultValue) ? defaultValue : NaN;
+	}
+
+	return newValue;
+};
+
+/**
+ * Parses a floating point number from a given value.
+ * Accepts number, string and number object values.
+ * If no valid floating point number can be determined from the specified value, the default value is returned instead.
+ *
+ * @function parseFloatingPointNumber
+ * @param {any} value - The value to parse into a floating point number.
+ * @param {number} [defaultValue=NaN] - The default value to return if the specified value is not a floating point number.
+ * @returns {number} A floating point number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified.
+ * @deprecated Use utilities.parseFloat instead. Will be removed in a future release.
+ * @see {@link module:utilities.parseFloat|parseFloat}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseFloatingPointNumber(-1)); // -1
+ * console.log(utilities.parseFloatingPointNumber(2.2)); // 1.1
+ * console.log(utilities.parseFloatingPointNumber("3")); // 3
+ * console.log(utilities.parseFloatingPointNumber("4.4")); // 4.4
+ * console.log(utilities.parseFloatingPointNumber(new Number(-5))); // -5
+ * console.log(utilities.parseFloatingPointNumber(new Number(6.6))); // 6.6
+ * console.log(utilities.parseFloatingPointNumber("nope.avi", 69); // 69
+ * console.log(utilities.parseFloatingPointNumber(null); // NaN
+ */
+utilities.parseFloatingPointNumber = utilities.parseFloat;
+
+/**
+ * Parses a date object from a given value.
+ * Accepts date object, date string, timestamp number string and timestamp number values.
+ * If no valid date object can be determined from the specified value, the default value is returned instead.
+ *
+ * @function parseDate
+ * @param {any} value - The value to parse into a date object.
+ * @param {(Date|null)} [defaultValue=null] - The default value to return if the specified value is not a valid date or timestamp.
+ * @returns {(Date|null)} A Date object instance if a valid date was determined from the specified value, otherwise the default value is returned. A value of null will be returned if the default value is not specified.
+ * @see {@link module:utilities.isDate|isDate}
+ * @see {@link module:utilities.compareDates|compateDates}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseDate("June 18, 1987 3:30 PM")); // new Date("1987-06-18T19:30:00.000Z")
+ * console.log(utilities.parseDate("2018-02-19T06:19:33Z")); // new Date("2018-02-19T06:19:33.000Z")
+ * console.log(utilities.parseDate(new Date("2020-03-28T18:52:05.136Z"))); // new Date("2020-03-28T18:52:05.136Z")
+ * console.log(utilities.parseDate(1585421525139)); // new Date("2020-03-28T18:52:05.136Z")
+ * console.log(utilities.parseDate("1585421525139")); // new Date("2020-03-28T18:52:05.136Z")
+ * console.log(utilities.parseDate(-1, new Date(0))); // new Date("1970-01-01T00:00:00.000Z")
+ * console.log(utilities.parseDate(-420)); // null
+ */
+utilities.parseDate = function parseDate(value, defaultValue) {
+	if(!utilities.isDate(defaultValue)) {
+		defaultValue = null;
+	}
+
+	if(typeof value === "number") {
+		if(utilities.isInvalidNumber(value) || !Number.isInteger(value) || value < 0) {
+			return defaultValue;
+		}
+
+		return new Date(parseInt(value));
+	}
+	else if(typeof value === "string") {
+		var formattedValue = value.trim();
+
+		if(formattedValue.length === 0) {
+			return defaultValue;
+		}
+
+		var timestamp = null;
+
+		if(utilities.isInteger(formattedValue)) {
+			timestamp = parseInt(formattedValue);
+		}
+		else {
+			timestamp = Date.parse(formattedValue);
+		}
+
+		if(utilities.isInvalidNumber(timestamp)) {
+			return defaultValue;
+		}
+
+		return new Date(timestamp);
+	}
+	else if(value instanceof Date) {
+		return value;
+	}
+
+	return defaultValue;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseTime
+ * @param {any} value - TODO_ARG_DESC.
+ * @returns {Object} TODO_RETURN_DESC
+ * @see {@link module:utilities.parseDate|parseDate}
+ * @since 1.1.2
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseTime()); // TODO_RESULT
+ */
+utilities.parseTime = function parseTime(value) {
+	if(utilities.isEmptyString(value)) {
+		throw new Error("Invalid or empty time value.");
+	}
+
+	var formattedValue = value.trim();
+	var hour = null;
+	var minutes = null;
+	var regularTime = formattedValue.match(/^[ \t]*(([2-9]|[1][0-2]?)(:([0-5][0-9]))?[ \t]*([ap]m))[ \t]*$/i);
+
+	if(regularTime) {
+		var regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2]));
+
+		if(utilities.isInvalidNumber(regularHour)) {
+			throw new Error("Invalid regular hour: \"" + regularTime[2] + "\".");
+		}
+
+		minutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4]));
+
+		if(utilities.isInvalidNumber(minutes)) {
+			minutes = 0;
+		}
+
+		var period = regularTime[5].toUpperCase();
+		var morning = period === "AM" ? true : (period === "PM" ? false : null);
+
+		if(morning === null) {
+			throw new Error("Invalid period: \"" + regularTime[5] + "\".");
+		}
+
+		hour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12);
+
+		if(hour === 24) {
+			hour = 0;
+		}
+	}
+	else {
+		var militaryTime = formattedValue.match(/^[ \t]*(((([0-1][0-9])|(2[0-3])):?([0-5][0-9]))|((24):?(00)))[ \t]*$/i);
+
+		if(militaryTime) {
+			var militaryHour = militaryTime[3];
+			var militaryMinutes = militaryTime[6];
+
+			if(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {
+				militaryHour = militaryTime[8];
+
+				if(utilities.isNonEmptyString(militaryTime[9])) {
+					militaryMinutes = militaryTime[9];
+				}
+			}
+
+			if(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) {
+				throw new Error("Invalid military time: \"" + formattedValue + "\".");
+			}
+
+			hour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour));
+
+			if(utilities.isInvalidNumber(hour)) {
+				throw new Error("Invalid military time hour: \"" + militaryHour + "\".");
+			}
+
+			minutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes));
+
+			if(utilities.isInvalidNumber(minutes)) {
+				throw new Error("Invalid military time minutes: \"" + militaryMinutes + "\".");
+			}
+
+			if(hour === 24 && minutes === 0) {
+				hour = 0;
+			}
+		}
+		else {
+			throw new Error("Invalid time: \"" + formattedValue + "\".");
+		}
+	}
+
+	if(hour < 0 || hour > 23) {
+		throw new Error("Time hour is out of range (0 - 23): \"" + hour + "\".");
+	}
+	else if(minutes < 0 || minutes > 59) {
+		throw new Error("Time minutes is out of range (0 - 59): \"" + minutes + "\".");
+	}
+
+	var regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12);
+	var period = hour < 12 ? "AM" : "PM";
+
+	return {
+		regular: {
+			raw: regularHour + ":" + utilities.addLeadingZeroes(minutes, 2) + " " + period,
+			hour: regularHour,
+			minutes: minutes,
+			period: period,
+			morning: hour < 12
+		},
+		military: {
+			raw: utilities.addLeadingZeroes(hour, 2) + utilities.addLeadingZeroes(minutes, 2),
+			hour: hour,
+			minutes: minutes
+		}
+	};
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseEmail
+ * @param {string} value - A string containing an email address.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.parseEmailDomain|parseEmailDomain}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseEmail()); // TODO_RESULT
+ */
+utilities.parseEmail = function parseEmail(value) {
+	if(utilities.isEmptyString(value)) {
+		return null;
+	}
+
+	var emailData = value.trim().toLowerCase().match(/([^+@]+)(\+.*)?(@.+\..+)/);
+
+	if(utilities.isInvalid(emailData) || emailData.length < 4) {
+		return null;
+	}
+
+	return emailData[1] + emailData[3];
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseEmailDomain
+ * @param {string} value - A string containing an email address.
+ * @deprecated Use value.split("@", 2)[1] instead. Will be removed in a future release.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.parseEmail|parseEmail}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseEmailDomain()); // TODO_RESULT
+ */
+utilities.parseEmailDomain = function parseEmailDomain(value) {
+	if(utilities.isEmptyString(value)) {
+		return null;
+	}
+
+	var emailDomainData = value.trim().toLowerCase().match(/([^+@]+)(\+.*)?@(.+\..+)/);
+
+	if(utilities.isInvalid(emailDomainData) || emailDomainData.length < 4) {
+		return null;
+	}
+
+	return emailDomainData[3];
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseStringList
+ * @param {string} value - A comma or semicolon separated list of string values.
+ * @returns {(string[]|null)} An array of strings as parsed from the specified string list or null if the specified value is not a string.
+ * @see {@link module:utilities.formatStringList|formatStringList}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseStringList("w, a, t")); // ["w", "a", "t"]
+ * console.log(utilities.parseStringList("ok")); // ["ok"]
+ * console.log(utilities.parseStringList([])); // null
+ */
+utilities.parseStringList = function parseStringList(value) {
+	if(typeof value !== "string") {
+		return null;
+	}
+
+	if(value.length === 0) {
+		return [];
+	}
+
+	var data = value.split(/[;,]+/);
+	var formattedList = [];
+	var formattedValue = null;
+
+	for(var i = 0; i < data.length; i++) {
+		formattedValue = data[i].trim();
+
+		if(formattedValue.length === 0) {
+			continue;
+		}
+
+		formattedList.push(formattedValue);
+	}
+
+	return formattedList;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseRegularExpression
+ * @param {string} value - The string value to parse a regular expression from.
+ * @param {boolean} [throwErrors=false] - Determines if errors should be thrown or not when invalid regular expression values are encountered.
+ * @returns {(RegExp|null)} Returns a RegExp object instance if a valid regular expression was parsed from the specified value or null if the value was invalid and throwErrors is unspecified or set to false.
+ * @throws Will optionally throw an error if the regular expression is invalid and throwErrors is set to true.
+ * @see {@link module:utilities.isRegularExpression|isRegularExpression}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseRegularExpression("/(regexp?)/gi")); // new RegExp("(regexp?)", "gi")
+ * console.log(utilities.parseRegularExpression(new RegExp("ok"))); // new RegExp("ok")
+ * console.log(utilities.parseRegularExpression({ })); // null
+ * console.log(utilities.parseRegularExpression(/invalid/x, true)); // throws Error
+ */
+utilities.parseRegularExpression = function parseRegularExpression(value, throwErrors) {
+	throwErrors = utilities.parseBoolean(throwErrors, false);
+
+	if(utilities.isRegularExpression(value)) {
+		return value;
+	}
+
+	if(utilities.isEmptyString(value)) {
+		if(throwErrors) {
+			throw new Error("Regular expression cannot be empty.");
+		}
+
+		return null;
+	}
+
+	var regExpData = value.match(/\s*\/(.*)\/(.*)\s*/);
+
+	if(!regExpData) {
+		if(throwErrors) {
+			throw new Error("Invalid regular expression value.");
+		}
+
+		return null;
+	}
+
+	try {
+		return new RegExp(regExpData[1], regExpData[2]);
+	}
+	catch(error) {
+		if(throwErrors) {
+			throw error;
+		}
+
+		return null;
+	}
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseYouTubeLink
+ * @param {string} value - The string URL value to parse a YouTube video identifier from.
+ * @returns {(string|null)} A string value containing the YouTube video ID or null if the video ID could be determined from the specified value.
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseYouTubeLink("http://youtube.com/v/OEEEy1dMceI")); // OEEEy1dMceI
+ * console.log(utilities.parseYouTubeLink("https://www.youtube.com/watch?v=NUnwFHplBg4")); // NUnwFHplBg4
+ * console.log(utilities.parseYouTubeLink("www.youtu.be/watch?v=Dkm8Hteeh6M")); // Dkm8Hteeh6M
+ * console.log(utilities.parseYouTubeLink("https://youtu.be/v/z874bjpO9d8")); // z874bjpO9d8
+ * console.log(utilities.parseYouTubeLink("https://www.nitro404.com")); // null
+ * console.log(utilities.parseYouTubeLink(NaN)); // null
+ */
+utilities.parseYouTubeLink = function parseYouTubeLink(value) {
+	if(utilities.isEmptyString(value)) {
+		return null;
+	}
+
+	var formattedValue = value.trim();
+	var linkData = formattedValue.match(/.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/i);
+
+	if(linkData && linkData[1].length >= 11) {
+		return linkData[1];
+	}
+
+	if(formattedValue.match(/[A-Z0-9_-]{11,}/i)) {
+		return formattedValue;
+	}
+
+	return null;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function formatValue
+ * @param {any} value - The value to format.
+ * @param {Object} format - The format specification.
+ * @param {Object} [options] - Formatting options.
+ * @returns {any} The formatted value.
+ * @since 1.1.1
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.formatValue()); // TODO_RESULT
+ */
+utilities.formatValue = function formatValue(value, format, options) {
+	if(utilities.isObjectStrict(options)) {
+		options = {
+			throwErrors: utilities.parseBoolean(options.throwErrors, false)
+		};
+
+		options.verbose = utilities.parseBoolean(options.verbose, !options.throwErrors);
+	}
+	else {
+		options = {
+			throwErrors: false,
+			verbose: true
+		};
+	}
+
+	if(!utilities.isObjectStrict(format)) {
+		return utilities.clone(value);
+	}
+
+	format = utilities.clone(format);
+
+	var errorMessage = null;
+
+	if(utilities.isEmptyString(format.type)) {
+		errorMessage = "Invalid required type format value - expected non-empty string.";
+	}
+	else {
+		var originalType = format.type;
+
+		format.type = format.type.trim().toLowerCase();
+
+		var validFormatType = false;
+
+		for(var i = 0; i < formatTypes.length; i++) {
+			if(format.type === formatTypes[i]) {
+				validFormatType = true;
+				break;
+			}
+		}
+
+		if(!validFormatType) {
+			errorMessage = "Invalid required type format value - expected one of " + formatTypes.join(", ") + ", received \"" + utilities.toString(originalType) + "\".";
+		}
+		else {
+			if(format.type === "bool") {
+				format.type = "boolean";
+			}
+			else if(format.type === "int") {
+				format.type = "integer";
+			}
+			else if(format.type === "number") {
+				format.type = "float";
+			}
+			else if(format.type === "string") {
+				if(format.trim !== undefined) {
+					var originalTrim = format.trim;
+
+					format.trim = utilities.parseBoolean(format.trim);
+
+					if(format.trim === null) {
+						errorMessage = "Invalid optional trim string format value - expected boolean, received \"" + utilities.toString(originalTrim) + "\".";
+					}
+				}
+
+				if(utilities.isInvalid(errorMessage)) {
+					if(format.case !== undefined) {
+						if(utilities.isEmptyString(format.case)) {
+							errorMessage = "Invalid optional string case format value - expected non-empty string.";
+						}
+						else {
+							var originalCase = format.case;
+
+							format.case = changeCase.camelCase(format.case.trim());
+
+							if(!utilities.isFunction(stringCaseFunctions[format.case])) {
+								errorMessage = "Invalid optional case format value - expected one of " + Object.keys(stringCaseFunctions).join(", ") + ", received \"" + utilities.toString(originalCase) + "\".";
+							}
+						}
+					}
+				}
+			}
+			else if(format.type === "object") {
+				if(format.strict !== undefined) {
+					var originalStrict = format.strict;
+
+					format.strict = utilities.parseBoolean(format.strict);
+
+					if(format.strict === null) {
+						errorMessage = "Invalid optional strict object format value - expected boolean, received \"" + utilities.toString(originalStrict) + "\".";
+					}
+				}
+
+				if(utilities.isInvalid(errorMessage)) {
+					if(format.autopopulate !== undefined) {
+						var originalAutopopulate = format.autopopulate;
+
+						format.autopopulate = utilities.parseBoolean(format.autopopulate);
+
+						if(format.autopopulate === null) {
+							errorMessage = "Invalid optional autopopulate object format value - expected boolean, received \"" + utilities.toString(originalAutopopulate) + "\".";
+						}
+					}
+				}
+
+				if(utilities.isInvalid(errorMessage)) {
+					if(format.order !== undefined) {
+						var originalOrder = format.order;
+
+						format.order = utilities.parseBoolean(format.order);
+
+						if(format.order === null) {
+							errorMessage = "Invalid optional order object format value - expected boolean, received \"" + utilities.toString(originalOrder) + "\".";
+						}
+					}
+				}
+
+				if(utilities.isInvalid(errorMessage)) {
+					if(format.removeExtra !== undefined) {
+						var originalRemoveExtra = format.removeExtra;
+
+						format.removeExtra = utilities.parseBoolean(format.removeExtra);
+
+						if(format.removeExtra === null) {
+							errorMessage = "Invalid optional removeExtra object format value - expected boolean, received \"" + utilities.toString(originalRemoveExtra) + "\".";
+						}
+					}
+				}
+			}
+			else if(format.type === "regexp" || format.type === "regularexpression") {
+				format.type = "regex";
+			}
+			else if(format.type === "func") {
+				format.type = "function";
+			}
+
+			if(utilities.isInvalid(errorMessage)) {
+				if(format.type === "object" || format.type === "array") {
+					if(format.format !== undefined && !utilities.isObjectStrict(format.format)) {
+						errorMessage = "Invalid optional format format value - expected object, received \"" + utilities.toString(format.format) + "\".";
+					}
+				}
+			}
+
+			if(utilities.isInvalid(errorMessage)) {
+				if(format.type === "string" || format.type === "object" || format.type === "array") {
+					if(format.nonEmpty !== undefined) {
+						var originalNonEmpty = format.nonEmpty;
+
+						format.nonEmpty = utilities.parseBoolean(format.nonEmpty);
+
+						if(format.nonEmpty === null) {
+							errorMessage = "Invalid optional nonEmpty format value - expected boolean, received \"" + utilities.toString(originalNonEmpty) + "\".";
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if(utilities.isInvalid(errorMessage)) {
+		if(format.nullable !== undefined) {
+			var originalNullable = format.nullable;
+
+			format.nullable = utilities.parseBoolean(format.nullable);
+
+			if(format.nullable === null) {
+				errorMessage = "Invalid optional nullable format value - expected boolean, received \"" + utilities.toString(originalNullable) + "\".";
+			}
+		}
+	}
+
+	if(utilities.isInvalid(errorMessage)) {
+		if(format.required !== undefined) {
+			var originalRequired = format.required;
+
+			format.required = utilities.parseBoolean(format.required);
+
+			if(format.required === null) {
+				errorMessage = "Invalid optional required format value - expected boolean, received \"" + utilities.toString(originalRequired) + "\".";
+			}
+		}
+	}
+
+	if(utilities.isInvalid(errorMessage)) {
+		if(format.parser !== undefined) {
+			if(!utilities.isFunction(format.parser)) {
+				errorMessage = "Invalid optional parser format value - expected function, received \"" + utilities.toString(format.parser) + "\".";
+			}
+		}
+	}
+
+	if(utilities.isInvalid(errorMessage)) {
+		if(format.validator !== undefined) {
+			if(!utilities.isFunction(format.validator)) {
+				errorMessage = "Invalid optional validator format value - expected function, received \"" + utilities.toString(format.validator) + "\".";
+			}
+		}
+	}
+
+	if(utilities.isInvalid(errorMessage)) {
+		if(format.formatter !== undefined) {
+			if(!utilities.isFunction(format.formatter)) {
+				errorMessage = "Invalid optional formatter format value - expected function, received \"" + utilities.toString(format.formatter) + "\".";
+			}
+		}
+	}
+
+	if(utilities.isValid(errorMessage)) {
+		if(options.throwErrors) {
+			throw new Error(errorMessage);
+		}
+		else if(options.verbose) {
+			console.error(errorMessage);
+		}
+
+		return null;
+	}
+
+	if(utilities.isFunction(format.parser)) {
+		if(options.throwErrors) {
+			value = format.parser(value, format, options);
+		}
+		else {
+			try {
+				value = format.parser(value, format, options);
+			}
+			catch(error) {
+				if(options.verbose) {
+					console.error(error.message);
+				}
+
+				return null;
+			}
+		}
+	}
+
+	var formattedValue = undefined;
+
+	if(value === undefined) {
+		formattedValue = utilities.clone(format.default);
+	}
+	else if(value === null) {
+		if(format.nullable) {
+			formattedValue = null;
+		}
+		else if(format.default !== undefined) {
+			formattedValue = utilities.clone(format.default);
+		}
+		else {
+			errorMessage = "Value cannot be null!";
+		}
+	}
+	else if(format.type === "boolean") {
+		formattedValue = utilities.parseBoolean(value);
+
+		if(formattedValue === null) {
+			errorMessage = "Invalid boolean value: \"" + utilities.toString(value) + "\".";
+		}
+	}
+	else if(format.type === "integer") {
+		formattedValue = utilities.parseInteger(value);
+
+		if(utilities.isInvalidNumber(formattedValue)) {
+			errorMessage = "Invalid integer value: \"" + utilities.toString(value) + "\".";
+		}
+	}
+	else if(format.type === "float") {
+		formattedValue = utilities.parseFloatingPointNumber(value);
+
+		if(utilities.isInvalidNumber(formattedValue)) {
+			errorMessage = "Invalid float value: \"" + utilities.toString(value) + "\".";
+		}
+	}
+	else if(format.type === "string") {
+		formattedValue = typeof value === "string" ? value : utilities.toString(value);
+
+		if(format.trim) {
+			formattedValue = formattedValue.trim();
+		}
+
+		if(format.case !== undefined) {
+			formattedValue = stringCaseFunctions[format.case](formattedValue);
+		}
+
+		if(format.nonEmpty && formattedValue.length === 0) {
+			var message = "String value cannot be empty.";
+
+			if(options.throwErrors) {
+				throw new Error(message);
+			}
+			else if(options.verbose) {
+				console.error(message);
+			}
+
+			return null;
+		}
+	}
+	else if(format.type === "array") {
+		if(typeof value === "string") {
+			try {
+				formattedValue = JSON.parse(value);
+
+				if(!Array.isArray(formattedValue)) {
+					errorMessage = "Invalid stringified array value type - expected array: \"" + utilities.toString(value) + "\"."
+				}
+			}
+			catch(error) {
+				errorMessage = "Invalid stringified array value: \"" + utilities.toString(value) + "\".";
+			}
+		}
+		else if(Array.isArray(value)) {
+			formattedValue = utilities.clone(value);
+		}
+		else {
+			errorMessage = "Invalid value type - expected array or stringified array: \"" + utilities.toString(value) + "\".";
+		}
+
+		if(utilities.isInvalid(errorMessage)) {
+			if(Array.isArray(formattedValue)) {
+				var formattedArray = [];
+
+				if(utilities.isObjectStrict(format.format)) {
+					var formattedElement = null;
+
+					for(var i = 0; i < formattedValue.length; i++) {
+						if(formattedValue[i] === undefined) {
+							continue;
+						}
+
+						if(options.throwErrors) {
+							formattedElement = utilities.formatValue(formattedValue[i], format.format, options);
+						}
+						else {
+							var subOptions = utilities.clone(options);
+
+							subOptions.throwErrors = true;
+
+							try {
+								formattedElement = utilities.formatValue(formattedValue[i], format.format, subOptions);
+							}
+							catch(error) {
+								if(options.verbose) {
+									console.error(error.message);
+								}
+
+								return null;
+							}
+						}
+
+						formattedArray.push(formattedElement);
+					}
+				}
+				else {
+					for(var i = 0; i < formattedValue.length; i++) {
+						if(formattedValue[i] === undefined) {
+							continue;
+						}
+
+						formattedArray.push(utilities.clone(formattedValue[i]));
+					}
+				}
+
+				formattedValue = formattedArray;
+
+				if(format.nonEmpty && formattedValue.length === 0) {
+					var message = "Array value cannot be empty.";
+
+					if(options.throwErrors) {
+						throw new Error(message);
+					}
+					else if(options.verbose) {
+						console.error(message);
+					}
+
+					return null;
+				}
+			}
+		}
+	}
+	else if(format.type === "date") {
+		formattedValue = utilities.parseDate(value);
+
+		if(!utilities.isDate(formattedValue)) {
+			errorMessage = "Invalid date value: \"" + utilities.toString(value) + "\".";
+		}
+	}
+	else if(format.type === "regex") {
+		if(utilities.isRegularExpression(value)) {
+			formattedValue = utilities.clone(value);
+		}
+		else {
+			if(options.throwErrors) {
+				formattedValue = utilities.parseRegularExpression(value, true);
+			}
+			else {
+				try {
+					formattedValue = utilities.parseRegularExpression(value, true);
+				}
+				catch(error) {
+					errorMessage = error.message;
+				}
+			}
+		}
+
+		if(utilities.isInvalid(formattedValue)) {
+			errorMessage = "Invalid regular expression value: \"" + utilities.toString(value) + "\".";
+		}
+	}
+	else if(format.type === "function") {
+		formattedValue = value;
+
+		if(!utilities.isFunction(formattedValue)) {
+			errorMessage = "Invalid function value: \"" + utilities.toString(value) + "\".";
+		}
+	}
+
+	if(utilities.isInvalid(errorMessage)) {
+		if(format.type === "object") {
+			if(utilities.isValid(value)) {
+				if(typeof value === "string") {
+					try {
+						formattedValue = JSON.parse(value);
+
+						if(!utilities.isObject(formattedValue, format.strict)) {
+							errorMessage = "Invalid stringified object value type - expected " + (format.strict ? "strict " : "") + "object: \"" + utilities.toString(value) + "\"."
+						}
+					}
+					catch(error) {
+						errorMessage = "Invalid stringified object value: \"" + utilities.toString(value) + "\".";
+					}
+				}
+				else if(utilities.isObject(value, format.strict)) {
+					formattedValue = utilities.clone(value);
+				}
+				else {
+					errorMessage = "Invalid value type - expected " + (format.strict ? "strict " : "") + "object or stringified object: \"" + utilities.toString(value) + "\".";
+				}
+			}
+
+			if(utilities.isInvalid(errorMessage)) {
+				if(utilities.isInvalid(formattedValue)) {
+					if(format.autopopulate && !utilities.isObject(formattedValue, format.strict)) {
+						formattedValue = { };
+					}
+				}
+
+				if(utilities.isObjectStrict(format.format) && utilities.isObject(formattedValue)) {
+					var attribute = null;
+					var attributes = Object.keys(format.format);
+
+					for(var i = 0; i < attributes.length; i++) {
+						attribute = attributes[i];
+
+						if(options.throwErrors) {
+							var formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], options);
+
+							if(formattedAttribute !== undefined) {
+								formattedValue[attribute] = formattedAttribute;
+							}
+						}
+						else {
+							var subOptions = utilities.clone(options);
+
+							subOptions.throwErrors = true;
+
+							try {
+								var formattedAttribute = utilities.formatValue(formattedValue[attribute], format.format[attribute], subOptions);
+
+								if(formattedAttribute !== undefined) {
+									formattedValue[attribute] = formattedAttribute;
+								}
+							}
+							catch(error) {
+								if(options.verbose) {
+									console.error(error.message);
+								}
+
+								return null;
+							}
+						}
+					}
+
+					if(format.removeExtra) {
+						var newValue = { };
+
+						attributes = Object.keys(formattedValue);
+
+						for(var i = 0; i < attributes.length; i++) {
+							attribute = attributes[i];
+
+							if(utilities.isValid(format.format[attribute])) {
+								newValue[attribute] = formattedValue[attribute];
+							}
+						}
+
+						formattedValue = newValue;
+					}
+
+					if(format.order) {
+						var orderedObject = { };
+
+						attributes = Object.keys(format.format);
+
+						for(var i = 0; i < attributes.length; i++) {
+							attribute = attributes[i];
+
+							if(formattedValue[attribute] !== undefined) {
+								orderedObject[attribute] = formattedValue[attribute];
+
+								delete formattedValue[attribute];
+							}
+						}
+
+						var extraAttributes = Object.keys(formattedValue);
+
+						for(var i = 0; i < extraAttributes.length; i++) {
+							attribute = extraAttributes[i];
+
+							orderedObject[attribute] = formattedValue[attribute];
+						}
+
+						formattedValue = orderedObject;
+					}
+				}
+
+				if(format.nonEmpty && utilities.isEmptyObject(formattedValue)) {
+					var message = "Object value must contain at least one attribute.";
+
+					if(options.throwErrors) {
+						throw new Error(message);
+					}
+					else if(options.verbose) {
+						console.error(message);
+					}
+
+					return null;
+				}
+			}
+		}
+	}
+
+	if(utilities.isValid(errorMessage)) {
+		if(options.throwErrors) {
+			throw new Error(errorMessage);
+		}
+		else if(options.verbose) {
+			console.error(errorMessage);
+		}
+
+		return null;
+	}
+
+	if(formattedValue === undefined) {
+		if(format.required) {
+			var message = "Missing required value!";
+
+			if(options.throwErrors) {
+				throw new Error(message);
+			}
+			else if(options.verbose) {
+				console.error(message);
+			}
+
+			return null;
+		}
+
+		if(format.default !== undefined) {
+			formattedValue = utilities.clone(format.default);
+		}
+	}
+
+	if(utilities.isFunction(format.validator)) {
+		if(options.throwErrors) {
+			if(!format.validator(formattedValue, format, options)) {
+				throw new Error("Validation check failed!");
+			}
+		}
+		else {
+			try {
+				if(!format.validator(formattedValue, format, options)) {
+					var message = "Validation check failed!";
+
+					if(options.verbose) {
+						console.error(message);
+					}
+
+					return null;
+				}
+			}
+			catch(error) {
+				if(options.verbose) {
+					console.error(error.message);
+				}
+
+				return null;
+			}
+		}
+	}
+
+	if(utilities.isFunction(format.formatter)) {
+		if(options.throwErrors) {
+			formattedValue = format.formatter(formattedValue, format, options);
+		}
+		else {
+			try {
+				formattedValue = format.formatter(formattedValue, format, options);
+			}
+			catch(error) {
+				if(options.verbose) {
+					console.error(error.message);
+				}
+
+				return null;
+			}
+		}
+	}
+
+	return formattedValue;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function formatObject
+ * @param {Object} object - The object to format.
+ * @param {Object} format - The format specification.
+ * @param {(boolean|Object)} [removeExtra=false] - Remove extra flag or formatting options object.
+ * @param {boolean} [throwErrors=false] - Remove extra flag or formatting options object.
+ * @returns {Object} The formatted object.
+ * @deprecated Use formatValue instead. Will be removed in a future release.
+ * @see {@link module:utilities.formatValue|formatValue}
+ * @since 1.1.1
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.formatObject()); // TODO_RESULT
+ */
+utilities.formatObject = function formatObject(object, format, removeExtra, throwErrors) {
+	if(!utilities.isObjectStrict(object) && (!utilities.isObjectStrict(removeExtra) || !utilities.isFunction(removeExtra.parser))) {
+		return { };
+	}
+
+	var options = null;
+
+	if(utilities.isObjectStrict(removeExtra)) {
+		options = {
+			throwErrors: utilities.parseBoolean(removeExtra.throwErrors, utilities.parseBoolean(throwErrors, false)),
+			verbose: utilities.parseBoolean(removeExtra.verbose, false)
+		};
+	}
+	else {
+		options = {
+			throwErrors: utilities.parseBoolean(throwErrors, false),
+			verbose: false
+		};
+	}
+
+	var subFormat = {
+		type: "object",
+		strict: false,
+		autopopulate: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.autopopulate, false) : false,
+		order: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.order, false) : false,
+		removeExtra: utilities.isObjectStrict(removeExtra) ? utilities.parseBoolean(removeExtra.removeExtra, utilities.parseBoolean(removeExtra, false)) : utilities.parseBoolean(removeExtra, false),
+		nullable: true,
+		required: false,
+		format: format
+	};
+
+	if(utilities.isObjectStrict(removeExtra)) {
+		if(utilities.isFunction(removeExtra.parser)) {
+			subFormat.parser = removeExtra.parser;
+		}
+
+		if(utilities.isFunction(removeExtra.validator)) {
+			subFormat.validator = removeExtra.validator;
+		}
+
+		if(utilities.isFunction(removeExtra.formatter)) {
+			subFormat.formatter = removeExtra.formatter;
+		}
+	}
+
+	var formattedObject = null;
+
+	if(options.throwErrors) {
+		formattedObject = utilities.formatValue(
+			object,
+			subFormat,
+			options
+		);
+	}
+	else {
+		var subOptions = utilities.clone(options);
+
+		subOptions.throwErrors = true;
+
+		try {
+			formattedObject = utilities.formatValue(
+				object,
+				subFormat,
+				subOptions
+			);
+		}
+		catch(error) {
+			if(options.verbose) {
+				console.error(error.message);
+			}
+
+			return null;
+		}
+	}
+
+	return utilities.isObjectStrict(formattedObject) || (utilities.isObjectStrict(removeExtra) && utilities.isFunction(removeExtra.parser)) ? formattedObject : { };
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function formatStringList
+ * @param {(string|string[])} value - The string list to format.
+ * @param {(boolean|null)} stringify - TODO_ARG_DESC
+ * @returns {string} The formatted string list.
+ * @see {@link module:utilities.parseStringList|parseStringList}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.formatStringList()); // TODO_RESULT
+ */
+utilities.formatStringList = function formatStringList(value, stringify) {
+	var data = null;
+
+	if(utilities.isNonEmptyString(value)) {
+		data = utilities.parseStringList(value);
+	}
+	else if(utilities.isNonEmptyArray(value)) {
+		data = value;
+	}
+	else if(typeof value === "string" || Array.isArray(value)) {
+		return "";
+	}
+	else {
+		return null;
+	}
+
+	var formattedList = "";
+	var formattedValue = null;
+
+	stringify = utilities.parseBoolean(stringify);
+
+	for(var i = 0; i < data.length; i++) {
+		if(typeof data[i] !== "string") {
+			if(stringify === null) {
+				continue;
+			}
+			else if(stringify) {
+				formattedValue = utilities.toString(data[i]);
+			}
+			else {
+				formattedValue = data[i];
+			}
+		}
+		else {
+			formattedValue = data[i].trim();
+		}
+
+		if(formattedValue.length === 0) {
+			continue;
+		}
+
+		if(formattedList.length > 0) {
+			formattedList += ", ";
+		}
+
+		formattedList += formattedValue;
+	}
+
+	return formattedList;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function leftShift
+ * @param {number} number - The number value to bit shift.
+ * @param {number} bits - The number of bits to shift the value left by.
+ * @returns {number} The number value right shifted by the specified number of bits.
+ * @see {@link module:utilities.rightShift|rightShift}
+ * @since 1.2.19
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.leftShift()); // TODO_RESULT
+ */
+utilities.leftShift = function leftShift(number, bits) {
+	if(!Number.isInteger(number) || !Number.isInteger(bits)) {
+		return NaN;
+	}
+
+	return number * Math.pow(2, bits);
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function rightShift
+ * @param {number} number - The number value to bit shift.
+ * @param {number} bits - The number of bits to shift the value right by.
+ * @returns {number} The number value right shifted by the specified number of bits.
+ * @see {@link module:utilities.leftShift|leftShift}
+ * @since 1.2.19
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.rightShift()); // TODO_RESULT
+ */
+utilities.rightShift = function rightShift(number, bits) {
+	if(!Number.isInteger(number) || !Number.isInteger(bits)) {
+		return NaN;
+	}
+
+	return number / Math.pow(2, bits);
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function trimString
+ * @param {string} value - The string to trim.
+ * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.isEmptyString|isEmptyString}
+ * @see {@link module:utilities.isNonEmptyString|isNonEmptyString}
+ * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString}
+ * @see {@link module:utilities.trimWhitespace|trimWhitespace}
+ * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines}
+ * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.trimString()); // TODO_RESULT
+ */
+utilities.trimString = function trimString(value, defaultValue) {
+	return typeof value === "string" ? value.trim() : (typeof defaultValue === "string" ? defaultValue : null);
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function trimNullTerminatedString
+ * @param {string} value - The null-terminated string to trim.
+ * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.isEmptyString|isEmptyString}
+ * @see {@link module:utilities.isNonEmptyString|isNonEmptyString}
+ * @see {@link module:utilities.trimString|trimString}
+ * @see {@link module:utilities.trimWhitespace|trimWhitespace}
+ * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines}
+ * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.trimNullTerminatedString()); // TODO_RESULT
+ */
+utilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) {
+	if(typeof value !== "string") {
+		return typeof defaultValue === "string" ? defaultValue : null;
+	}
+
+	var nullTerminatorIndex = value.indexOf("\0");
+
+	if(nullTerminatorIndex >= 0) {
+		return value.substr(0, nullTerminatorIndex);
+	}
+
+	return value;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function trimWhitespace
+ * @param {string} value - The string to trim whitespace characters from.
+ * @param {boolean} trimNewlines - TODO_ARG_DESC.
+ * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.isEmptyString|isEmptyString}
+ * @see {@link module:utilities.isNonEmptyString|isNonEmptyString}
+ * @see {@link module:utilities.trimString|trimString}
+ * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString}
+ * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines}
+ * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.trimWhitespace()); // TODO_RESULT
+ */
+utilities.trimWhitespace = function trimWhitespace(value, trimNewlines, defaultValue) {
+	if(typeof value !== "string") {
+		return typeof defaultValue === "string" ? defaultValue : null;
+	}
+
+	var trimmedString = value.replace(/^[ \t]+|[ \t]+$/gm, "");
+
+	if(utilities.parseBoolean(trimNewlines, false)) {
+		trimmedString = trimmedString.replace(/\r\n?|\n/g, "");
+	}
+
+	return trimmedString;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function trimTrailingNewlines
+ * @param {string} value - The string to trim trailing newline characters from.
+ * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.isEmptyString|isEmptyString}
+ * @see {@link module:utilities.isNonEmptyString|isNonEmptyString}
+ * @see {@link module:utilities.trimString|trimString}
+ * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString}
+ * @see {@link module:utilities.trimWhitespace|trimWhitespace}
+ * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces}
+ * @since 1.1.5
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.trimTrailingNewlines()); // TODO_RESULT
+ */
+utilities.trimTrailingNewlines = function trimTrailingNewlines(value, defaultValue) {
+	if(typeof value !== "string") {
+		return typeof defaultValue === "string" ? defaultValue : null;
+	}
+
+	if(utilities.isEmptyString(value)) {
+		return value;
+	}
+
+	return value.replace(/[ \t\r\n]+$/, "");
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function replaceNonBreakingSpaces
+ * @param {string} value - The string to replace non breaking spaces in.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.isEmptyString|isEmptyString}
+ * @see {@link module:utilities.isNonEmptyString|isNonEmptyString}
+ * @see {@link module:utilities.trimString|trimString}
+ * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString}
+ * @see {@link module:utilities.trimWhitespace|trimWhitespace}
+ * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.replaceNonBreakingSpaces()); // TODO_RESULT
+ */
+utilities.replaceNonBreakingSpaces = function replaceNonBreakingSpaces(value) {
+	return typeof value === "string" ? value.replace(/&nbsp;/gi, " ") : null;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function indentText
+ * @param {string} value - The string to indent.
+ * @param {number} [amount=1] - The amount of times  to indent the string.
+ * @param {indentation} [indentation="\t"] - The indentation string to use.
+ * @param {boolean} [clearEmptyLines=true] - Determines if empty lines should be trimmed or not.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.indentText()); // TODO_RESULT
+ */
+utilities.indentText = function indentText(value, amount, indentation, clearEmptyLines) {
+	if(typeof value !== "string") {
+		return null;
+	}
+
+	clearEmptyLines = utilities.parseBoolean(clearEmptyLines, true);
+
+	amount = utilities.parseInteger(amount, 1);
+
+	if(amount < 0) {
+		amount = 0;
+	}
+
+	indentation = typeof indentation === "string" ? indentation : "\t";
+
+	var totalIndentation = "";
+
+	for(var i = 0; i < amount; i++) {
+		totalIndentation += indentation;
+	}
+
+	var line = null;
+	var lines = value.split(/\r\n?|\n/g);
+	var indentedParagraph = "";
+
+	for(var i = 0; i < lines.length; i++) {
+		line = lines[i];
+
+		indentedParagraph += (utilities.isEmptyString(line) && clearEmptyLines ? "" : totalIndentation + line) + ((i < lines.length - 1) ? "\n" : "");
+	}
+
+	return indentedParagraph;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function trimLeadingZeroes
+ * @param {string} value - The string to remove leading zeroes from.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.addLeadingZeroes|addLeadingZeroes}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.trimLeadingZeroes()); // TODO_RESULT
+ */
+utilities.trimLeadingZeroes = function trimLeadingZeroes(value) {
+	if(typeof value !== "string") {
+		return null;
+	}
+
+	if(value.length === 0) {
+		return value;
+	}
+
+	var formattedValue = value.trim();
+
+	if(formattedValue.length === 0) {
+		return formattedValue;
+	}
+	else if(formattedValue.match(/^[0]+$/)) {
+		return "0";
+	}
+
+	return formattedValue.replace(/^0+/, "");
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function addLeadingZeroes
+ * @param {string} value - The string to add leading zeroes to.
+ * @param {number} [expectedLength=NaN] - The expected minimum length of the string after zeroes have been prepended to it.
+ * @returns {(string|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.trimLeadingZeroes|trimLeadingZeroes}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.addLeadingZeroes()); // TODO_RESULT
+ */
+utilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) {
+	if(utilities.isInvalid(value)) {
+		return null;
+	}
+
+	value = value.toString();
+	expectedLength = utilities.parseInteger(expectedLength);
+
+	if(utilities.isInvalidNumber(expectedLength) || expectedLength < 0) {
+		return value;
+	}
+
+	var numberOfZeroes = expectedLength - value.length;
+
+	for(var i = 0; i < numberOfZeroes; i++) {
+		value = "0" + value;
+	}
+
+	return value;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function toString
+ * @param {any} value - The value to convert into a string.
+ * @returns {string} A string representation of the specified value.
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.toString(undefined)); // "undefined"
+ * console.log(utilities.toString(null)); // "null"
+ * console.log(utilities.toString(Infinity)); // "Infinity"
+ * console.log(utilities.toString(-Infinity)); // "-Infinity"
+ * console.log(utilities.toString(NaN)); // "NaN"
+ * console.log(utilities.toString("test")); // "\"test\""
+ * console.log(utilities.toString(new Date(0))); // "1970-01-01T00:00:00.000Z"
+ * console.log(utilities.toString(function() { })); // "function() { }"
+ * console.log(utilities.toString({ door: "stuck" })); // "{\"door":\"stuck\"}"
+ * console.log(utilities.toString([4, 2, "0"])); // "[4,2,\"0\"]"
+ */
+utilities.toString = function toString(value) {
+	if(value === undefined) {
+		return "undefined";
+	}
+	else if(value === null) {
+		return "null";
+	}
+	else if(typeof value === "string") {
+		return value;
+	}
+	else if(value === Infinity) {
+		return "Infinity";
+	}
+	else if(value === -Infinity) {
+		return "-Infinity";
+	}
+	else if(typeof value === "number" && isNaN(value)) {
+		return "NaN";
+	}
+	else if(value instanceof Date) {
+		return value.toString();
+	}
+	else if(value instanceof RegExp) {
+		var flags = "";
+
+		for(var flag in regExpFlags) {
+			if(value[flag]) {
+				flags += regExpFlags[flag];
+			}
+		}
+
+		return "/" + value.source + "/" + flags;
+	}
+	else if(value instanceof Function) {
+		return value.toString();
+	}
+	else if(value instanceof Error) {
+		return value.stack;
+	}
+
+	return JSON.stringify(value);
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function compareDates
+ * @param {any} a - The first date to compare.
+ * @param {any} b - The second date to compare.
+ * @returns {number} TODO_RETURN_DESC
+ * @see {@link module:utilities.isDate|isDate}
+ * @see {@link module:utilities.parseDate|parseDate}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.compareDates()); // TODO_RESULT
+ */
+utilities.compareDates = function compareDates(a, b) {
+	a = utilities.parseDate(a);
+	b = utilities.parseDate(b);
+
+	if(a === null && b === null) {
+		return 0;
+	}
+
+	if(a === null) {
+		return -1;
+	}
+	else if(b === null) {
+		return 1;
+	}
+
+	return a.getTime() - b.getTime();
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function compareCasePercentage
+ * @param {string} value - The string value to compare the case percentage of.
+ * @returns {number} TODO_RETURN_DESC
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.compareCasePercentage()); // TODO_RESULT
+ */
+utilities.compareCasePercentage = function compareCasePercentage(value) {
+	if(utilities.isEmptyString(value)) {
+		return 0;
+	}
+
+	var c = null;
+	var upper = 0;
+	var lower = 0;
+	var lowerA = "a".charCodeAt();
+	var lowerZ = "z".charCodeAt();
+	var upperA = "A".charCodeAt();
+	var upperZ = "Z".charCodeAt();
+
+	for(var i = 0; i < value.length; i++) {
+		c = value.charCodeAt(i);
+
+		if(c >= lowerA && c <= lowerZ) {
+			lower++;
+		}
+		else if(c >= upperA && c <= upperZ) {
+			upper++;
+		}
+	}
+
+	return upper - lower;
+};
+
+/**
+ * Reverses a string value with special handling for unicode characters.
+ *
+ * @function reverseString
+ * @param {string} value - The string value to reverse.
+ * @returns {(string|null)} The reversed representation of the specified string value or a value of null if the specified value is not a string.
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.reverseString("backwards")); // "sdrawkcab"
+ * console.log(utilities.reverseString(NaN)); // null
+ */
+utilities.reverseString = function reverseString(value) {
+	if(typeof value !== "string") {
+		return null;
+	}
+
+	value = value.replace(
+		/([\0-\u02FF\u0370-\u1AAF\u1B00-\u1DBF\u1E00-\u20CF\u2100-\uD7FF\uE000-\uFE1F\uFE30-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])([\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]+)/g,
+		function($0, $1, $2) {
+			return utilities.reverseString($2) + $1;
+		}
+	).replace(/([\uD800-\uDBFF])([\uDC00-\uDFFF])/g, "$2$1");
+
+	var reverse = "";
+
+	for(var i = value.length - 1; i >= 0; i--) {
+		reverse += value[i];
+	}
+
+	return reverse;
+};
+
+/**
+ * Creates an Error object instance with the specified message and HTTP status code.
+ *
+ * @function createError
+ * @param {string} message - The error message.
+ * @param {number} [status=500] - The HTTP status code of the error.
+ * @returns {Error} The error with the specified message and status code property.
+ * @deprecated Use new Error() instead. Will be removed in a future release.
+ * @see {@link module:utilities.isError|isError}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.createError("COOL HATS ONLY.", 401)); // new Error("COOL HATS ONLY.") (with status property set to 401)
+ */
+utilities.createError = function createError(message, status) {
+	var error = new Error(message);
+	error.status = utilities.parseInteger(status, 500);
+	return error;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function clone
+ * @param {any} value - The value to clone.
+ * @returns {any} A copy of the specified value.
+ * @see {@link module:utilities.merge|merge}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.clone({ some: "value" })); // {"some":"value"}
+ */
+utilities.clone = function clone(value) {
+	if(!utilities.isObject(value)) {
+		return value;
+	}
+	else if(value instanceof Boolean) {
+		return new Boolean(value.valueOf());
+	}
+	else if(value instanceof Date) {
+		var copy = new Date();
+		copy.setTime(value.getTime());
+
+		return copy;
+	}
+	else if(value instanceof Array) {
+		var copy = [];
+
+		for(var i = 0, length = value.length; i < length; i++) {
+			copy[i] = utilities.clone(value[i]);
+		}
+
+		return copy;
+	}
+	else if(value instanceof Set) {
+		return new Set(value);
+	}
+	else if(value instanceof Map) {
+		return new Map(value);
+	}
+	else if(value instanceof RegExp) {
+		var flags = "";
+
+		for(var flag in regExpFlags) {
+			if(value[flag]) {
+				flags += regExpFlags[flag]
+			}
+		}
+
+		return new RegExp(value.source, flags);
+	}
+	else if(typeof Buffer !== "undefined" && value instanceof Buffer) {
+		return Buffer.from instanceof Function ? Buffer.from(value) : new Buffer(value);
+	}
+	else if(value instanceof Object) {
+		var copy = null;
+
+		if(value instanceof Error) {
+			copy = new Error(value.message);
+
+			copy.stack = utilities.clone(value.stack);
+
+			var properties = Object.keys(value);
+
+			for(var i = 0; i < properties.length; i++) {
+				copy[properties[i]] = utilities.clone(value[properties[i]]);
+			}
+		}
+		else {
+			copy = { };
+		}
+
+		for(var attribute in value) {
+			if(Object.prototype.hasOwnProperty.call(value, attribute)) {
+				copy[attribute] = utilities.clone(value[attribute]);
+			}
+		}
+
+		return copy;
+	}
+
+	return value;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function merge
+ * @param {Object} a - The object to merge into.
+ * @param {Object} b - The object whose properties are being merged.
+ * @param {boolean} [copy=true] - Determines if a copy of the first object should be made before merging.
+ * @param {boolean} [deepMerge=true] - Determines if properties should be recursively merged or just the base properties.
+ * @returns {(Object|null)} TODO_RETURN_DESC
+ * @see {@link module:utilities.clone|clone}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.merge({ a: 1 }, { b: 2 })); // { a: 1, b: 2 }
+ */
+utilities.merge = function merge(a, b, copy, deepMerge) {
+	if(!utilities.isObject(a) || Array.isArray(a)) {
+		return null;
+	}
+
+	var newObject = null;
+
+	copy = utilities.parseBoolean(copy, true);
+
+	if(copy) {
+		newObject = utilities.clone(a);
+	}
+	else {
+		newObject = a;
+	}
+
+	if(!utilities.isObject(a) || Array.isArray(a) || !utilities.isObject(b) || Array.isArray(b)) {
+		return newObject;
+	}
+
+	var attribute = null;
+	var value = null;
+	var newValue = null;
+	var attributes = Object.keys(b);
+
+	deepMerge = utilities.parseBoolean(deepMerge, true);
+
+	for(var i = 0; i < attributes.length; i++) {
+		attribute = attributes[i];
+		value = newObject[attribute];
+
+		if(copy) {
+			newValue = utilities.clone(b[attribute]);
+		}
+		else {
+			newValue = b[attribute];
+		}
+
+		if(deepMerge && utilities.isObject(value) && !Array.isArray(value) && utilities.isObject(newValue) && !Array.isArray(newValue)) {
+			newObject[attribute] = utilities.merge(value, newValue);
+		}
+		else {
+			newObject[attribute] = newValue;
+		}
+	}
+
+	return newObject;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function getFileName
+ * @param {string} filePath - A file path string to retrieve the file name from.
+ * @returns {(string|null)} Returns a string value containing the name of the file or null if the file path was not a string.
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.truncateFileName|truncateFileName}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.getFileName("C:\settings.ini")); // "settings.ini"
+ * console.log(utilities.getFileName("/var/tmp/test.txt")); // "test.txt"
+ * console.log(utilities.getFileName("MyApp.wgt")); // "MyApp.wgt"
+ * console.log(utilities.getFileName(NaN)); // null
+ */
+utilities.getFileName = function getFileName(filePath) {
+	if(typeof filePath !== "string") {
+		return null;
+	}
+
+	filePath = filePath.trim();
+
+	for(var i = filePath.length - 1; i >= 0; i--) {
+		if(filePath[i] === "/" || filePath[i] === "\\") {
+			return filePath.substring(i + 1, filePath.length).trim();
+		}
+	}
+
+	return filePath;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function getFilePath
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.truncateFileName|truncateFileName}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.getFilePath()); // TODO_RESULT
+ */
+utilities.getFilePath = function getFilePath(filePath) {
+	if(typeof filePath !== "string") {
+		return null;
+	}
+
+	filePath = filePath.trim();
+
+	for(var i = filePath.length - 1; i >= 0; i--) {
+		if(filePath[i] === "/" || filePath[i] === "\\") {
+			return filePath.substring(0, i).trim();
+		}
+	}
+
+	return "";
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function getFileNameNoExtension
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.truncateFileName|truncateFileName}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.getFileNameNoExtension()); // TODO_RESULT
+ */
+utilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) {
+	if(typeof fileName !== "string") {
+		return null;
+	}
+
+	fileName = utilities.getFileName(fileName);
+
+	for(var i = fileName.length - 1; i >= 0; i--) {
+		if(fileName[i] === ".") {
+			return fileName.substring(0, i).trim();
+		}
+	}
+
+	return fileName;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function getFileExtension
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.truncateFileName|truncateFileName}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.getFileExtension()); // TODO_RESULT
+ */
+utilities.getFileExtension = function getFileExtension(fileName) {
+	if(typeof fileName !== "string") {
+		return null;
+	}
+
+	fileName = utilities.getFileName(fileName);
+
+	for(var i = fileName.length - 1; i >= 0; i--) {
+		if(fileName[i] === ".") {
+			return fileName.substring(i + 1, fileName.length).trim();
+		}
+	}
+
+	return "";
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function fileHasExtension
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.truncateFileName|truncateFileName}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.fileHasExtension()); // TODO_RESULT
+ */
+utilities.fileHasExtension = function fileHasExtension(fileName, extension) {
+	if(utilities.isEmptyString(fileName) || utilities.isEmptyString(extension)) {
+		return false;
+	}
+
+	var actualFileExtension = utilities.getFileExtension(fileName);
+
+	if(utilities.isEmptyString(actualFileExtension)) {
+		return false;
+	}
+
+	return actualFileExtension.toLowerCase() === extension.trim().toLowerCase();
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function reverseFileExtension
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.truncateFileName|truncateFileName}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.reverseFileExtension()); // TODO_RESULT
+ */
+utilities.reverseFileExtension = function reverseFileExtension(fileName) {
+	if(typeof fileName !== "string") {
+		return null;
+	}
+
+	fileName = fileName.trim();
+
+	for(var i = fileName.length - 1; i >= 0; i--) {
+		if(fileName[i] === ".") {
+			return fileName.substring(0, i) + "." + utilities.reverseString(fileName.substring(i + 1, fileName.length));
+		}
+	}
+
+	return fileName;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function truncateFileName
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @since 1.2.18
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.truncateFileName()); // TODO_RESULT
+ */
+utilities.truncateFileName = function truncateFileName(fileName, maxLength) {
+	if(typeof fileName !== "string") {
+		return null;
+	}
+
+	fileName = utilities.getFileName(fileName);
+
+	if(utilities.isEmptyString(fileName)) {
+		return "";
+	}
+
+	maxLength = utilities.parseInteger(maxLength);
+
+	if(utilities.isInvalidNumber(maxLength) || maxLength < 0) {
+		return fileName;
+	}
+
+	if(maxLength === 0) {
+		return "";
+	}
+
+	if(fileName.length <= maxLength) {
+		return fileName;
+	}
+
+	var extension = "";
+	var originalFileName = fileName;
+
+	for(var i = fileName.length - 1; i >= 0; i--) {
+		if(fileName[i] === ".") {
+			extension = fileName.substring(i + 1, fileName.length);
+			originalFileName = fileName.substring(0, i);
+			break;
+		}
+	}
+
+	if(maxLength - (extension.length + (extension.length > 0 ? 1 : 0)) < 1) {
+		return originalFileName.substring(0, maxLength);
+	}
+
+	return originalFileName.substring(0, maxLength - extension.length - (extension.length > 0 ? 1 : 0)) + (extension.length > 0 ? "." + extension : "");
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function prependSlash
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @see {@link module:utilities.appendSlash|appendSlash}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.prependSlash()); // TODO_RESULT
+ */
+utilities.prependSlash = function prependSlash(value) {
+	if(typeof value !== "string") {
+		return null;
+	}
+
+	var formattedValue = value.trim();
+
+	if(formattedValue.length === 0) {
+		return formattedValue;
+	}
+
+	if(formattedValue[0] !== "/" && formattedValue[0] !== "\\") {
+		formattedValue = "/" + formattedValue;
+	}
+
+	return formattedValue;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function appendSlash
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @see {@link module:utilities.prependSlash|prependSlash}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.appendSlash()); // TODO_RESULT
+ */
+utilities.appendSlash = function appendSlash(value) {
+	if(typeof value !== "string") {
+		return null;
+	}
+
+	var formattedValue = value.trim();
+
+	if(formattedValue.length === 0) {
+		return formattedValue;
+	}
+
+	if(formattedValue[formattedValue.length - 1] !== "/" && formattedValue[formattedValue.length - 1] !== "\\") {
+		formattedValue += "/";
+	}
+
+	return formattedValue;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function joinPaths
+ * @param {...string|string[]} paths - TODO_ARG_DESC.
+ * @param {Object} [options] - TODO_ARG_DESC.
+ * @returns {string} TODO_RETURN_DESC
+ * @see {@link module:utilities.getFileName|getFileName}
+ * @see {@link module:utilities.getFilePath|getFilePath}
+ * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension}
+ * @see {@link module:utilities.getFileExtension|getFileExtension}
+ * @see {@link module:utilities.fileHasExtension|fileHasExtension}
+ * @see {@link module:utilities.reverseFileExtension|reverseFileExtension}
+ * @see {@link module:utilities.joinPaths|joinPaths}
+ * @see {@link module:utilities.prependSlash|prependSlash}
+ * @see {@link module:utilities.appendSlash|appendSlash}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.joinPaths()); // TODO_RESULT
+ */
+utilities.joinPaths = function joinPaths(paths, options) {
+	if(!Array.isArray(paths)) {
+		paths = Array.prototype.slice.call(arguments);
+	}
+
+	if(paths.length !== 0 && utilities.isObjectStrict(paths[paths.length - 1])) {
+		options = paths.splice(paths.length - 1, 1)[0];
+	}
+
+	if(!utilities.isObjectStrict(options)) {
+		options = { };
+	}
+
+	options.separator = utilities.trimString(options.separator);
+
+	if(options.separator !== "/" && options.separator !== "\\") {
+		options.separator = "/";
+	}
+
+	var newPath = "";
+
+	for(var i = 0; i < paths.length; i++) {
+		var path = utilities.trimString(paths[i]);
+
+		if(utilities.isEmptyString(path)) {
+			continue;
+		}
+
+		if(utilities.isEmptyString(newPath)) {
+			if(path === "/" || path === "\\") {
+				newPath = path;
+			}
+			else {
+				newPath = path.replace(/[\/\\]+$/, "");
+			}
+		}
+		else {
+			path = path.replace(/^[\/\\]+/, "");
+
+			if(utilities.isNonEmptyString(path)) {
+				if(newPath[newPath.length - 1] !== options.separator) {
+					newPath += options.separator;
+				}
+
+				newPath += path;
+			}
+		}
+	}
+
+	return newPath.replace(/[\/\\]/g, options.separator);
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function createQueryString
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.createQueryString()); // TODO_RESULT
+ */
+utilities.createQueryString = function createQueryString(value, includeQuestionMark) {
+	if(!utilities.isObjectStrict(value)) {
+		return "";
+	}
+
+	var parameters = Object.keys(value).map(function(key) {
+		return encodeURIComponent(key) + "=" + encodeURIComponent(utilities.toString(value[key]));
+	}).join("&");
+
+	if(parameters.length === 0) {
+		return "";
+	}
+
+	return (utilities.parseBoolean(includeQuestionMark, false) ? "?" : "") + parameters;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function createRange
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @deprecated Determined to no longer be useful, will be removed in a future release.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.createRange()); // TODO_RESULT
+ */
+utilities.createRange = function createRange(start, end) {
+	var formattedStart = utilities.parseInteger(start);
+	var formattedEnd = utilities.parseInteger(end);
+
+	if(arguments.length === 1) {
+		formattedEnd = formattedStart;
+		formattedStart = 0;
+	}
+
+	if(utilities.isInvalidNumber(formattedStart) || utilities.isInvalidNumber(formattedEnd) || formattedStart > formattedEnd) {
+		return [];
+	}
+
+	var range = [];
+
+	for(var i = formattedStart; i <= formattedEnd; i++) {
+		range.push(i);
+	}
+
+	return range;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function futureMonths
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.futureMonths()); // TODO_RESULT
+ */
+utilities.futureMonths = function futureMonths(date, prependZero) {
+	date = utilities.parseDate(date);
+
+	if(date === null) {
+		return null;
+	}
+
+	var currentDate = new Date();
+	var month = 0;
+
+	if(date.getFullYear() === currentDate.getFullYear()) {
+		month = currentDate.getMonth();
+	}
+
+	var months = [];
+
+	prependZero = utilities.parseBoolean(prependZero, false);
+
+	for(var i = 0; i < 12; i++) {
+		if(i >= month) {
+			if(prependZero) {
+				months.push((i <= 8 ? "0" : "") + (i + 1));
+			}
+			else {
+				months.push(i + 1);
+			}
+		}
+	}
+
+	return months;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function visibleElements
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @see {@link module:utilities.hiddenElements|hiddenElements}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.visibleElements()); // TODO_RESULT
+ */
+utilities.visibleElements = function visibleElements(elements) {
+	if(!Array.isArray(elements)) {
+		return [];
+	}
+
+	var visibleElements = [];
+
+	for(var i = 0; i < elements.length; i++) {
+		if(utilities.isVisible(elements[i])) {
+			visibleElements.push(elements[i]);
+		}
+	}
+
+	return visibleElements;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function hiddenElements
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @see {@link module:utilities.visibleElements|visibleElements}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.hiddenElements()); // TODO_RESULT
+ */
+utilities.hiddenElements = function hiddenElements(elements) {
+	if(!Array.isArray(elements)) {
+		return [];
+	}
+
+	var hiddenElements = [];
+
+	for(var i = 0; i < elements.length; i++) {
+		if(utilities.isHidden(elements[i])) {
+			hiddenElements.push(elements[i]);
+		}
+	}
+
+	return hiddenElements;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function enabledElements
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @see {@link module:utilities.disabledElements|disabledElements}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.enabledElements()); // TODO_RESULT
+ */
+utilities.enabledElements = function enabledElements(elements) {
+	if(!Array.isArray(elements)) {
+		return [];
+	}
+
+	var enabledElements = [];
+
+	for(var i = 0; i < elements.length; i++) {
+		if(utilities.isEnabled(elements[i])) {
+			enabledElements.push(elements[i]);
+		}
+	}
+
+	return enabledElements;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function disabledElements
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @see {@link module:utilities.enabledElements|enabledElements}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.disabledElements()); // TODO_RESULT
+ */
+utilities.disabledElements = function disabledElements(elements) {
+	if(!Array.isArray(elements)) {
+		return [];
+	}
+
+	var disabledElements = [];
+
+	for(var i = 0; i < elements.length; i++) {
+		if(utilities.isDisabled(elements[i])) {
+			disabledElements.push(elements[i]);
+		}
+	}
+
+	return disabledElements;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function elementsWithAttribute
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @see {@link module:utilities.elementsWithoutAttribute|elementsWithoutAttribute}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.elementsWithAttribute()); // TODO_RESULT
+ */
+utilities.elementsWithAttribute = function elementsWithAttribute(elements, attribute, hasAttribute) {
+	if(!Array.isArray(elements) || utilities.isEmptyString(attribute)) {
+		return [];
+	}
+
+	var element = null;
+	var filteredElements = [];
+
+	attribute = attribute.trim();
+	hasAttribute = utilities.parseBoolean(hasAttribute, true);
+
+	for(var i = 0; i < elements.length; i++) {
+		element = elements[i];
+
+		if(!utilities.isObject(element)) {
+			continue;
+		}
+
+		if(utilities.isInvalid(elements[i][attribute])) {
+			if(!hasAttribute) {
+				filteredElements.push(element);
+			}
+		}
+		else {
+			if(hasAttribute) {
+				filteredElements.push(elements[i]);
+			}
+		}
+	}
+
+	return filteredElements;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function elementsWithoutAttribute
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @see {@link module:utilities.elementsWithAttribute|elementsWithAttribute}
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.elementsWithoutAttribute()); // TODO_RESULT
+ */
+utilities.elementsWithoutAttribute = function elementsWithoutAttribute(elements, attribute) {
+	return utilities.elementsWithAttribute(elements, attribute, false);
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function matchAttribute
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @deprecated Use Array.filter() instead. Will be removed in a future release.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @since 1.0.0
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.matchAttribute()); // TODO_RESULT
+ */
+utilities.matchAttribute = function matchAttribute(element, attribute, value) {
+	if(!utilities.isObject(element)) {
+		return false;
+	}
+
+	if(utilities.isEmptyString(attribute)) {
+		return true;
+	}
+
+	return element[attribute.trim()] === value;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function generateVersions
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.parseVersion|parseVersion}
+ * @see {@link module:utilities.compareVersions|compareVersions}
+ * @since 1.0.3
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.generateVersions()); // TODO_RESULT
+ */
+utilities.generateVersions = function generateVersions(version, prefix, suffix) {
+	version = utilities.parseVersion(version);
+
+	if(version === null) {
+		return null;
+	}
+
+	prefix = utilities.trimString(prefix);
+	suffix = utilities.trimString(suffix);
+
+	var versions = [];
+	var value = null;
+
+	for(var i = 0; i < version.length; i++) {
+		value = "";
+
+		if(utilities.isNonEmptyString(prefix)) {
+			value += prefix;
+		}
+
+		for(var j = 0; j <= i; j++) {
+			if(j > 0) {
+				value += "_";
+			}
+
+			value += version[j];
+		}
+
+		if(utilities.isNonEmptyString(suffix)) {
+			value += suffix;
+		}
+
+		versions.push(value);
+	}
+
+	return versions;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function parseVersion
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.generateVersions|generateVersions}
+ * @see {@link module:utilities.compareVersions|compareVersions}
+ * @since 1.0.3
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.parseVersion()); // TODO_RESULT
+ */
+utilities.parseVersion = function parseVersion(value, trimTrailingZeroes) {
+	var formattedValue = utilities.isValidNumber(value) ? value.toString() : value;
+
+	if(typeof formattedValue !== "string") {
+		return null;
+	}
+
+	var version = [];
+	var versionData = formattedValue.match(/[^. \t]+/g);
+
+	if(versionData === null || versionData.length === 0) {
+		return null;
+	}
+
+	var part = null;
+
+	for(var i = 0; i < versionData.length; i++) {
+		if(utilities.isInteger(versionData[i])) {
+			part = utilities.parseInteger(versionData[i]);
+
+			if(utilities.isInvalidNumber(part) || part < 0) {
+				continue;
+			}
+
+			version.push(part.toString());
+		}
+		else {
+			version.push(versionData[i]);
+		}
+	}
+
+	if(utilities.parseBoolean(trimTrailingZeroes, false)) {
+		while(true) {
+			if(version.length <= 1) {
+				break;
+			}
+
+			if(version[version.length - 1] === "0") {
+				version.pop();
+			}
+			else {
+				break;
+			}
+		}
+	}
+
+	return version.length === 0 ? null : version;
+};
+
+/**
+ * TODO_FUNC_DESC
+ *
+ * @function compareVersions
+ * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC.
+ * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC
+ * @see {@link module:utilities.generateVersions|generateVersions}
+ * @see {@link module:utilities.parseVersion|parseVersion}
+ * @since 1.0.3
+ * @memberOf module:utilities
+ * @example
+ * console.log(utilities.compareVersions()); // TODO_RESULT
+ */
+utilities.compareVersions = function compareVersions(v1, v2, caseSensitive) {
+	caseSensitive = utilities.parseBoolean(caseSensitive, false);
+
+	v1 = utilities.parseVersion(v1);
+
+	if(v1 === null) {
+		throw new Error("Cannot compare invalid or empty first version.");
+	}
+
+	v2 = utilities.parseVersion(v2);
+
+	if(v2 === null) {
+		throw new Error("Cannot compare invalid or empty second version.");
+	}
+
+	var index = 0;
+
+	while(true) {
+		if(index >= v1.length) {
+			if(v1.length === v2.length) {
+				return 0;
+			}
+
+			for(var i = index; i < v2.length; i++) {
+				if(v2[i] !== "0") {
+					return -1;
+				}
+			}
+
+			return 0;
+		}
+
+		if(index >= v2.length) {
+			for(var i = index; i < v1.length; i++) {
+				if(v1[i] !== "0") {
+					return 1;
+				}
+			}
+
+			return 0;
+		}
+
+		var formattedA = utilities.parseInteger(v1[index]);
+		var formattedB = utilities.parseInteger(v2[index]);
+
+		if(utilities.isInvalidNumber(formattedA)) {
+			formattedA = caseSensitive ? v1[index] : v1[index].toUpperCase();
+		}
+
+		if(utilities.isInvalidNumber(formattedB)) {
+			formattedB = caseSensitive ? v2[index] : v2[index].toUpperCase();
+		}
+
+		if(Number.isInteger(formattedA)) {
+			if(!Number.isInteger(formattedB)) {
+				return -1;
+			}
+		}
+		else {
+			if(Number.isInteger(formattedB)) {
+				return 1;
+			}
+		}
+
+		if(formattedA > formattedB) {
+			return 1;
+		}
+		else if(formattedA < formattedB) {
+			return -1;
+		}
+
+		index++;
+	}
+};
+
+module.exports = utilities;
+
+
+
+ + + + + + +
+ +
+ +
+ Documentation generated by JSDoc 3.6.3 on Sun Mar 29 2020 11:42:52 GMT-0400 (Eastern Daylight Time) using the docdash theme. +
+ + + + + + + + + + + diff --git a/docs/fonts/Montserrat/Montserrat-Bold.eot b/docs/fonts/Montserrat/Montserrat-Bold.eot new file mode 100644 index 0000000..f2970bb Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Bold.eot differ diff --git a/docs/fonts/Montserrat/Montserrat-Bold.ttf b/docs/fonts/Montserrat/Montserrat-Bold.ttf new file mode 100644 index 0000000..3bfd79b Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Bold.ttf differ diff --git a/docs/fonts/Montserrat/Montserrat-Bold.woff b/docs/fonts/Montserrat/Montserrat-Bold.woff new file mode 100644 index 0000000..9260765 Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Bold.woff differ diff --git a/docs/fonts/Montserrat/Montserrat-Bold.woff2 b/docs/fonts/Montserrat/Montserrat-Bold.woff2 new file mode 100644 index 0000000..d9940cd Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Bold.woff2 differ diff --git a/docs/fonts/Montserrat/Montserrat-Regular.eot b/docs/fonts/Montserrat/Montserrat-Regular.eot new file mode 100644 index 0000000..735d12b Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Regular.eot differ diff --git a/docs/fonts/Montserrat/Montserrat-Regular.ttf b/docs/fonts/Montserrat/Montserrat-Regular.ttf new file mode 100644 index 0000000..5da852a Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Regular.ttf differ diff --git a/docs/fonts/Montserrat/Montserrat-Regular.woff b/docs/fonts/Montserrat/Montserrat-Regular.woff new file mode 100644 index 0000000..bf91832 Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Regular.woff differ diff --git a/docs/fonts/Montserrat/Montserrat-Regular.woff2 b/docs/fonts/Montserrat/Montserrat-Regular.woff2 new file mode 100644 index 0000000..72d13c6 Binary files /dev/null and b/docs/fonts/Montserrat/Montserrat-Regular.woff2 differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot new file mode 100644 index 0000000..0f24510 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg new file mode 100644 index 0000000..5384f98 --- /dev/null +++ b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg @@ -0,0 +1,978 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf new file mode 100644 index 0000000..e6c158c Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff new file mode 100644 index 0000000..d0a1c29 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 new file mode 100644 index 0000000..d286974 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot new file mode 100644 index 0000000..b420448 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg new file mode 100644 index 0000000..dee0949 --- /dev/null +++ b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg @@ -0,0 +1,1049 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf new file mode 100644 index 0000000..4d56c33 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff new file mode 100644 index 0000000..4681019 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff differ diff --git a/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 new file mode 100644 index 0000000..8ddcae3 Binary files /dev/null and b/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..af5b35c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,128 @@ + + + + + + Home - Documentation + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + +
+

+
+ + + + + + + + + + + + + +
+

Extra Utilities

+

NPM version +Build Status +Coverage Status +Known Vulnerabilities +Dependencies +Downloads +Install Size +Contributors +Pull Requests Welcome

+

A collection of useful JavaScript helper functions.

+

Documentation

+

Work-in-progress API documentation is available here.

+

Web Usage

+
<script src="extra-utilities.js"></script>
+
+<script type="text/javascript">
+	utilities.isBoolean(false); // => true
+</script>
+
+

Node.js Usage

+
const utilities = require("extra-utilities");
+
+utilities.isValidNumber(NaN); // => false
+
+

Installation

+

To install this module:

+
npm install extra-utilities
+
+

Building

+

To build the distribution files for this module:

+
npm run build
+
+

Running Unit Tests

+

To run the unit test suite for this module:

+
npm run test
+
+

Generating Documentation

+
npm run docs
+
+
+ + + + + + + + +
+ +
+ +
+ Documentation generated by JSDoc 3.6.3 on Sun Mar 29 2020 11:42:52 GMT-0400 (Eastern Daylight Time) using the docdash theme. +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/module-utilities.html b/docs/module-utilities.html new file mode 100644 index 0000000..f8d458d --- /dev/null +++ b/docs/module-utilities.html @@ -0,0 +1,15808 @@ + + + + + + utilities - Documentation + + + + + + + + + + + + + + + + + + + +
+ +

utilities

+ + + + + + + +
+ +
+ + + +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + +

Methods

+ + + + + + +

(static) addLeadingZeroes(value, expectedLengthopt) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.addLeadingZeroes()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The string to add leading zeroes to.

expectedLength + + +number + + + + + + <optional>
+ + + + + +
+ + NaN + +

The expected minimum length of the string after zeroes have been prepended to it.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) appendSlash(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.appendSlash()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) clone(value) → {any}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.clone({ some: "value" })); // {"some":"value"}
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to clone.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A copy of the specified value.

+
+ + + +
+
+ Type +
+
+ +any + + +
+
+ + + + + + + + + + +

(static) compareCasePercentage(value) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.compareCasePercentage()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

The string value to compare the case percentage of.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) compareDates(a, b) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.compareDates()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
a + + +any + + + +

The first date to compare.

b + + +any + + + +

The second date to compare.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) compareVersions(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.3
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.compareVersions()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) createError(message, statusopt) → {Error}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use new Error() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Creates an Error object instance with the specified message and HTTP status code.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.createError("COOL HATS ONLY.", 401)); // new Error("COOL HATS ONLY.") (with status property set to 401)
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
message + + +string + + + + + + + + + + + +

The error message.

status + + +number + + + + + + <optional>
+ + + + + +
+ + 500 + +

The HTTP status code of the error.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The error with the specified message and status code property.

+
+ + + +
+
+ Type +
+
+ +Error + + +
+
+ + + + + + + + + + +

(static) createQueryString(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.createQueryString()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) createRange(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Determined to no longer be useful, will be removed in a future release.
+ + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.createRange()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) disabledElements(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.disabledElements()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) elementsWithAttribute(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.elementsWithAttribute()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) elementsWithoutAttribute(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.elementsWithoutAttribute()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) enabledElements(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.enabledElements()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) equalsIgnoreCase(stringA, stringB) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.3.2
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Case insensitively compares two strings to determine if they are equal.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.equalsIgnoreCase("Test", "TEsT")); // true
console.log(utilities.equalsIgnoreCase("lower", "lower")); // true
console.log(utilities.equalsIgnoreCase("yes", "ye$")); // false
console.log(utilities.equalsIgnoreCase(null, "unknown")); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
stringA + + +string + + + +

The first string to compare.

stringB + + +string + + + +

The second string to compare against

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

.A value of true if the strings are case insensitively equal, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) fileHasExtension(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.fileHasExtension()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) formatObject(object, format, removeExtraopt, throwErrorsopt) → {Object}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.1.1
+ + + + + + + + + + + + + +
Deprecated:
  • Use formatValue instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.formatObject()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
object + + +Object + + + + + + + + + + + +

The object to format.

format + + +Object + + + + + + + + + + + +

The format specification.

removeExtra + + +boolean +| + +Object + + + + + + <optional>
+ + + + + +
+ + false + +

Remove extra flag or formatting options object.

throwErrors + + +boolean + + + + + + <optional>
+ + + + + +
+ + false + +

Remove extra flag or formatting options object.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The formatted object.

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + +

(static) formatStringList(value, stringify) → {string}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.formatStringList()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string +| + +Array.<string> + + + +

The string list to format.

stringify + + +boolean +| + +null + + + +

TODO_ARG_DESC

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The formatted string list.

+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + +

(static) formatValue(value, format, optionsopt) → {any}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.1.1
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.formatValue()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
value + + +any + + + + + + + + + +

The value to format.

format + + +Object + + + + + + + + + +

The format specification.

options + + +Object + + + + + + <optional>
+ + + + + +

Formatting options.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The formatted value.

+
+ + + +
+
+ Type +
+
+ +any + + +
+
+ + + + + + + + + + +

(static) futureMonths(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.futureMonths()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) generateVersions(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.3
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.generateVersions()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) getFileExtension(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.getFileExtension()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) getFileName(filePath) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.getFileName("C:\settings.ini")); // "settings.ini"
console.log(utilities.getFileName("/var/tmp/test.txt")); // "test.txt"
console.log(utilities.getFileName("MyApp.wgt")); // "MyApp.wgt"
console.log(utilities.getFileName(NaN)); // null
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
filePath + + +string + + + +

A file path string to retrieve the file name from.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

Returns a string value containing the name of the file or null if the file path was not a string.

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) getFileNameNoExtension(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.getFileNameNoExtension()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) getFilePath(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.getFilePath()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) hiddenElements(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.hiddenElements()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) indentText(value, amountopt, indentationopt, clearEmptyLinesopt) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.indentText()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The string to indent.

amount + + +number + + + + + + <optional>
+ + + + + +
+ + 1 + +

The amount of times to indent the string.

indentation + + +indentation + + + + + + <optional>
+ + + + + +
+ + "\t" + +

The indentation string to use.

clearEmptyLines + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Determines if empty lines should be trimmed or not.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) isBoolean(value, allowObjectsopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is a boolean.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isBoolean(false)); // true
console.log(utilities.isBoolean(8675309)); // false
console.log(utilities.isBoolean(new Boolean(true))); // false
console.log(utilities.isBoolean(new Boolean(false), true)); // true
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to check.

allowObjects + + +boolean + + + + + + <optional>
+ + + + + +
+ + false + +

Will allow Boolean objects to be treated as valid values.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a boolean, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isComment(value, commentopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Checks if a specified string value starts with the corresponding comment notation. +Any whitespace characters at the start of the string will be ignored. +Empty and non-string values will always result in a value of false being returned.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isComment("// test comment, please ignore")); // true
console.log(utilities.isComment("# another comment")); // false
console.log(utilities.isComment("# valid comment", "#")); // true
console.log(utilities.isComment("some text")); // false
console.log(utilities.isComment("")); // false
console.log(utilities.isComment(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The value to check.

comment + + +string + + + + + + <optional>
+ + + + + +
+ + "//" + +

The comment notation string, can be one or more characters.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a string and begins with the corresponding comment notation.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isDate(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.1.1
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an instance of the Date object.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isDate(new Date())); // true
console.log(utilities.isDate("June 18")); // false
console.log(utilities.isDate(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a Date object instance, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isDisabled(element) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Determined to no longer be useful, will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if an object is disabled or not. +A value which is not an object is considered to be disabled. +A property named disabled with a boolean value of true or function returning true is considered to be disabled. +If there is no property named disabled, but a property named disabled is present with a boolean value of false or function returning false, the object is considered to be disabled. +If the value does not contain either a enabled or disabled property, it is not considered to be disabled.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isDisabled({ disabled: true })); // true
console.log(utilities.isDisabled({ disabled: function() { return true; } })); // true
console.log(utilities.isDisabled({ enabled: false })); // true
console.log(utilities.isDisabled({ enabled: function() { return false; } })); // true
console.log(utilities.isDisabled({ })); // false
console.log(utilities.isDisabled(null)); // true
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
element + + +object + + + +

The element to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

Returns a value of true if the object is determined to be disabled.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isEmptyArray(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an array and contains no items. +Values which are not arrays will always result in a value of false.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isEmptyArray([])); // true
console.log(utilities.isEmptyArray(new Array())); // true
console.log(utilities.isEmptyArray([null])); // false
console.log(utilities.isEmptyArray({ })); // false
console.log(utilities.isEmptyArray(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value if true if the specified value is an array and does not contain any items, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isEmptyObject(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an object and does not contain any enumerable properties. +Values which are not strict objects regardless of how many enumerable properties they have will always result in a value of false.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isEmptyObject({ })); // true
console.log(utilities.isEmptyObject(new Object())); // true
console.log(utilities.isEmptyObject({ example: "data" })); // false
console.log(utilities.isEmptyObject(new Map())); // false
console.log(utilities.isEmptyObject(new Error())); // false
console.log(utilities.isEmptyObject(function() { })); // false
console.log(utilities.isEmptyObject(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a strict object with no enumerable properties, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isEmptyString(value, trimopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an empty string. +By default this will also trim strings and consider values which only contain whitespace, as well as non-string values to also be empty strings.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isEmptyString("")); // true
console.log(utilities.isEmptyString("\t")); // true
console.log(utilities.isEmptyString("Door stuck!")); // false
console.log(utilities.isEmptyString("   ", false)); // false
console.log(utilities.isEmptyString(null)); // true
console.log(utilities.isEmptyString([])); // true
console.log(utilities.isEmptyString(NaN)); // true
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to check.

trim + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Determines if the value should be trimmed before checking if it is empty.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is not a string, or is a string and is empty or only contains whitespace characters if trim is set to true.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isEnabled(element) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Determined to no longer be useful, will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if an object is enabled or not. +A value which is not an object is not considered to be enabled. +A property named enabled with a boolean value of true or function returning true is considered to be enabled. +If there is no property named enabled, but a property named disabled is present with a boolean value of false or function returning false, the object is considered to be enabled. +If the value does not contain either a enabled or disabled property, it is considered to be enabled.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isEnabled({ enabled: true })); // true
console.log(utilities.isEnabled({ enabled: function() { return true; } })); // true
console.log(utilities.isEnabled({ disabled: false })); // true
console.log(utilities.isEnabled({ disabled: function() { return false; } })); // true
console.log(utilities.isEnabled({ })); // false
console.log(utilities.isEnabled(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
element + + +object + + + +

The element to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

Returns a value of true if the object is determined to be enabled.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isError(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.2
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Checks if the specified value is an instance of the Error object.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isError(new Error("Oops."))); // true
console.log(utilities.isError(new SyntaxError("Unknown!"))); // true
console.log(utilities.isError(new DOMException("System failure.", "AbortError"))); // true
console.log(utilities.isError({ message: "fake" })); // false
console.log(utilities.isError(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is an Error object instance, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isFloat(value, allowObjectsopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.3.7
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is a floating point number either represented in a number type, string type or optionally a Number object. +Integer values are also considered to be floating point numbers.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isInteger(7)); // true
console.log(utilities.isInteger(133.7)); // true
console.log(utilities.isInteger("420")); // true
console.log(utilities.isInteger("6.9")); // true
console.log(utilities.isInteger(new Number(64))); // true
console.log(utilities.isInteger(new Number(3.2))); // true
console.log(utilities.isInteger(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to check.

allowObjects + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Will allow Number objects to be treated as valid values.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a floating point number, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isFunction(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Checks if the specified value is an instance of the Function object.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isFunction(function() { })); // true
console.log(utilities.isFunction(console.log)); // true
console.log(utilities.isFunction({ })); // false
console.log(utilities.isFunction({ })); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a Function object instance, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isHidden(element) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Determined to no longer be useful, will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if an object is hidden or not. +A value which is not an object is considered to be hidden. +A property named hidden with a boolean value of true or function returning true is considered to be hidden. +If there is no property named hidden, but a property named hidden is present with a boolean value of false or function returning false, the object is considered to be hidden. +If the value does not contain either a visible or hidden property, it is not considered to be hidden.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isHidden({ hidden: true })); // true
console.log(utilities.isHidden({ hidden: function() { return true; } })); // true
console.log(utilities.isHidden({ visible: false })); // true
console.log(utilities.isHidden({ visible: function() { return false; } })); // true
console.log(utilities.isHidden({ })); // false
console.log(utilities.isHidden(null)); // true
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
element + + +object + + + +

The element to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

Returns a value of true if the object is determined to be hidden.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isInteger(value, allowObjectsopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.3.7
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an integer either represented in a number type, string type or optionally a Number object.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isInteger(7)); // true
console.log(utilities.isInteger(133.7)); // false
console.log(utilities.isInteger("420")); // true
console.log(utilities.isInteger("6.9")); // false
console.log(utilities.isInteger(new Number(64))); // true
console.log(utilities.isInteger(new Number(3.2))); // false
console.log(utilities.isInteger(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to check.

allowObjects + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Will allow Number objects to be treated as valid values.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is an integer, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isInvalid(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is null or undefined.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isInvalid(69)); // false
console.log(utilities.isInvalid(undefined)); // true
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is null or undefined, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isInvalidNumber(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is not a valid number. +Values of NaN, +/- Infinity and Number objects are also not considered to be valid numbers.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isInvalidNumber(7331)); // false
console.log(utilities.isInvalidNumber(-2.718281828459045)); // false
console.log(utilities.isInvalidNumber("7")); // true
console.log(utilities.isInvalidNumber(new Number(65534))); // true
console.log(utilities.isInvalidNumber(NaN)); // true
console.log(utilities.isInvalidNumber(Infinity)); // true
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is not a valid number, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isNonEmptyArray(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an array and contains at least one item. +Values which are not arrays will always result in a value of false.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isEmptyArray([])); // false
console.log(utilities.isEmptyArray(new Array())); // false
console.log(utilities.isEmptyArray([null])); // true
console.log(utilities.isEmptyArray([4, 2, 0])); // true
console.log(utilities.isEmptyArray({ })); // false
console.log(utilities.isEmptyArray(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value if true if the specified value is an array and contains at least one item, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isNonEmptyObject(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an object and contains at least one enumerable property. +Values which are not strict objects regardless of how many properties they have will always result in a value of false.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isEmptyObject({ })); // false
console.log(utilities.isEmptyObject(new Object())); // false
console.log(utilities.isEmptyObject({ example: "data" })); // true
console.log(utilities.isEmptyObject(new Map())); // false
console.log(utilities.isEmptyObject(new Error())); // false
console.log(utilities.isEmptyObject(function() { })); // false
console.log(utilities.isEmptyObject(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a strict object with at least one enumerable property, otherwise false for any other value or strict object with no enumerable properties.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isNonEmptyString(value, trimopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is a non-empty string. +By default this will also trim strings and consider values which only contain whitespace to be empty strings.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isNonEmptyString("")); // false
console.log(utilities.isNonEmptyString("\t")); // false
console.log(utilities.isNonEmptyString("Door stuck!")); // true
console.log(utilities.isNonEmptyString("   ", false)); // true
console.log(utilities.isNonEmptyString(null)); // false
console.log(utilities.isNonEmptyString([])); // false
console.log(utilities.isNonEmptyString(NaN)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to check.

trim + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Determines if the value should be trimmed before checking if it is not empty.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of false if the specified value is not a string, or is a string and is empty or only contains whitespace characters if trim is set to true.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isObject(value, strictopt) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an object. +Functions and values of null are not considered to be real objects. +Any object which inherits from object will yield a result of true unless strict is set to true.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isObject({ please: "ignore" })); // true
console.log(utilities.isObject(new Object())); // true
console.log(utilities.isObject([1, 2, 3])); // true
console.log(utilities.isObject(new Date())); // true
console.log(utilities.isObject(new Date(), true)); // false
console.log(utilities.isObject(function() { })); // false
console.log(utilities.isObject(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to check.

strict + + +boolean + + + + + + <optional>
+ + + + + +
+ + false + +

Only consider values which have Object for a constructor as objects when checking the value.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is an object, otherwise false if it inhertis from object and strict is set to true, or it is any other value type.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isObjectStrict(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is a strict object by checking that the value's constructor is Object. +Functions and values of null are not considered to be strict objects. +Any object which inherits from object will yield a result of false.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isObjectStrict({ foo: "bar" })); // true
console.log(utilities.isObjectStrict(new Object())); // true
console.log(utilities.isObjectStrict(["a", "b", "c"])); // false
console.log(utilities.isObjectStrict(new Error("?"))); // false
console.log(utilities.isObjectStrict(function() { })); // false
console.log(utilities.isObjectStrict(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is an object and has Object for a constructor, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isRegularExpression(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if the specified value is an instance of the RegExp object.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isRegularExpression(/te|st/gmi)); // true
console.log(utilities.isRegularExpression(new RegExp("https?"))); // true
console.log(utilities.isRegularExpression("/hi/")); // false
console.log(utilities.isRegularExpression({ }})); // false
console.log(utilities.isRegularExpression(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a RegExp object instance, otherwise false for any other value.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isValid(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks that the specified value is not null or undefined.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isValid(42)); // true
console.log(utilities.isValid(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is not null or undefined, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isValidNumber(value) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks that that the specified value is a valid number. +Values of NaN, +/- Infinity and Number objects are not considered to be valid numbers.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isValidNumber(1337)); // true
console.log(utilities.isValidNumber(-3.141592654)); // true
console.log(utilities.isValidNumber("32767")); // false
console.log(utilities.isValidNumber(new Number(65534))); // false
console.log(utilities.isValidNumber(NaN)); // false
console.log(utilities.isValidNumber(-Infinity)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if the specified value is a valid number, otherwise false.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) isVisible(element) → {boolean}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Determined to no longer be useful, will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Checks if an object is visible or not. +A value which is not an object is not considered to be visible. +A property named visible with a boolean value of true or function returning true is considered to be visible. +If there is no property named visible, but a property named hidden is present with a boolean value of false or function returning false, the object is considered to be visible. +If the value does not contain either a visible or hidden property, it is considered to be visible.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.isVisible({ visible: true })); // true
console.log(utilities.isVisible({ visible: function() { return true; } })); // true
console.log(utilities.isVisible({ hidden: false })); // true
console.log(utilities.isVisible({ hidden: function() { return false; } })); // true
console.log(utilities.isVisible({ })); // false
console.log(utilities.isVisible(null)); // false
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
element + + +object + + + +

The element to check.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

Returns a value of true if the object is determined to be visible.

+
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + +

(static) joinPaths(paths, optionsopt) → {string}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.joinPaths()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
paths + + +string +| + +Array.<string> + + + + + + + + + +

TODO_ARG_DESC.

options + + +Object + + + + + + <optional>
+ + + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + +

(static) leftShift(number, bits) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.19
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.leftShift()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
number + + +number + + + +

The number value to bit shift.

bits + + +number + + + +

The number of bits to shift the value left by.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The number value right shifted by the specified number of bits.

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) matchAttribute(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.matchAttribute()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) merge(a, b, copyopt, deepMergeopt) → {Object|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.merge({ a: 1 }, { b: 2 })); // { a: 1, b: 2 }
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
a + + +Object + + + + + + + + + + + +

The object to merge into.

b + + +Object + + + + + + + + + + + +

The object whose properties are being merged.

copy + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Determines if a copy of the first object should be made before merging.

deepMerge + + +boolean + + + + + + <optional>
+ + + + + +
+ + true + +

Determines if properties should be recursively merged or just the base properties.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +Object +| + +null + + +
+
+ + + + + + + + + + +

(static) parseBoolean(value, defaultValueopt) → {boolean|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Parses a boolean from a given value. +If no valid boolean value can be determined, defaultValue is returned instead which by default has a value of null. +There are many possibilities for valid truthy boolean values including:

+
    +
  • true
  • +
  • new Boolean(true)
  • +
  • 1
  • +
  • "1"
  • +
  • "true"
  • +
  • "yes"
  • +
  • "on"
  • +
  • "t"
  • +
  • "y"
  • +
+

As well as a number of possibilities for valid falsey boolean values:

+
    +
  • false
  • +
  • new Boolean(false)
  • +
  • 0
  • +
  • "0"
  • +
  • "false"
  • +
  • "no"
  • +
  • "off"
  • +
  • "f"
  • +
  • "n"
  • +
+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseBoolean(true)); // true
console.log(utilities.parseBoolean("false")); // false
console.log(utilities.parseBoolean("yes")); // true
console.log(utilities.parseBoolean(1)); // true
console.log(utilities.parseBoolean(4)); // null
console.log(utilities.parseBoolean("wat")); // null
console.log(utilities.parseBoolean("wot", true)); // true
console.log(utilities.parseBoolean("huh", 420)); // null
console.log(utilities.parseBoolean(null)); // null
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to parse into a boolean.

defaultValue + + +boolean +| + +null + + + + + + <optional>
+ + + + + +
+ + null + +

The value to return if no valid boolean value can be determined. Specifying a non-boolean value will result in null being used instead.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A value of true if a valid truthy value was determined from the specified value, false if a valid falsey value was determined, otherwise the default value is returned. A value of null will be returned if the default value is not specified.

+
+ + + +
+
+ Type +
+
+ +boolean +| + +null + + +
+
+ + + + + + + + + + +

(static) parseDate(value, defaultValueopt) → {Date|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Parses a date object from a given value. +Accepts date object, date string, timestamp number string and timestamp number values. +If no valid date object can be determined from the specified value, the default value is returned instead.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseDate("June 18, 1987 3:30 PM")); // new Date("1987-06-18T19:30:00.000Z")
console.log(utilities.parseDate("2018-02-19T06:19:33Z")); // new Date("2018-02-19T06:19:33.000Z")
console.log(utilities.parseDate(new Date("2020-03-28T18:52:05.136Z"))); // new Date("2020-03-28T18:52:05.136Z")
console.log(utilities.parseDate(1585421525139)); // new Date("2020-03-28T18:52:05.136Z")
console.log(utilities.parseDate("1585421525139")); // new Date("2020-03-28T18:52:05.136Z")
console.log(utilities.parseDate(-1, new Date(0))); // new Date("1970-01-01T00:00:00.000Z")
console.log(utilities.parseDate(-420)); // null
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to parse into a date object.

defaultValue + + +Date +| + +null + + + + + + <optional>
+ + + + + +
+ + null + +

The default value to return if the specified value is not a valid date or timestamp.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A Date object instance if a valid date was determined from the specified value, otherwise the default value is returned. A value of null will be returned if the default value is not specified.

+
+ + + +
+
+ Type +
+
+ +Date +| + +null + + +
+
+ + + + + + + + + + +

(static) parseEmail(value) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseEmail()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

A string containing an email address.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) parseEmailDomain(value) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use value.split("@", 2)[1] instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseEmailDomain()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

A string containing an email address.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) parseFloat(value, defaultValueopt) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.3.7
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Parses a floating point number from a given value. +Accepts number, string and number object values. +If no valid floating point number can be determined from the specified value, the default value is returned instead.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseFloat(-999)); // -999
console.log(utilities.parseFloat(13.37)); // 13.37
console.log(utilities.parseFloat("51")); // 51
console.log(utilities.parseFloat("-867.5309")); // -867.5309
console.log(utilities.parseFloat(new Number(-4231))); // -4231
console.log(utilities.parseFloat(new Number(9.999))); // 9.999
console.log(utilities.parseFloat("wat", 10010101); // 10010101
console.log(utilities.parseFloat(null); // NaN
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to parse into a floating point number.

defaultValue + + +number + + + + + + <optional>
+ + + + + +
+ + NaN + +

The default value to return if the specified value is not a floating point number.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A floating point number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified.

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) parseFloatingPointNumber(value, defaultValueopt) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use utilities.parseFloat instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Parses a floating point number from a given value. +Accepts number, string and number object values. +If no valid floating point number can be determined from the specified value, the default value is returned instead.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseFloatingPointNumber(-1)); // -1
console.log(utilities.parseFloatingPointNumber(2.2)); // 1.1
console.log(utilities.parseFloatingPointNumber("3")); // 3
console.log(utilities.parseFloatingPointNumber("4.4")); // 4.4
console.log(utilities.parseFloatingPointNumber(new Number(-5))); // -5
console.log(utilities.parseFloatingPointNumber(new Number(6.6))); // 6.6
console.log(utilities.parseFloatingPointNumber("nope.avi", 69); // 69
console.log(utilities.parseFloatingPointNumber(null); // NaN
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to parse into a floating point number.

defaultValue + + +number + + + + + + <optional>
+ + + + + +
+ + NaN + +

The default value to return if the specified value is not a floating point number.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A floating point number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified.

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) parseInteger(value, defaultValueopt) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

Parses an integer number from a given value. +Accepts number, string and number object values. +If no valid integer number can be determined from the specified value, the default value is returned instead.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseInteger(88)); // 88
console.log(utilities.parseInteger(-73.31)); // -73
console.log(utilities.parseInteger("-15")); // -15
console.log(utilities.parseInteger("3.141592654")); // 3
console.log(utilities.parseInteger(new Number(4096))); // 4096
console.log(utilities.parseInteger(new Number(3.333))); // 3
console.log(utilities.parseInteger("wat", 11100101); // 11100101
console.log(utilities.parseInteger(null); // NaN
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +any + + + + + + + + + + + +

The value to parse into a integer number.

defaultValue + + +number + + + + + + <optional>
+ + + + + +
+ + NaN + +

The default value to return if the specified value is not an integer or floating point number.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

An integer number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified.

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) parseRegularExpression(value, throwErrorsopt) → {RegExp|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseRegularExpression("/(regexp?)/gi")); // new RegExp("(regexp?)", "gi")
console.log(utilities.parseRegularExpression(new RegExp("ok"))); // new RegExp("ok")
console.log(utilities.parseRegularExpression({ })); // null
console.log(utilities.parseRegularExpression(/invalid/x, true)); // throws Error
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The string value to parse a regular expression from.

throwErrors + + +boolean + + + + + + <optional>
+ + + + + +
+ + false + +

Determines if errors should be thrown or not when invalid regular expression values are encountered.

+ + + + + + + + + + + + + + +
Throws:
+ + + +
+ +

Will optionally throw an error if the regular expression is invalid and throwErrors is set to true.

+ +
+ + + + + +
Returns:
+ + +
+

Returns a RegExp object instance if a valid regular expression was parsed from the specified value or null if the value was invalid and throwErrors is unspecified or set to false.

+
+ + + +
+
+ Type +
+
+ +RegExp +| + +null + + +
+
+ + + + + + + + + + +

(static) parseStringList(value) → {Array.<string>|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseStringList("w, a, t")); // ["w", "a", "t"]
console.log(utilities.parseStringList("ok")); // ["ok"]
console.log(utilities.parseStringList([])); // null
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

A comma or semicolon separated list of string values.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

An array of strings as parsed from the specified string list or null if the specified value is not a string.

+
+ + + +
+
+ Type +
+
+ +Array.<string> +| + +null + + +
+
+ + + + + + + + + + +

(static) parseTime(value) → {Object}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.1.2
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseTime()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + +

(static) parseVersion(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.3
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseVersion()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + + + + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.parseYouTubeLink("http://youtube.com/v/OEEEy1dMceI")); // OEEEy1dMceI
console.log(utilities.parseYouTubeLink("https://www.youtube.com/watch?v=NUnwFHplBg4")); // NUnwFHplBg4
console.log(utilities.parseYouTubeLink("www.youtu.be/watch?v=Dkm8Hteeh6M")); // Dkm8Hteeh6M
console.log(utilities.parseYouTubeLink("https://youtu.be/v/z874bjpO9d8")); // z874bjpO9d8
console.log(utilities.parseYouTubeLink("https://www.nitro404.com")); // null
console.log(utilities.parseYouTubeLink(NaN)); // null
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

The string URL value to parse a YouTube video identifier from.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A string value containing the YouTube video ID or null if the video ID could be determined from the specified value.

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) prependSlash(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.prependSlash()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) replaceNonBreakingSpaces(value) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.replaceNonBreakingSpaces()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

The string to replace non breaking spaces in.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) reverseFileExtension(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.reverseFileExtension()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) reverseString(value) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Reverses a string value with special handling for unicode characters.

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.reverseString("backwards")); // "sdrawkcab"
console.log(utilities.reverseString(NaN)); // null
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

The string value to reverse.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The reversed representation of the specified string value or a value of null if the specified value is not a string.

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) rightShift(number, bits) → {number}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.19
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.rightShift()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
number + + +number + + + +

The number value to bit shift.

bits + + +number + + + +

The number of bits to shift the value right by.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

The number value right shifted by the specified number of bits.

+
+ + + +
+
+ Type +
+
+ +number + + +
+
+ + + + + + + + + + +

(static) toString(value) → {string}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.toString(undefined)); // "undefined"
console.log(utilities.toString(null)); // "null"
console.log(utilities.toString(Infinity)); // "Infinity"
console.log(utilities.toString(-Infinity)); // "-Infinity"
console.log(utilities.toString(NaN)); // "NaN"
console.log(utilities.toString("test")); // "\"test\""
console.log(utilities.toString(new Date(0))); // "1970-01-01T00:00:00.000Z"
console.log(utilities.toString(function() { })); // "function() { }"
console.log(utilities.toString({ door: "stuck" })); // "{\"door":\"stuck\"}"
console.log(utilities.toString([4, 2, "0"])); // "[4,2,\"0\"]"
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +any + + + +

The value to convert into a string.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A string representation of the specified value.

+
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + +

(static) trimLeadingZeroes(value) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.trimLeadingZeroes()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
value + + +string + + + +

The string to remove leading zeroes from.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) trimNullTerminatedString(value, defaultValueopt) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.trimNullTerminatedString()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The null-terminated string to trim.

defaultValue + + +string +| + +null + + + + + + <optional>
+ + + + + +
+ + null + +

The default value to return if the specified value is not a string.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) trimString(value, defaultValueopt) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.trimString()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The string to trim.

defaultValue + + +string +| + +null + + + + + + <optional>
+ + + + + +
+ + null + +

The default value to return if the specified value is not a string.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) trimTrailingNewlines(value, defaultValueopt) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.1.5
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.trimTrailingNewlines()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The string to trim trailing newline characters from.

defaultValue + + +string +| + +null + + + + + + <optional>
+ + + + + +
+ + null + +

The default value to return if the specified value is not a string.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) trimWhitespace(value, trimNewlines, defaultValueopt) → {string|null}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.trimWhitespace()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDefaultDescription
value + + +string + + + + + + + + + + + +

The string to trim whitespace characters from.

trimNewlines + + +boolean + + + + + + + + + + + +

TODO_ARG_DESC.

defaultValue + + +string +| + +null + + + + + + <optional>
+ + + + + +
+ + null + +

The default value to return if the specified value is not a string.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +string +| + +null + + +
+
+ + + + + + + + + + +

(static) truncateFileName(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.2.18
+ + + + + + + + + + + + + + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.truncateFileName()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + +

(static) visibleElements(TODO_ARG_NAME) → {TODO_RETURN_TYPE}

+ + + + + + +
+ + +
Source:
+
+ + + + + +
Since:
+
  • 1.0.0
+ + + + + + + + + + + + + +
Deprecated:
  • Use Array.filter() instead. Will be removed in a future release.
+ + + + + + + + + + + + + +
See:
+
+ +
+ + + +
+ + + + + +
+

TODO_FUNC_DESC

+
+ + + + + + + + + +
Example
+ +
console.log(utilities.visibleElements()); // TODO_RESULT
+ + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
TODO_ARG_NAME + + +TODO_ARG_TYPE + + + +

TODO_ARG_DESC.

+ + + + + + + + + + + + + + + + +
Returns:
+ + +
+

TODO_RETURN_DESC

+
+ + + +
+
+ Type +
+
+ +TODO_RETURN_TYPE + + +
+
+ + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ +
+ Documentation generated by JSDoc 3.6.3 on Sun Mar 29 2020 11:42:52 GMT-0400 (Eastern Daylight Time) using the docdash theme. +
+ + + + + + + + + + + \ No newline at end of file diff --git a/docs/scripts/collapse.js b/docs/scripts/collapse.js new file mode 100644 index 0000000..327039f --- /dev/null +++ b/docs/scripts/collapse.js @@ -0,0 +1,20 @@ +function hideAllButCurrent(){ + //by default all submenut items are hidden + //but we need to rehide them for search + document.querySelectorAll("nav > ul > li > ul li").forEach(function(parent) { + parent.style.display = "none"; + }); + + //only current page (if it exists) should be opened + var file = window.location.pathname.split("/").pop().replace(/\.html/, ''); + document.querySelectorAll("nav > ul > li > a").forEach(function(parent) { + var href = parent.attributes.href.value.replace(/\.html/, ''); + if (file === href) { + parent.parentNode.querySelectorAll("ul li").forEach(function(elem) { + elem.style.display = "block"; + }); + } + }); +} + +hideAllButCurrent(); \ No newline at end of file diff --git a/docs/scripts/linenumber.js b/docs/scripts/linenumber.js new file mode 100644 index 0000000..8d52f7e --- /dev/null +++ b/docs/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(function() { + var source = document.getElementsByClassName('prettyprint source linenums'); + var i = 0; + var lineNumber = 0; + var lineId; + var lines; + var totalLines; + var anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = 'line' + lineNumber; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/docs/scripts/nav.js b/docs/scripts/nav.js new file mode 100644 index 0000000..6dd8313 --- /dev/null +++ b/docs/scripts/nav.js @@ -0,0 +1,12 @@ +function scrollToNavItem() { + var path = window.location.href.split('/').pop().replace(/\.html/, ''); + document.querySelectorAll('nav a').forEach(function(link) { + var href = link.attributes.href.value.replace(/\.html/, ''); + if (path === href) { + link.scrollIntoView({block: 'center'}); + return; + } + }) + } + + scrollToNavItem(); diff --git a/docs/scripts/polyfill.js b/docs/scripts/polyfill.js new file mode 100644 index 0000000..44b4c92 --- /dev/null +++ b/docs/scripts/polyfill.js @@ -0,0 +1,4 @@ +//IE Fix, src: https://www.reddit.com/r/programminghorror/comments/6abmcr/nodelist_lacks_foreach_in_internet_explorer/ +if (typeof(NodeList.prototype.forEach)!==typeof(alert)){ + NodeList.prototype.forEach=Array.prototype.forEach; +} \ No newline at end of file diff --git a/docs/scripts/prettify/Apache-License-2.0.txt b/docs/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/docs/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/docs/scripts/prettify/lang-css.js b/docs/scripts/prettify/lang-css.js new file mode 100644 index 0000000..041e1f5 --- /dev/null +++ b/docs/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/docs/scripts/prettify/prettify.js b/docs/scripts/prettify/prettify.js new file mode 100644 index 0000000..eef5ad7 --- /dev/null +++ b/docs/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p ul > li:not(.level-hide)").forEach(function(elem) { + elem.style.display = "block"; + }); + + if (typeof hideAllButCurrent === "function"){ + //let's do what ever collapse wants to do + hideAllButCurrent(); + } else { + //menu by default should be opened + document.querySelectorAll("nav > ul > li > ul li").forEach(function(elem) { + elem.style.display = "block"; + }); + } + } else { + //we are searching + document.documentElement.setAttribute(searchAttr, ''); + + //show all parents + document.querySelectorAll("nav > ul > li").forEach(function(elem) { + elem.style.display = "block"; + }); + //hide all results + document.querySelectorAll("nav > ul > li > ul li").forEach(function(elem) { + elem.style.display = "none"; + }); + //show results matching filter + document.querySelectorAll("nav > ul > li > ul a").forEach(function(elem) { + if (!contains(elem.parentNode, search)) { + return; + } + elem.parentNode.style.display = "block"; + }); + //hide parents without children + document.querySelectorAll("nav > ul > li").forEach(function(parent) { + var countSearchA = 0; + parent.querySelectorAll("a").forEach(function(elem) { + if (contains(elem, search)) { + countSearchA++; + } + }); + + var countUl = 0; + var countUlVisible = 0; + parent.querySelectorAll("ul").forEach(function(ulP) { + // count all elements that match the search + if (contains(ulP, search)) { + countUl++; + } + + // count all visible elements + var children = ulP.children + for (i=0; i ul { + padding: 0 10px; +} + +nav > ul > li > a { + color: #606; + margin-top: 10px; +} + +nav ul ul a { + color: hsl(207, 1%, 60%); + border-left: 1px solid hsl(207, 10%, 86%); +} + +nav ul ul a, +nav ul ul a:active { + padding-left: 20px +} + +nav h2 { + font-size: 13px; + margin: 10px 0 0 0; + padding: 0; +} + +nav > h2 > a { + margin: 10px 0 -10px; + color: #606 !important; +} + +footer { + color: hsl(0, 0%, 28%); + margin-left: 250px; + display: block; + padding: 15px; + font-style: italic; + font-size: 90%; +} + +.ancestors { + color: #999 +} + +.ancestors a { + color: #999 !important; +} + +.clear { + clear: both +} + +.important { + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px +} + +.type-signature { + color: #CA79CA +} + +.type-signature:last-child { + color: #eee; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace +} + +.signature { + color: #fc83ff; +} + +.details { + margin-top: 6px; + border-left: 2px solid #DDD; + line-height: 20px; + font-size: 14px; +} + +.details dt { + width: auto; + float: left; + padding-left: 10px; +} + +.details dd { + margin-left: 70px; + margin-top: 6px; + margin-bottom: 6px; +} + +.details ul { + margin: 0 +} + +.details ul { + list-style-type: none +} + +.details pre.prettyprint { + margin: 0 +} + +.details .object-value { + padding-top: 0 +} + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption { + font-style: italic; + font-size: 107%; + margin: 0; +} + +.prettyprint { + font-size: 14px; + overflow: auto; +} + +.prettyprint.source { + width: inherit; + line-height: 18px; + display: block; + background-color: #0d152a; + color: #aeaeae; +} + +.prettyprint code { + line-height: 18px; + display: block; + background-color: #0d152a; + color: #4D4E53; +} + +.prettyprint > code { + padding: 15px; +} + +.prettyprint .linenums code { + padding: 0 15px +} + +.prettyprint .linenums li:first-of-type code { + padding-top: 15px +} + +.prettyprint code span.line { + display: inline-block +} + +.prettyprint.linenums { + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol { + padding-left: 0 +} + +.prettyprint.linenums li { + border-left: 3px #34446B solid; +} + +.prettyprint.linenums li.selected, .prettyprint.linenums li.selected * { + background-color: #34446B; +} + +.prettyprint.linenums li * { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.prettyprint.linenums li code:empty:after { + content:""; + display:inline-block; + width:0px; +} + +table { + border-spacing: 0; + border: 1px solid #ddd; + border-collapse: collapse; + border-radius: 3px; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + width: 100%; + font-size: 14px; + margin: 1em 0; +} + +td, th { + margin: 0px; + text-align: left; + vertical-align: top; + padding: 10px; + display: table-cell; +} + +thead tr, thead tr { + background-color: #fff; + font-weight: bold; + border-bottom: 1px solid #ddd; +} + +.params .type { + white-space: nowrap; +} + +.params code { + white-space: pre; +} + +.params td, .params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td { + border-top: 1px solid #eee +} + +.params td.description > p:first-child, .props td.description > p:first-child { + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, .props td.description > p:last-child { + margin-bottom: 0; + padding-bottom: 0; +} + +span.param-type, .params td .param-type, .param-type dd { + color: #606; + font-family: Consolas, Monaco, 'Andale Mono', monospace +} + +.param-type dt, .param-type dd { + display: inline-block +} + +.param-type { + margin: 14px 0; +} + +.disabled { + color: #454545 +} + +/* navicon button */ +.navicon-button { + display: none; + position: relative; + padding: 2.0625rem 1.5rem; + transition: 0.25s; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + opacity: .8; +} +.navicon-button .navicon:before, .navicon-button .navicon:after { + transition: 0.25s; +} +.navicon-button:hover { + transition: 0.5s; + opacity: 1; +} +.navicon-button:hover .navicon:before, .navicon-button:hover .navicon:after { + transition: 0.25s; +} +.navicon-button:hover .navicon:before { + top: .825rem; +} +.navicon-button:hover .navicon:after { + top: -.825rem; +} + +/* navicon */ +.navicon { + position: relative; + width: 2.5em; + height: .3125rem; + background: #000; + transition: 0.3s; + border-radius: 2.5rem; +} +.navicon:before, .navicon:after { + display: block; + content: ""; + height: .3125rem; + width: 2.5rem; + background: #000; + position: absolute; + z-index: -1; + transition: 0.3s 0.25s; + border-radius: 1rem; +} +.navicon:before { + top: .625rem; +} +.navicon:after { + top: -.625rem; +} + +/* open */ +.nav-trigger:checked + label:not(.steps) .navicon:before, +.nav-trigger:checked + label:not(.steps) .navicon:after { + top: 0 !important; +} + +.nav-trigger:checked + label .navicon:before, +.nav-trigger:checked + label .navicon:after { + transition: 0.5s; +} + +/* Minus */ +.nav-trigger:checked + label { + -webkit-transform: scale(0.75); + transform: scale(0.75); +} + +/* × and + */ +.nav-trigger:checked + label.plus .navicon, +.nav-trigger:checked + label.x .navicon { + background: transparent; +} + +.nav-trigger:checked + label.plus .navicon:before, +.nav-trigger:checked + label.x .navicon:before { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + background: #FFF; +} + +.nav-trigger:checked + label.plus .navicon:after, +.nav-trigger:checked + label.x .navicon:after { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + background: #FFF; +} + +.nav-trigger:checked + label.plus { + -webkit-transform: scale(0.75) rotate(45deg); + transform: scale(0.75) rotate(45deg); +} + +.nav-trigger:checked ~ nav { + left: 0 !important; +} + +.nav-trigger:checked ~ .overlay { + display: block; +} + +.nav-trigger { + position: fixed; + top: 0; + clip: rect(0, 0, 0, 0); +} + +.overlay { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + background: hsla(0, 0%, 0%, 0.5); + z-index: 1; +} + +/* nav level */ +.level-hide { + display: none; +} +html[data-search-mode] .level-hide { + display: block; +} + + +@media only screen and (max-width: 680px) { + body { + overflow-x: hidden; + } + + nav { + background: #FFF; + width: 250px; + height: 100%; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: -250px; + z-index: 3; + padding: 0 10px; + transition: left 0.2s; + } + + .navicon-button { + display: inline-block; + position: fixed; + top: 1.5em; + right: 0; + z-index: 2; + } + + #main { + width: 100%; + } + + #main h1.page-title { + margin: 1em 0; + } + + #main section { + padding: 0; + } + + footer { + margin-left: 0; + } +} + +/** Add a '#' to static members */ +[data-type="member"] a::before { + content: '#'; + display: inline-block; + margin-left: -14px; + margin-right: 5px; +} + +#disqus_thread{ + margin-left: 30px; +} + +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + src: url('../fonts/Montserrat/Montserrat-Regular.eot'); /* IE9 Compat Modes */ + src: url('../fonts/Montserrat/Montserrat-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/Montserrat/Montserrat-Regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/Montserrat/Montserrat-Regular.woff') format('woff'), /* Pretty Modern Browsers */ + url('../fonts/Montserrat/Montserrat-Regular.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 700; + src: url('../fonts/Montserrat/Montserrat-Bold.eot'); /* IE9 Compat Modes */ + src: url('../fonts/Montserrat/Montserrat-Bold.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/Montserrat/Montserrat-Bold.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/Montserrat/Montserrat-Bold.woff') format('woff'), /* Pretty Modern Browsers */ + url('../fonts/Montserrat/Montserrat-Bold.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +@font-face { + font-family: 'Source Sans Pro'; + src: url('../fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot'); + src: url('../fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('../fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2') format('woff2'), + url('../fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff') format('woff'), + url('../fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf') format('truetype'), + url('../fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg#source_sans_proregular') format('svg'); + font-weight: 400; + font-style: normal; +} + +@font-face { + font-family: 'Source Sans Pro'; + src: url('../fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot'); + src: url('../fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot?#iefix') format('embedded-opentype'), + url('../fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2') format('woff2'), + url('../fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff') format('woff'), + url('../fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf') format('truetype'), + url('../fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg#source_sans_prolight') format('svg'); + font-weight: 300; + font-style: normal; + +} \ No newline at end of file diff --git a/docs/styles/prettify.css b/docs/styles/prettify.css new file mode 100644 index 0000000..d9521ec --- /dev/null +++ b/docs/styles/prettify.css @@ -0,0 +1,79 @@ +.pln { + color: #ddd; +} + +/* string content */ +.str { + color: #61ce3c; +} + +/* a keyword */ +.kwd { + color: #fbde2d; +} + +/* a comment */ +.com { + color: #aeaeae; +} + +/* a type name */ +.typ { + color: #8da6ce; +} + +/* a literal value */ +.lit { + color: #fbde2d; +} + +/* punctuation */ +.pun { + color: #ddd; +} + +/* lisp open bracket */ +.opn { + color: #000000; +} + +/* lisp close bracket */ +.clo { + color: #000000; +} + +/* a markup tag name */ +.tag { + color: #8da6ce; +} + +/* a markup attribute name */ +.atn { + color: #fbde2d; +} + +/* a markup attribute value */ +.atv { + color: #ddd; +} + +/* a declaration */ +.dec { + color: #EF5050; +} + +/* a variable name */ +.var { + color: #c82829; +} + +/* a function name */ +.fun { + color: #4271ae; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/gulpfile.js b/gulpfile.js index cfe5c0d..ccccd31 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -4,8 +4,5 @@ fabricator.setup({ name: "Extra Utilities", build: { exportName: "Utilities" - }, - base: { - directory: __dirname } }); diff --git a/package-lock.json b/package-lock.json index b2f1156..5593ca1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "extra-utilities", - "version": "1.3.6", + "version": "1.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,12 +14,12 @@ } }, "@babel/compat-data": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.6.tgz", - "integrity": "sha512-CurCIKPTkS25Mb8mz267vU95vy+TyUpnctEX2lV33xWNmHAfjruztgiPBbXZRh3xZZy1CYvGx6XfxyTVS+sk7Q==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz", + "integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.9.1", "invariant": "^2.2.4", "semver": "^5.5.0" } @@ -48,12 +48,12 @@ } }, "@babel/generator": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", - "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", + "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", "dev": true, "requires": { - "@babel/types": "^7.8.7", + "@babel/types": "^7.9.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -78,17 +78,6 @@ "@babel/types": "^7.8.3" } }, - "@babel/helper-call-delegate": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz", - "integrity": "sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.7" - } - }, "@babel/helper-compilation-targets": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", @@ -182,9 +171,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", - "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.8.3", @@ -192,7 +181,7 @@ "@babel/helper-simple-access": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/template": "^7.8.6", - "@babel/types": "^7.8.6", + "@babel/types": "^7.9.0", "lodash": "^4.17.13" } }, @@ -264,6 +253,12 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true + }, "@babel/helper-wrap-function": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", @@ -277,31 +272,31 @@ } }, "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", + "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", "dev": true, "requires": { "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0" } }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.9.0", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", - "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -346,9 +341,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz", + "integrity": "sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", @@ -366,9 +361,9 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", - "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", @@ -497,9 +492,9 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", - "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz", + "integrity": "sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", @@ -560,9 +555,9 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", - "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", + "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -597,47 +592,47 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", - "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz", + "integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", - "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz", + "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "@babel/helper-simple-access": "^7.8.3", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", - "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz", + "integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.8.3", - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", - "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", + "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3" } }, @@ -670,12 +665,11 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.8.tgz", - "integrity": "sha512-hC4Ld/Ulpf1psQciWWwdnUspQoQco2bMzSrwU6TmzRlvoYQe4rQFy9vnCZDTlVeCQj0JPfL+1RX0V8hCJvkgBA==", + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz", + "integrity": "sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==", "dev": true, "requires": { - "@babel/helper-call-delegate": "^7.8.7", "@babel/helper-get-function-arity": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" } @@ -840,9 +834,9 @@ } }, "@babel/runtime": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", - "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", + "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -860,29 +854,29 @@ } }, "@babel/traverse": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", - "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", + "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.6", + "@babel/generator": "^7.9.0", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", - "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", + "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", "dev": true, "requires": { - "esutils": "^2.0.2", + "@babel/helper-validator-identifier": "^7.9.0", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -980,9 +974,9 @@ "dev": true }, "@types/node": { - "version": "13.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.2.tgz", - "integrity": "sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg==", + "version": "13.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.3.tgz", + "integrity": "sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==", "dev": true }, "abbrev": { @@ -1124,6 +1118,48 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", @@ -1611,6 +1647,16 @@ "file-uri-to-path": "1.0.0" } }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -1626,6 +1672,60 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1666,13 +1766,13 @@ } }, "browserslist": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.10.0.tgz", - "integrity": "sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.0.tgz", + "integrity": "sha512-WqEC7Yr5wUH5sg6ruR++v2SGOQYpyUdYYd4tZoAq1F7y+QXoLoYGXVbxhtaIqWmAJjtNTRjVD3HuJc1OXTel2A==", "dev": true, "requires": { "caniuse-lite": "^1.0.30001035", - "electron-to-chromium": "^1.3.378", + "electron-to-chromium": "^1.3.380", "node-releases": "^1.1.52", "pkg-up": "^3.1.0" } @@ -1736,6 +1836,16 @@ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, + "camel-case": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", + "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", + "dev": true, + "requires": { + "pascal-case": "^3.1.1", + "tslib": "^1.10.0" + } + }, "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", @@ -1761,9 +1871,26 @@ } }, "caniuse-lite": { - "version": "1.0.30001035", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", - "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==", + "version": "1.0.30001036", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001036.tgz", + "integrity": "sha512-jU8CIFIj2oR7r4W+5AKcsvWNVIb6Q6OZE3UsrXrZBHFtreT4YgTeOJtTucp+zSedEpTi3L5wASSP0LYIE3if6w==", + "dev": true + }, + "capital-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.3.tgz", + "integrity": "sha512-OlUSJpUr7SY0uZFOxcwnDOU7/MpHlKTZx2mqnDYQFrDudXLFm0JJ9wr/l4csB+rh2Ug0OPuoSO53PqiZBqno9A==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0", + "upper-case-first": "^2.0.1" + } + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", "dev": true }, "caseless": { @@ -1816,6 +1943,26 @@ "supports-color": "^5.3.0" } }, + "change-case": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.1.tgz", + "integrity": "sha512-qRlUWn/hXnX1R1LBDF/RelJLiqNjKjUqlmuBVSEIyye8kq49CXqkZWKmi8XeUAdDXWFOcGLUMZ+aHn3Q5lzUXw==", + "dev": true, + "requires": { + "camel-case": "^4.1.1", + "capital-case": "^1.0.3", + "constant-case": "^3.0.3", + "dot-case": "^3.0.3", + "header-case": "^2.0.3", + "no-case": "^3.0.3", + "param-case": "^3.0.3", + "pascal-case": "^3.1.1", + "path-case": "^3.0.3", + "sentence-case": "^3.0.3", + "snake-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, "change-case-bundled": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/change-case-bundled/-/change-case-bundled-1.0.3.tgz", @@ -1855,6 +2002,12 @@ } } }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -1912,6 +2065,12 @@ "glob": "^7.1.1" } }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, "cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", @@ -2083,6 +2242,20 @@ } } }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", @@ -2099,6 +2272,17 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, + "constant-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.3.tgz", + "integrity": "sha512-FXtsSnnrFYpzDmvwDGQW+l8XK3GV1coLyBN0eBz16ZUzGaZcT2ANVCJmLeuw2GQgxKHQIe9e0w2dzkSfaRlUmA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0", + "upper-case": "^2.0.1" + } + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -2178,16 +2362,32 @@ } } }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", "which": "^1.2.9" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", @@ -2321,6 +2521,12 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2456,6 +2662,12 @@ } } }, + "docdash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/docdash/-/docdash-1.2.0.tgz", + "integrity": "sha512-IYZbgYthPTspgqYeciRJNPhSwL51yer7HAwDXhF5p+H7mTDbPvY3PCk/QDjNxdPCpWkaJVFC4t7iCNB/t9E5Kw==", + "dev": true + }, "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", @@ -2518,6 +2730,31 @@ "domelementtype": "1" } }, + "dot-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz", + "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -2551,9 +2788,9 @@ } }, "electron-to-chromium": { - "version": "1.3.379", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.379.tgz", - "integrity": "sha512-NK9DBBYEBb5f9D7zXI0hiE941gq3wkBeQmXs1ingigA/jnTg5mhwY2Z5egwA+ZI8OLGKCx0h1Cl8/xeuIBuLlg==", + "version": "1.3.383", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.383.tgz", + "integrity": "sha512-EHYVJl6Ox1kFy/SzGVbijHu8ksQotJnqHCFFfaVhXiC+erOSplwhCtOTSocu1jRwirlNsSn/aZ9Kf84Z6s5qrg==", "dev": true }, "end-of-stream": { @@ -2846,6 +3083,21 @@ "es5-ext": "~0.10.14" } }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -3028,13 +3280,21 @@ } }, "extra-utilities": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/extra-utilities/-/extra-utilities-1.3.3.tgz", - "integrity": "sha512-iOvbP17lkiIORLn1hI1ERuGH9uPnFosTm+j/5AV7iiwTaewiZOmDjWMwhqlKSxAjL7xJJXkY1PbFPcNIfGSjag==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/extra-utilities/-/extra-utilities-1.3.6.tgz", + "integrity": "sha512-T27Jt9omh7eUtfTNYCMSRkGxRX+bfZIJ/monTaOqyEOZFhq2qoA0NBISetMrD9ZF2JtpKs9DmguYEjHEzK32WA==", "dev": true, "requires": { "change-case-bundled": "^1.0.3", "validator": "^12.2.0" + }, + "dependencies": { + "validator": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz", + "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ==", + "dev": true + } } }, "extsprintf": { @@ -3941,6 +4201,12 @@ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -4065,6 +4331,15 @@ "object.defaults": "^1.1.0" } }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -4165,6 +4440,25 @@ } } }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -4271,18 +4565,19 @@ } }, "gulp-fabricator": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gulp-fabricator/-/gulp-fabricator-1.2.0.tgz", - "integrity": "sha512-WnOpeMh1tEQjencCi8U2F875xbdJaG0332aPzBaWF8lLT61tU40PZ2vJ+z4c7qnE+VPt2gHeoDCnLeEuuZkBkA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/gulp-fabricator/-/gulp-fabricator-1.2.6.tgz", + "integrity": "sha512-E9f62QomdcU66OCSI/f1TloNjN+TxvWRCUbLgS3Q60UhRm8M8WXzFXLJ5U5m0eDSrGOPpA7HwGyY0LavjWSQOA==", "dev": true, "requires": { "@babel/core": "7.8.7", "@babel/polyfill": "7.8.7", "@babel/preset-env": "7.8.7", "autoprefixer": "9.7.4", - "change-case-bundled": "1.0.3", + "change-case-bundled": "^1.1.2", "colors": "1.4.0", - "extra-utilities": "1.3.3", + "docdash": "^1.2.0", + "extra-utilities": "^1.3.6", "fancy-log": "1.3.3", "gulp": "4.0.2", "gulp-babel": "8.0.0", @@ -4293,6 +4588,7 @@ "gulp-jsdoc3": "2.0.0", "gulp-less": "4.0.1", "gulp-lesshint": "6.1.0", + "gulp-nodemon": "^2.5.0", "gulp-postcss": "8.0.0", "gulp-rename": "2.0.0", "gulp-sass": "4.0.2", @@ -4306,7 +4602,27 @@ "plugin-error": "1.0.1", "pump": "3.0.0", "through2": "3.0.1", - "uglify-js": "3.8.0" + "uglify-js": "3.8.0", + "vinyl-buffer": "^1.0.1", + "vinyl-source-stream": "^2.0.0" + }, + "dependencies": { + "change-case-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/change-case-bundled/-/change-case-bundled-1.1.2.tgz", + "integrity": "sha512-MczhVVlLtiUG4SWFCfQ2Alo2VhDt39yzwzY1Er2UZqBd7uxJe0557lRCshrt60eqfUAm64D/bvN8LYtpn0Stog==", + "dev": true, + "requires": { + "change-case": "^4.1.1", + "lower-case": "^2.0.1", + "lower-case-first": "^2.0.1", + "sponge-case": "^1.0.0", + "swap-case": "^2.0.1", + "title-case": "^3.0.2", + "upper-case": "^2.0.1", + "upper-case-first": "^2.0.1" + } + } } }, "gulp-filter": { @@ -4484,6 +4800,17 @@ "through2": "^3.0.0" } }, + "gulp-nodemon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.5.0.tgz", + "integrity": "sha512-vXfaP72xo2C6XOaXrNcLEM3QqDJ1x21S3x97U4YtzN2Rl2kH57++aFkAVxe6BafGRSTxs/xVfE/jNNlCv5Ym2Q==", + "dev": true, + "requires": { + "colors": "^1.2.1", + "gulp": "^4.0.0", + "nodemon": "^2.0.2" + } + }, "gulp-postcss": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-8.0.0.tgz", @@ -4852,6 +5179,16 @@ } } }, + "header-case": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.3.tgz", + "integrity": "sha512-LChe/V32mnUQnTwTxd3aAlNMk8ia9tjCDb/LjYtoMrdAPApxLB+azejUk5ERZIZdIqvinwv6BAUuFXH/tQPdZA==", + "dev": true, + "requires": { + "capital-case": "^1.0.3", + "tslib": "^1.10.0" + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -4974,6 +5311,12 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, "image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -5009,6 +5352,12 @@ "resolve-from": "^3.0.0" } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -5194,6 +5543,15 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -5281,6 +5639,16 @@ "is-extglob": "^2.1.1" } }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", @@ -5306,6 +5674,12 @@ "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", "dev": true }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -5326,6 +5700,21 @@ } } }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -5347,9 +5736,15 @@ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", "dev": true }, - "is-relative": { + "is-redirect": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { @@ -5362,6 +5757,18 @@ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -5636,6 +6043,15 @@ "es6-weak-map": "^2.0.1" } }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -5917,6 +6333,30 @@ "signal-exit": "^3.0.0" } }, + "lower-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", + "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, + "lower-case-first": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-2.0.1.tgz", + "integrity": "sha512-Z5fqHsaDN4FkWtPjTkhZDBy3uD4ir9L/ooqrNzOyyruDW6nCn/05AbC9HupxEIjlIoeT4bdrtChUllcU+cNgmg==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -5936,6 +6376,23 @@ "es5-ext": "~0.10.2" } }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -6193,9 +6650,9 @@ } }, "mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -6269,6 +6726,16 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, + "no-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", + "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", + "dev": true, + "requires": { + "lower-case": "^2.0.1", + "tslib": "^1.10.0" + } + }, "node-gyp": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", @@ -6289,6 +6756,15 @@ "which": "1" }, "dependencies": { + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", @@ -6358,6 +6834,16 @@ "supports-color": "^2.0.0" } }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -6366,10 +6852,144 @@ } } }, + "nodemon": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.2.tgz", + "integrity": "sha512-GWhYPMfde2+M0FsHnggIHXTqPDHXia32HRhh6H0d75Mt9FKUoCBvumNHr7LdrpPBTKxsWmIEOjoN+P4IU6Hcaw==", + "dev": true, + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.7" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { "abbrev": "1" @@ -6411,6 +7031,15 @@ "once": "^1.3.2" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -6615,6 +7244,12 @@ "os-tmpdir": "^1.0.0" } }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -6639,6 +7274,28 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "param-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.3.tgz", + "integrity": "sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==", + "dev": true, + "requires": { + "dot-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -6707,12 +7364,32 @@ "dev": true, "optional": true }, + "pascal-case": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", + "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, + "path-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.3.tgz", + "integrity": "sha512-UMFU6UETFpCNWbIWNczshPrnK/7JAXBP2NYw80ojElbQ2+JYxdqWDBkvvqM93u4u6oLmuJ/tPOf2tM8KtXv4eg==", + "dev": true, + "requires": { + "dot-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -6747,6 +7424,12 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -6791,6 +7474,12 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -6926,6 +7615,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -6979,6 +7674,12 @@ "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", "dev": true }, + "pstree.remy": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", + "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -7024,6 +7725,26 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -7177,6 +7898,25 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, "regjsgen": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", @@ -7594,6 +8334,15 @@ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "semver-greatest-satisfied-range": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", @@ -7603,6 +8352,17 @@ "sver-compat": "^1.5.0" } }, + "sentence-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.3.tgz", + "integrity": "sha512-ZPr4dgTcNkEfcGOMFQyDdJrTU9uQO1nb1cjf+nuzb6FxgMDgKddZOM29qEsB7jvsZSMruLRcL2KfM4ypKpa0LA==", + "dev": true, + "requires": { + "no-case": "^3.0.3", + "tslib": "^1.10.0", + "upper-case-first": "^2.0.1" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -7632,6 +8392,21 @@ } } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shelljs": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", @@ -7657,6 +8432,16 @@ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, + "snake-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.3.tgz", + "integrity": "sha512-WM1sIXEO+rsAHBKjGf/6R1HBBcgbncKS08d2Aqec/mrDSpU80SiOU41hO7ny6DToHSyrlwTYzQBIK1FPSx4Y3Q==", + "dev": true, + "requires": { + "dot-case": "^3.0.3", + "tslib": "^1.10.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7851,6 +8636,15 @@ "extend-shallow": "^3.0.0" } }, + "sponge-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sponge-case/-/sponge-case-1.0.0.tgz", + "integrity": "sha512-aGer++MWUeckV5eMT+seSLVnGNzQstrwe1AL5qNL2MCX/9P2zybPW2siB3gwD8fh4x/H67QIOfNeIQqBI77Vjw==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -7994,6 +8788,12 @@ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", @@ -8028,6 +8828,15 @@ "es6-symbol": "^3.1.1" } }, + "swap-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-2.0.1.tgz", + "integrity": "sha512-BhkFAg9mkLQ3ZntQXg5Tar7lIBEatetX6WS50nsKrxuenqam591bQ9t3vweMP13TpRbvLCmThQvszFgA03bztQ==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, "table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", @@ -8129,6 +8938,15 @@ "inherits": "2" } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8178,6 +8996,12 @@ "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", "dev": true }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -8188,6 +9012,15 @@ "next-tick": "1" } }, + "title-case": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.2.tgz", + "integrity": "sha512-1P5hyjEhJ9Ab0AT8Xbm0z1avwPSgRR6XtFSNCdfo6B7111TTTja+456UZ2ZPkbTbzqBwIpQxp/tazh5UvpJ+fA==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -8276,6 +9109,15 @@ } } }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -8400,6 +9242,32 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dev": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, "underscore": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", @@ -8485,6 +9353,15 @@ "through2-filter": "^3.0.0" } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -8531,12 +9408,54 @@ } } }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, "upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "upper-case": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.1.tgz", + "integrity": "sha512-laAsbea9SY5osxrv7S99vH9xAaJKrw5Qpdh4ENRLcaxipjKsiaBwiAsxfa8X5mObKNTQPsupSq0J/VIxsSJe3A==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, + "upper-case-first": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.1.tgz", + "integrity": "sha512-105J8XqQ+9RxW3l9gHZtgve5oaiR9TIwvmZAMAIZWRHe00T21cdvewKORTlOJf/zXW6VukuTshM+HXZNWz7N5w==", + "dev": true, + "requires": { + "tslib": "^1.10.0" + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -8552,6 +9471,15 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -8616,9 +9544,9 @@ } }, "validator": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-12.2.0.tgz", - "integrity": "sha512-jJfE/DW6tIK1Ek8nCfNFqt8Wb3nzMoAbocBF6/Icgg1ZFSBpObdnwVY2jQj6qUqzhx5jc71fpvBWyLGO7Xl+nQ==" + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.0.0.tgz", + "integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA==" }, "value-or-function": { "version": "3.0.0", @@ -8651,6 +9579,28 @@ "replace-ext": "^1.0.0" } }, + "vinyl-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz", + "integrity": "sha1-lsGjR5uMU5JULGEgKQE7Wyf4i78=", + "dev": true, + "requires": { + "bl": "^1.2.1", + "through2": "^2.0.3" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, "vinyl-fs": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", @@ -8688,6 +9638,28 @@ } } }, + "vinyl-source-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-2.0.0.tgz", + "integrity": "sha1-84pa+53R6Ttl1VBGmsYYKsT1S44=", + "dev": true, + "requires": { + "through2": "^2.0.3", + "vinyl": "^2.1.0" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, "vinyl-sourcemap": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", @@ -8742,6 +9714,48 @@ "string-width": "^1.0.2 || 2" } }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", @@ -8785,6 +9799,23 @@ "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, "xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", diff --git a/package.json b/package.json index c655cb6..f678548 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,20 @@ { "name": "extra-utilities", - "version": "1.3.6", - "description": "A collection of useful helper functions.", + "version": "1.4.0", + "description": "A collection of useful JavaScript helper functions.", "main": "src/extra-utilities.js", "scripts": { "build": "gulp build", "lint": "gulp lint", "test": "mocha", + "docs": "gulp docs", + "deploy": "npm run build && npm run lint && npm run test && npm run docs && npm version --no-git-tag-version patch", "coverage": "nyc npm run test", "coveralls": "npm run coverage && nyc report --reporter=text-lcov | coveralls" }, "repository": { "type": "git", - "url": "git+https://github.com/nitro404/extra-utilities.git" + "url": "https://github.com/nitro404/extra-utilities.git" }, "keywords": [ "extra", @@ -28,13 +30,13 @@ "bugs": { "url": "https://github.com/nitro404/extra-utilities/issues" }, - "homepage": "https://github.com/nitro404/extra-utilities#readme", + "homepage": "https://nitro404.github.io/extra-utilities/module-utilities.html", "dependencies": { "change-case-bundled": "^1.0.3", - "validator": "^12.2.0" + "validator": "^13.0.0" }, "devDependencies": { "chai": "^4.2.0", - "gulp-fabricator": "^1.2.0" + "gulp-fabricator": "^1.2.6" } } diff --git a/src/extra-utilities.js b/src/extra-utilities.js index 82c6edd..32fe903 100644 --- a/src/extra-utilities.js +++ b/src/extra-utilities.js @@ -1,13 +1,14 @@ -if(typeof require !== "undefined") { - if(typeof validator === "undefined") { - global.validator = require("validator"); - } +"use strict"; +if(typeof require !== "undefined") { if(typeof changeCase === "undefined") { global.changeCase = require("change-case-bundled"); } } +/** + * @module utilities + */ var utilities = { }; var regExpFlags = { @@ -41,74 +42,485 @@ var stringCaseFunctions = { upperFirst: changeCase.upperCaseFirst }; +/** + * Checks that the specified value is not null or undefined. + * + * @function isValid + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is not null or undefined, otherwise false. + * @see {@link module:utilities.isInvalid|isInvalid} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isValid(42)); // true + * console.log(utilities.isValid(null)); // false + */ utilities.isValid = function isValid(value) { return value !== undefined && value !== null; }; +/** + * Checks if the specified value is null or undefined. + * + * @function isInvalid + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is null or undefined, otherwise false. + * @see {@link module:utilities.isValid|isValid} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isInvalid(69)); // false + * console.log(utilities.isInvalid(undefined)); // true + */ utilities.isInvalid = function isInvalid(value) { return value === undefined || value === null; }; +/** + * Checks if the specified value is a boolean. + * + * @function isBoolean + * @param {any} value - The value to check. + * @param {boolean} [allowObjects=false] - Will allow Boolean objects to be treated as valid values. + * @returns {boolean} A value of true if the specified value is a boolean, otherwise false. + * @see {@link module:utilities.parseBoolean|parseBoolean} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isBoolean(false)); // true + * console.log(utilities.isBoolean(8675309)); // false + * console.log(utilities.isBoolean(new Boolean(true))); // false + * console.log(utilities.isBoolean(new Boolean(false), true)); // true + */ utilities.isBoolean = function isBoolean(value, allowObjects) { return value === true || value === false || (!!allowObjects && value instanceof Boolean); }; +/** + * Checks that that the specified value is a valid number. + * Values of NaN, +/- Infinity and Number objects are not considered to be valid numbers. + * + * @function isValidNumber + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is a valid number, otherwise false. + * @see {@link module:utilities.isInvalidNumber|isInvalidNumber} + * @see {@link module:utilities.parseInteger|parseInteger} + * @see {@link module:utilities.parseFloat|parseFloat} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isValidNumber(1337)); // true + * console.log(utilities.isValidNumber(-3.141592654)); // true + * console.log(utilities.isValidNumber("32767")); // false + * console.log(utilities.isValidNumber(new Number(65534))); // false + * console.log(utilities.isValidNumber(NaN)); // false + * console.log(utilities.isValidNumber(-Infinity)); // false + */ utilities.isValidNumber = function isValidNumber(value) { return typeof value === "number" && !isNaN(value) && value !== -Infinity && value !== Infinity; }; +/** + * Checks if the specified value is not a valid number. + * Values of NaN, +/- Infinity and Number objects are also not considered to be valid numbers. + * + * @function isInvalidNumber + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is not a valid number, otherwise false. + * @see {@link module:utilities.isValidNumber|isValidNumber} + * @see {@link module:utilities.parseInteger|parseInteger} + * @see {@link module:utilities.parseFloat|parseFloat} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isInvalidNumber(7331)); // false + * console.log(utilities.isInvalidNumber(-2.718281828459045)); // false + * console.log(utilities.isInvalidNumber("7")); // true + * console.log(utilities.isInvalidNumber(new Number(65534))); // true + * console.log(utilities.isInvalidNumber(NaN)); // true + * console.log(utilities.isInvalidNumber(Infinity)); // true + */ utilities.isInvalidNumber = function isInvalidNumber(value) { return typeof value !== "number" || isNaN(value) || value === -Infinity || value === Infinity; }; +/** + * Checks if the specified value is an integer either represented in a number type, string type or optionally a Number object. + * + * @function isInteger + * @param {any} value - The value to check. + * @param {boolean} [allowObjects=true] - Will allow Number objects to be treated as valid values. + * @returns {boolean} A value of true if the specified value is an integer, otherwise false. + * @see {@link module:utilities.isValidNumber|isValidNumber} + * @see {@link module:utilities.isInvalidNumber|isInvalidNumber} + * @see {@link module:utilities.isFloat|isFloat} + * @see {@link module:utilities.parseInteger|parseInteger} + * @see {@link module:utilities.parseFloat|parseFloat} + * @since 1.3.7 + * @memberOf module:utilities + * @example + * console.log(utilities.isInteger(7)); // true + * console.log(utilities.isInteger(133.7)); // false + * console.log(utilities.isInteger("420")); // true + * console.log(utilities.isInteger("6.9")); // false + * console.log(utilities.isInteger(new Number(64))); // true + * console.log(utilities.isInteger(new Number(3.2))); // false + * console.log(utilities.isInteger(null)); // false + */ +utilities.isInteger = function isInteger(value, allowObjects) { + if(Number.isInteger(value)) { + return true; + } + + if(value instanceof Number && utilities.parseBoolean(allowObjects, true)) { + return Number.isInteger(value.valueOf()); + } + + if(typeof value !== "string") { + return false; + } + + return !!value.match(/^([+-]?[1-9][0-9]*|0)$/); +}; + +/** + * Checks if the specified value is a floating point number either represented in a number type, string type or optionally a Number object. + * Integer values are also considered to be floating point numbers. + * + * @function isFloat + * @param {any} value - The value to check. + * @param {boolean} [allowObjects=true] - Will allow Number objects to be treated as valid values. + * @returns {boolean} A value of true if the specified value is a floating point number, otherwise false. + * @see {@link module:utilities.isValidNumber|isValidNumber} + * @see {@link module:utilities.isInvalidNumber|isInvalidNumber} + * @see {@link module:utilities.isInteger|isInteger} + * @see {@link module:utilities.parseInteger|parseInteger} + * @see {@link module:utilities.parseFloat|parseFloat} + * @since 1.3.7 + * @memberOf module:utilities + * @example + * console.log(utilities.isInteger(7)); // true + * console.log(utilities.isInteger(133.7)); // true + * console.log(utilities.isInteger("420")); // true + * console.log(utilities.isInteger("6.9")); // true + * console.log(utilities.isInteger(new Number(64))); // true + * console.log(utilities.isInteger(new Number(3.2))); // true + * console.log(utilities.isInteger(null)); // false + */ +utilities.isFloat = function isFloat(value, allowObjects) { + if(typeof value === "number") { + return !isNaN(value) && isFinite(value); + } + + if(value instanceof Number && utilities.parseBoolean(allowObjects, true)) { + return true; + } + + if(typeof value !== "string") { + return false; + } + + return !!value.match(/^([+-]?(((([1-9][0-9]*|0)?\.)[0-9]+)|([1-9][0-9]*|0)))$/); +}; + +/** + * Checks if the specified value is an empty string. + * By default this will also trim strings and consider values which only contain whitespace, as well as non-string values to also be empty strings. + * + * @function isEmptyString + * @param {any} value - The value to check. + * @param {boolean} [trim=true] - Determines if the value should be trimmed before checking if it is empty. + * @returns {boolean} A value of true if the specified value is not a string, or is a string and is empty or only contains whitespace characters if trim is set to true. + * @see {@link module:utilities.isNonEmptyString|isNonEmptyString} + * @see {@link module:utilities.trimString|trimString} + * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString} + * @see {@link module:utilities.trimWhitespace|trimWhitespace} + * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines} + * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isEmptyString("")); // true + * console.log(utilities.isEmptyString("\t")); // true + * console.log(utilities.isEmptyString("Door stuck!")); // false + * console.log(utilities.isEmptyString(" ", false)); // false + * console.log(utilities.isEmptyString(null)); // true + * console.log(utilities.isEmptyString([])); // true + * console.log(utilities.isEmptyString(NaN)); // true + */ utilities.isEmptyString = function isEmptyString(value, trim) { return typeof value !== "string" || (utilities.parseBoolean(trim, true) ? value.trim().length === 0 : value.length === 0); }; +/** + * Checks if the specified value is a non-empty string. + * By default this will also trim strings and consider values which only contain whitespace to be empty strings. + * + * @function isNonEmptyString + * @param {any} value - The value to check. + * @param {boolean} [trim=true] - Determines if the value should be trimmed before checking if it is not empty. + * @returns {boolean} A value of false if the specified value is not a string, or is a string and is empty or only contains whitespace characters if trim is set to true. + * @see {@link module:utilities.isEmptyString|isEmptyString} + * @see {@link module:utilities.trimString|trimString} + * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString} + * @see {@link module:utilities.trimWhitespace|trimWhitespace} + * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines} + * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isNonEmptyString("")); // false + * console.log(utilities.isNonEmptyString("\t")); // false + * console.log(utilities.isNonEmptyString("Door stuck!")); // true + * console.log(utilities.isNonEmptyString(" ", false)); // true + * console.log(utilities.isNonEmptyString(null)); // false + * console.log(utilities.isNonEmptyString([])); // false + * console.log(utilities.isNonEmptyString(NaN)); // false + */ utilities.isNonEmptyString = function isNonEmptyString(value, trim) { return typeof value === "string" && (utilities.parseBoolean(trim, true) ? value.trim().length !== 0 : value.length !== 0); }; +/** + * Checks if the specified value is an object. + * Functions and values of null are not considered to be real objects. + * Any object which inherits from object will yield a result of true unless strict is set to true. + * + * @function isObject + * @param {any} value - The value to check. + * @param {boolean} [strict=false] - Only consider values which have Object for a constructor as objects when checking the value. + * @returns {boolean} A value of true if the specified value is an object, otherwise false if it inhertis from object and strict is set to true, or it is any other value type. + * @see {@link module:utilities.isObjectStrict|isObjectStrict} + * @see {@link module:utilities.isEmptyObject|isEmptyObject} + * @see {@link module:utilities.isNonEmptyObject|isNonEmptyObject} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isObject({ please: "ignore" })); // true + * console.log(utilities.isObject(new Object())); // true + * console.log(utilities.isObject([1, 2, 3])); // true + * console.log(utilities.isObject(new Date())); // true + * console.log(utilities.isObject(new Date(), true)); // false + * console.log(utilities.isObject(function() { })); // false + * console.log(utilities.isObject(null)); // false + */ utilities.isObject = function isObject(value, strict) { return value !== undefined && (strict ? value !== null && value.constructor === Object : value instanceof Object && !(value instanceof Function)); }; +/** + * Checks if the specified value is a strict object by checking that the value's constructor is Object. + * Functions and values of null are not considered to be strict objects. + * Any object which inherits from object will yield a result of false. + * + * @function isObjectStrict + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is an object and has Object for a constructor, otherwise false for any other value. + * @see {@link module:utilities.isObjectStrict|isObjectStrict} + * @see {@link module:utilities.isEmptyObject|isEmptyObject} + * @see {@link module:utilities.isNonEmptyObject|isNonEmptyObject} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isObjectStrict({ foo: "bar" })); // true + * console.log(utilities.isObjectStrict(new Object())); // true + * console.log(utilities.isObjectStrict(["a", "b", "c"])); // false + * console.log(utilities.isObjectStrict(new Error("?"))); // false + * console.log(utilities.isObjectStrict(function() { })); // false + * console.log(utilities.isObjectStrict(null)); // false + */ utilities.isObjectStrict = function isObjectStrict(value) { return value !== undefined && value !== null && value.constructor === Object; }; +/** + * Checks if the specified value is an object and does not contain any enumerable properties. + * Values which are not strict objects regardless of how many enumerable properties they have will always result in a value of false. + * + * @function isEmptyObject + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is a strict object with no enumerable properties, otherwise false for any other value. + * @see {@link module:utilities.isObject|isObject} + * @see {@link module:utilities.isObjectStrict|isObjectStrict} + * @see {@link module:utilities.isNonEmptyObject|isNonEmptyObject} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isEmptyObject({ })); // true + * console.log(utilities.isEmptyObject(new Object())); // true + * console.log(utilities.isEmptyObject({ example: "data" })); // false + * console.log(utilities.isEmptyObject(new Map())); // false + * console.log(utilities.isEmptyObject(new Error())); // false + * console.log(utilities.isEmptyObject(function() { })); // false + * console.log(utilities.isEmptyObject(null)); // false + */ utilities.isEmptyObject = function isEmptyObject(value) { return value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length === 0; }; +/** + * Checks if the specified value is an object and contains at least one enumerable property. + * Values which are not strict objects regardless of how many properties they have will always result in a value of false. + * + * @function isNonEmptyObject + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is a strict object with at least one enumerable property, otherwise false for any other value or strict object with no enumerable properties. + * @see {@link module:utilities.isObject|isObject} + * @see {@link module:utilities.isObjectStrict|isObjectStrict} + * @see {@link module:utilities.isEmptyObject|isEmptyObject} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isEmptyObject({ })); // false + * console.log(utilities.isEmptyObject(new Object())); // false + * console.log(utilities.isEmptyObject({ example: "data" })); // true + * console.log(utilities.isEmptyObject(new Map())); // false + * console.log(utilities.isEmptyObject(new Error())); // false + * console.log(utilities.isEmptyObject(function() { })); // false + * console.log(utilities.isEmptyObject(null)); // false + */ utilities.isNonEmptyObject = function isNonEmptyObject(value) { return value !== undefined && value !== null && value.constructor === Object && Object.keys(value).length !== 0; }; +/** + * Checks if the specified value is an array and contains no items. + * Values which are not arrays will always result in a value of false. + * + * @function isEmptyArray + * @param {any} value - The value to check. + * @returns {boolean} A value if true if the specified value is an array and does not contain any items, otherwise false for any other value. + * @see {@link module:utilities.isNonEmptyArray|isNonEmptyArray} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isEmptyArray([])); // true + * console.log(utilities.isEmptyArray(new Array())); // true + * console.log(utilities.isEmptyArray([null])); // false + * console.log(utilities.isEmptyArray({ })); // false + * console.log(utilities.isEmptyArray(null)); // false + */ utilities.isEmptyArray = function isEmptyArray(value) { return Array.isArray(value) ? value.length === 0 : true; }; +/** + * Checks if the specified value is an array and contains at least one item. + * Values which are not arrays will always result in a value of false. + * + * @function isNonEmptyArray + * @param {any} value - The value to check. + * @returns {boolean} A value if true if the specified value is an array and contains at least one item, otherwise false for any other value. + * @see {@link module:utilities.isEmptyArray|isEmptyArray} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isEmptyArray([])); // false + * console.log(utilities.isEmptyArray(new Array())); // false + * console.log(utilities.isEmptyArray([null])); // true + * console.log(utilities.isEmptyArray([4, 2, 0])); // true + * console.log(utilities.isEmptyArray({ })); // false + * console.log(utilities.isEmptyArray(null)); // false + */ utilities.isNonEmptyArray = function isNonEmptyArray(value) { return Array.isArray(value) && value.length !== 0; }; +/** + * Checks if the specified value is an instance of the Date object. + * + * @function isDate + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is a Date object instance, otherwise false for any other value. + * @see {@link module:utilities.parseDate|parseDate} + * @see {@link module:utilities.compareDates|compateDates} + * @since 1.1.1 + * @memberOf module:utilities + * @example + * console.log(utilities.isDate(new Date())); // true + * console.log(utilities.isDate("June 18")); // false + * console.log(utilities.isDate(null)); // false + */ utilities.isDate = function isDate(value) { return value instanceof Date; }; +/** + * Checks if the specified value is an instance of the Error object. + * + * @function isError + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is an Error object instance, otherwise false for any other value. + * @since 1.2.2 + * @memberOf module:utilities + * @example + * console.log(utilities.isError(new Error("Oops."))); // true + * console.log(utilities.isError(new SyntaxError("Unknown!"))); // true + * console.log(utilities.isError(new DOMException("System failure.", "AbortError"))); // true + * console.log(utilities.isError({ message: "fake" })); // false + * console.log(utilities.isError(null)); // false + */ utilities.isError = function isError(value) { return value instanceof Error; }; +/** + * Checks if the specified value is an instance of the RegExp object. + * + * @function isRegularExpression + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is a RegExp object instance, otherwise false for any other value. + * @see {@link module:utilities.parseRegularExpression|parseRegularExpression} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isRegularExpression(/te|st/gmi)); // true + * console.log(utilities.isRegularExpression(new RegExp("https?"))); // true + * console.log(utilities.isRegularExpression("/hi/")); // false + * console.log(utilities.isRegularExpression({ }})); // false + * console.log(utilities.isRegularExpression(null)); // false + */ utilities.isRegularExpression = function isRegularExpression(value) { return value instanceof RegExp; }; +/** + * Checks if the specified value is an instance of the Function object. + * + * @function isFunction + * @param {any} value - The value to check. + * @returns {boolean} A value of true if the specified value is a Function object instance, otherwise false for any other value. + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isFunction(function() { })); // true + * console.log(utilities.isFunction(console.log)); // true + * console.log(utilities.isFunction({ })); // false + * console.log(utilities.isFunction({ })); // false + */ utilities.isFunction = function isFunction(value) { return value instanceof Function; }; +/** + * Checks if a specified string value starts with the corresponding comment notation. + * Any whitespace characters at the start of the string will be ignored. + * Empty and non-string values will always result in a value of false being returned. + * + * @function isComment + * @param {string} value - The value to check. + * @param {string} [comment="//"] - The comment notation string, can be one or more characters. + * @returns {boolean} A value of true if the specified value is a string and begins with the corresponding comment notation. + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isComment("// test comment, please ignore")); // true + * console.log(utilities.isComment("# another comment")); // false + * console.log(utilities.isComment("# valid comment", "#")); // true + * console.log(utilities.isComment("some text")); // false + * console.log(utilities.isComment("")); // false + * console.log(utilities.isComment(null)); // false + */ utilities.isComment = function isComment(value, comment) { if(utilities.isEmptyString(value)) { return false; @@ -151,6 +563,28 @@ utilities.isComment = function isComment(value, comment) { return true; }; +/** + * Checks if an object is visible or not. + * A value which is not an object is not considered to be visible. + * A property named visible with a boolean value of true or function returning true is considered to be visible. + * If there is no property named visible, but a property named hidden is present with a boolean value of false or function returning false, the object is considered to be visible. + * If the value does not contain either a visible or hidden property, it is considered to be visible. + * + * @function isVisible + * @param {object} element - The element to check. + * @returns {boolean} Returns a value of true if the object is determined to be visible. + * @deprecated Determined to no longer be useful, will be removed in a future release. + * @see {@link module:utilities.isHidden|isHidden} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isVisible({ visible: true })); // true + * console.log(utilities.isVisible({ visible: function() { return true; } })); // true + * console.log(utilities.isVisible({ hidden: false })); // true + * console.log(utilities.isVisible({ hidden: function() { return false; } })); // true + * console.log(utilities.isVisible({ })); // false + * console.log(utilities.isVisible(null)); // false + */ utilities.isVisible = function isVisible(element) { if(!utilities.isObject(element)) { return false; @@ -172,6 +606,28 @@ utilities.isVisible = function isVisible(element) { return true; }; +/** + * Checks if an object is hidden or not. + * A value which is not an object is considered to be hidden. + * A property named hidden with a boolean value of true or function returning true is considered to be hidden. + * If there is no property named hidden, but a property named hidden is present with a boolean value of false or function returning false, the object is considered to be hidden. + * If the value does not contain either a visible or hidden property, it is not considered to be hidden. + * + * @function isHidden + * @param {object} element - The element to check. + * @returns {boolean} Returns a value of true if the object is determined to be hidden. + * @deprecated Determined to no longer be useful, will be removed in a future release. + * @see {@link module:utilities.isVisible|isVisible} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isHidden({ hidden: true })); // true + * console.log(utilities.isHidden({ hidden: function() { return true; } })); // true + * console.log(utilities.isHidden({ visible: false })); // true + * console.log(utilities.isHidden({ visible: function() { return false; } })); // true + * console.log(utilities.isHidden({ })); // false + * console.log(utilities.isHidden(null)); // true + */ utilities.isHidden = function isHidden(element) { if(!utilities.isObject(element)) { return true; @@ -193,6 +649,28 @@ utilities.isHidden = function isHidden(element) { return false; }; +/** + * Checks if an object is enabled or not. + * A value which is not an object is not considered to be enabled. + * A property named enabled with a boolean value of true or function returning true is considered to be enabled. + * If there is no property named enabled, but a property named disabled is present with a boolean value of false or function returning false, the object is considered to be enabled. + * If the value does not contain either a enabled or disabled property, it is considered to be enabled. + * + * @function isEnabled + * @param {object} element - The element to check. + * @returns {boolean} Returns a value of true if the object is determined to be enabled. + * @deprecated Determined to no longer be useful, will be removed in a future release. + * @see {@link module:utilities.isDisabled|isDisabled} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isEnabled({ enabled: true })); // true + * console.log(utilities.isEnabled({ enabled: function() { return true; } })); // true + * console.log(utilities.isEnabled({ disabled: false })); // true + * console.log(utilities.isEnabled({ disabled: function() { return false; } })); // true + * console.log(utilities.isEnabled({ })); // false + * console.log(utilities.isEnabled(null)); // false + */ utilities.isEnabled = function isEnabled(element) { if(!utilities.isObject(element)) { return false; @@ -214,6 +692,28 @@ utilities.isEnabled = function isEnabled(element) { return true; }; +/** + * Checks if an object is disabled or not. + * A value which is not an object is considered to be disabled. + * A property named disabled with a boolean value of true or function returning true is considered to be disabled. + * If there is no property named disabled, but a property named disabled is present with a boolean value of false or function returning false, the object is considered to be disabled. + * If the value does not contain either a enabled or disabled property, it is not considered to be disabled. + * + * @function isDisabled + * @param {object} element - The element to check. + * @returns {boolean} Returns a value of true if the object is determined to be disabled. + * @deprecated Determined to no longer be useful, will be removed in a future release. + * @see {@link module:utilities.isEnabled|isEnabled} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.isDisabled({ disabled: true })); // true + * console.log(utilities.isDisabled({ disabled: function() { return true; } })); // true + * console.log(utilities.isDisabled({ enabled: false })); // true + * console.log(utilities.isDisabled({ enabled: function() { return false; } })); // true + * console.log(utilities.isDisabled({ })); // false + * console.log(utilities.isDisabled(null)); // true + */ utilities.isDisabled = function isDisabled(element) { if(!utilities.isObject(element)) { return true; @@ -235,6 +735,21 @@ utilities.isDisabled = function isDisabled(element) { return false; }; +/** + * Case insensitively compares two strings to determine if they are equal. + * + * @function equalsIgnoreCase + * @param {string} stringA - The first string to compare. + * @param {string} stringB - The second string to compare against + * @returns {boolean} .A value of true if the strings are case insensitively equal, otherwise false. + * @since 1.3.2 + * @memberOf module:utilities + * @example + * console.log(utilities.equalsIgnoreCase("Test", "TEsT")); // true + * console.log(utilities.equalsIgnoreCase("lower", "lower")); // true + * console.log(utilities.equalsIgnoreCase("yes", "ye$")); // false + * console.log(utilities.equalsIgnoreCase(null, "unknown")); // false + */ utilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) { if(typeof stringA !== "string" || typeof stringB !== "string") { return false; @@ -243,6 +758,49 @@ utilities.equalsIgnoreCase = function equalsIgnoreCase(stringA, stringB) { return stringA.localeCompare(stringB, undefined, { sensitivity: "accent" }) === 0; }; +/** + * Parses a boolean from a given value. + * If no valid boolean value can be determined, defaultValue is returned instead which by default has a value of null. + * There are many possibilities for valid truthy boolean values including: + * - true + * - new Boolean(true) + * - 1 + * - "1" + * - "true" + * - "yes" + * - "on" + * - "t" + * - "y" + * + * As well as a number of possibilities for valid falsey boolean values: + * - false + * - new Boolean(false) + * - 0 + * - "0" + * - "false" + * - "no" + * - "off" + * - "f" + * - "n" + * + * @function parseBoolean + * @param {any} value - The value to parse into a boolean. + * @param {(boolean|null)} [defaultValue=null] - The value to return if no valid boolean value can be determined. Specifying a non-boolean value will result in null being used instead. + * @returns {(boolean|null)} A value of true if a valid truthy value was determined from the specified value, false if a valid falsey value was determined, otherwise the default value is returned. A value of null will be returned if the default value is not specified. + * @see {@link module:utilities.isBoolean|isBoolean} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseBoolean(true)); // true + * console.log(utilities.parseBoolean("false")); // false + * console.log(utilities.parseBoolean("yes")); // true + * console.log(utilities.parseBoolean(1)); // true + * console.log(utilities.parseBoolean(4)); // null + * console.log(utilities.parseBoolean("wat")); // null + * console.log(utilities.parseBoolean("wot", true)); // true + * console.log(utilities.parseBoolean("huh", 420)); // null + * console.log(utilities.parseBoolean(null)); // null + */ utilities.parseBoolean = function parseBoolean(value, defaultValue) { if(utilities.isBoolean(value)) { return value; @@ -306,6 +864,30 @@ utilities.parseBoolean = function parseBoolean(value, defaultValue) { return defaultValue; }; +/** + * Parses an integer number from a given value. + * Accepts number, string and number object values. + * If no valid integer number can be determined from the specified value, the default value is returned instead. + * + * @function parseInteger + * @param {any} value - The value to parse into a integer number. + * @param {number} [defaultValue=NaN] - The default value to return if the specified value is not an integer or floating point number. + * @returns {number} An integer number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified. + * @see {@link module:utilities.isValidNumber|isValidNumber} + * @see {@link module:utilities.isInvalidNumber|isInvalidNumber} + * @see {@link module:utilities.parseFloat|parseFloat} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseInteger(88)); // 88 + * console.log(utilities.parseInteger(-73.31)); // -73 + * console.log(utilities.parseInteger("-15")); // -15 + * console.log(utilities.parseInteger("3.141592654")); // 3 + * console.log(utilities.parseInteger(new Number(4096))); // 4096 + * console.log(utilities.parseInteger(new Number(3.333))); // 3 + * console.log(utilities.parseInteger("wat", 11100101); // 11100101 + * console.log(utilities.parseInteger(null); // NaN + */ utilities.parseInteger = function parseInteger(value, defaultValue) { var newValue = NaN; @@ -313,10 +895,13 @@ utilities.parseInteger = function parseInteger(value, defaultValue) { newValue = parseInt(value); } else if(typeof value === "string") { - if(validator.isFloat(value)) { + if(utilities.isFloat(value)) { newValue = parseInt(value); } } + else if(value instanceof Number) { + newValue = parseInt(value.valueOf()); + } if(utilities.isInvalidNumber(newValue)) { defaultValue = parseInt(defaultValue); @@ -327,17 +912,44 @@ utilities.parseInteger = function parseInteger(value, defaultValue) { return newValue; }; -utilities.parseFloatingPointNumber = function parseFloatingPointNumber(value, defaultValue) { +/** + * Parses a floating point number from a given value. + * Accepts number, string and number object values. + * If no valid floating point number can be determined from the specified value, the default value is returned instead. + * + * @function parseFloat + * @param {any} value - The value to parse into a floating point number. + * @param {number} [defaultValue=NaN] - The default value to return if the specified value is not a floating point number. + * @returns {number} A floating point number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified. + * @see {@link module:utilities.isValidNumber|isValidNumber} + * @see {@link module:utilities.isInvalidNumber|isInvalidNumber} + * @see {@link module:utilities.parseInteger|parseInteger} + * @since 1.3.7 + * @memberOf module:utilities + * @example + * console.log(utilities.parseFloat(-999)); // -999 + * console.log(utilities.parseFloat(13.37)); // 13.37 + * console.log(utilities.parseFloat("51")); // 51 + * console.log(utilities.parseFloat("-867.5309")); // -867.5309 + * console.log(utilities.parseFloat(new Number(-4231))); // -4231 + * console.log(utilities.parseFloat(new Number(9.999))); // 9.999 + * console.log(utilities.parseFloat("wat", 10010101); // 10010101 + * console.log(utilities.parseFloat(null); // NaN + */ +utilities.parseFloat = function parseFloatingPointNumber(value, defaultValue) { var newValue = NaN; if(typeof value === "number") { newValue = value; } else if(typeof value === "string") { - if(validator.isFloat(value)) { + if(utilities.isFloat(value)) { newValue = parseFloat(value); } } + else if(value instanceof Number) { + newValue = value.valueOf(); + } if(utilities.isInvalidNumber(newValue)) { return utilities.isValidNumber(defaultValue) ? defaultValue : NaN; @@ -346,13 +958,60 @@ utilities.parseFloatingPointNumber = function parseFloatingPointNumber(value, de return newValue; }; +/** + * Parses a floating point number from a given value. + * Accepts number, string and number object values. + * If no valid floating point number can be determined from the specified value, the default value is returned instead. + * + * @function parseFloatingPointNumber + * @param {any} value - The value to parse into a floating point number. + * @param {number} [defaultValue=NaN] - The default value to return if the specified value is not a floating point number. + * @returns {number} A floating point number value if a valid number value was determined from the specified value, otherwise the default value is returned. A value of NaN will be returned if the default value is not specified. + * @deprecated Use utilities.parseFloat instead. Will be removed in a future release. + * @see {@link module:utilities.parseFloat|parseFloat} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseFloatingPointNumber(-1)); // -1 + * console.log(utilities.parseFloatingPointNumber(2.2)); // 1.1 + * console.log(utilities.parseFloatingPointNumber("3")); // 3 + * console.log(utilities.parseFloatingPointNumber("4.4")); // 4.4 + * console.log(utilities.parseFloatingPointNumber(new Number(-5))); // -5 + * console.log(utilities.parseFloatingPointNumber(new Number(6.6))); // 6.6 + * console.log(utilities.parseFloatingPointNumber("nope.avi", 69); // 69 + * console.log(utilities.parseFloatingPointNumber(null); // NaN + */ +utilities.parseFloatingPointNumber = utilities.parseFloat; + +/** + * Parses a date object from a given value. + * Accepts date object, date string, timestamp number string and timestamp number values. + * If no valid date object can be determined from the specified value, the default value is returned instead. + * + * @function parseDate + * @param {any} value - The value to parse into a date object. + * @param {(Date|null)} [defaultValue=null] - The default value to return if the specified value is not a valid date or timestamp. + * @returns {(Date|null)} A Date object instance if a valid date was determined from the specified value, otherwise the default value is returned. A value of null will be returned if the default value is not specified. + * @see {@link module:utilities.isDate|isDate} + * @see {@link module:utilities.compareDates|compateDates} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseDate("June 18, 1987 3:30 PM")); // new Date("1987-06-18T19:30:00.000Z") + * console.log(utilities.parseDate("2018-02-19T06:19:33Z")); // new Date("2018-02-19T06:19:33.000Z") + * console.log(utilities.parseDate(new Date("2020-03-28T18:52:05.136Z"))); // new Date("2020-03-28T18:52:05.136Z") + * console.log(utilities.parseDate(1585421525139)); // new Date("2020-03-28T18:52:05.136Z") + * console.log(utilities.parseDate("1585421525139")); // new Date("2020-03-28T18:52:05.136Z") + * console.log(utilities.parseDate(-1, new Date(0))); // new Date("1970-01-01T00:00:00.000Z") + * console.log(utilities.parseDate(-420)); // null + */ utilities.parseDate = function parseDate(value, defaultValue) { if(!utilities.isDate(defaultValue)) { defaultValue = null; } if(typeof value === "number") { - if(utilities.isInvalidNumber(value) || !Number.isInteger(value)) { + if(utilities.isInvalidNumber(value) || !Number.isInteger(value) || value < 0) { return defaultValue; } @@ -367,7 +1026,7 @@ utilities.parseDate = function parseDate(value, defaultValue) { var timestamp = null; - if(validator.isInt(formattedValue)) { + if(utilities.isInteger(formattedValue)) { timestamp = parseInt(formattedValue); } else { @@ -387,15 +1046,21 @@ utilities.parseDate = function parseDate(value, defaultValue) { return defaultValue; }; -utilities.parseTime = function parseTime(value, throwErrors) { - throwErrors = utilities.parseBoolean(throwErrors); - +/** + * TODO_FUNC_DESC + * + * @function parseTime + * @param {any} value - TODO_ARG_DESC. + * @returns {Object} TODO_RETURN_DESC + * @see {@link module:utilities.parseDate|parseDate} + * @since 1.1.2 + * @memberOf module:utilities + * @example + * console.log(utilities.parseTime()); // TODO_RESULT + */ +utilities.parseTime = function parseTime(value) { if(utilities.isEmptyString(value)) { - if(throwErrors) { - throw new Error("Invalid or empty time value."); - } - - return null; + throw new Error("Invalid or empty time value."); } var formattedValue = value.trim(); @@ -407,11 +1072,7 @@ utilities.parseTime = function parseTime(value, throwErrors) { var regularHour = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[2])); if(utilities.isInvalidNumber(regularHour)) { - if(throwErrors) { - throw new Error("Invalid regular hour: \"" + regularTime[2] + "\"."); - } - - return null; + throw new Error("Invalid regular hour: \"" + regularTime[2] + "\"."); } minutes = utilities.parseInteger(utilities.trimLeadingZeroes(regularTime[4])); @@ -424,11 +1085,7 @@ utilities.parseTime = function parseTime(value, throwErrors) { var morning = period === "AM" ? true : (period === "PM" ? false : null); if(morning === null) { - if(throwErrors) { - throw new Error("Invalid period: \"" + regularTime[5] + "\"."); - } - - return null; + throw new Error("Invalid period: \"" + regularTime[5] + "\"."); } hour = morning ? regularHour + (regularHour === 12 ? 12 : 0) : regularHour + (regularHour === 12 ? 0 : 12); @@ -453,31 +1110,19 @@ utilities.parseTime = function parseTime(value, throwErrors) { } if(utilities.isInvalid(militaryHour) || utilities.isInvalid(militaryMinutes)) { - if(throwErrors) { - throw new Error("Invalid military time: \"" + formattedValue + "\"."); - } - - return null; + throw new Error("Invalid military time: \"" + formattedValue + "\"."); } hour = utilities.parseInteger(utilities.trimLeadingZeroes(militaryHour)); if(utilities.isInvalidNumber(hour)) { - if(throwErrors) { - throw new Error("Invalid military time hour: \"" + militaryHour + "\"."); - } - - return null; + throw new Error("Invalid military time hour: \"" + militaryHour + "\"."); } minutes = utilities.parseInteger(utilities.trimLeadingZeroes(militaryMinutes)); if(utilities.isInvalidNumber(minutes)) { - if(throwErrors) { - throw new Error("Invalid military time minutes: \"" + militaryMinutes + "\"."); - } - - return null; + throw new Error("Invalid military time minutes: \"" + militaryMinutes + "\"."); } if(hour === 24 && minutes === 0) { @@ -485,27 +1130,15 @@ utilities.parseTime = function parseTime(value, throwErrors) { } } else { - if(throwErrors) { - throw new Error("Invalid time: \"" + formattedValue + "\"."); - } - - return null; + throw new Error("Invalid time: \"" + formattedValue + "\"."); } } if(hour < 0 || hour > 23) { - if(throwErrors) { - throw new Error("Time hour is out of range (0 - 23): \"" + hour + "\"."); - } - - return null; + throw new Error("Time hour is out of range (0 - 23): \"" + hour + "\"."); } else if(minutes < 0 || minutes > 59) { - if(throwErrors) { - throw new Error("Time minutes is out of range (0 - 59): \"" + minutes + "\"."); - } - - return null; + throw new Error("Time minutes is out of range (0 - 59): \"" + minutes + "\"."); } var regularHour = hour === 0 ? 12 : (hour <= 12 ? hour : hour - 12); @@ -527,6 +1160,18 @@ utilities.parseTime = function parseTime(value, throwErrors) { }; }; +/** + * TODO_FUNC_DESC + * + * @function parseEmail + * @param {string} value - A string containing an email address. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.parseEmailDomain|parseEmailDomain} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseEmail()); // TODO_RESULT + */ utilities.parseEmail = function parseEmail(value) { if(utilities.isEmptyString(value)) { return null; @@ -541,6 +1186,19 @@ utilities.parseEmail = function parseEmail(value) { return emailData[1] + emailData[3]; }; +/** + * TODO_FUNC_DESC + * + * @function parseEmailDomain + * @param {string} value - A string containing an email address. + * @deprecated Use value.split("@", 2)[1] instead. Will be removed in a future release. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.parseEmail|parseEmail} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseEmailDomain()); // TODO_RESULT + */ utilities.parseEmailDomain = function parseEmailDomain(value) { if(utilities.isEmptyString(value)) { return null; @@ -555,6 +1213,20 @@ utilities.parseEmailDomain = function parseEmailDomain(value) { return emailDomainData[3]; }; +/** + * TODO_FUNC_DESC + * + * @function parseStringList + * @param {string} value - A comma or semicolon separated list of string values. + * @returns {(string[]|null)} An array of strings as parsed from the specified string list or null if the specified value is not a string. + * @see {@link module:utilities.formatStringList|formatStringList} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseStringList("w, a, t")); // ["w", "a", "t"] + * console.log(utilities.parseStringList("ok")); // ["ok"] + * console.log(utilities.parseStringList([])); // null + */ utilities.parseStringList = function parseStringList(value) { if(typeof value !== "string") { return null; @@ -581,6 +1253,23 @@ utilities.parseStringList = function parseStringList(value) { return formattedList; }; +/** + * TODO_FUNC_DESC + * + * @function parseRegularExpression + * @param {string} value - The string value to parse a regular expression from. + * @param {boolean} [throwErrors=false] - Determines if errors should be thrown or not when invalid regular expression values are encountered. + * @returns {(RegExp|null)} Returns a RegExp object instance if a valid regular expression was parsed from the specified value or null if the value was invalid and throwErrors is unspecified or set to false. + * @throws Will optionally throw an error if the regular expression is invalid and throwErrors is set to true. + * @see {@link module:utilities.isRegularExpression|isRegularExpression} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseRegularExpression("/(regexp?)/gi")); // new RegExp("(regexp?)", "gi") + * console.log(utilities.parseRegularExpression(new RegExp("ok"))); // new RegExp("ok") + * console.log(utilities.parseRegularExpression({ })); // null + * console.log(utilities.parseRegularExpression(/invalid/x, true)); // throws Error + */ utilities.parseRegularExpression = function parseRegularExpression(value, throwErrors) { throwErrors = utilities.parseBoolean(throwErrors, false); @@ -606,18 +1295,34 @@ utilities.parseRegularExpression = function parseRegularExpression(value, throwE return null; } - if(throwErrors) { - return new RegExp(regExpData[1], regExpData[2]); - } - try { return new RegExp(regExpData[1], regExpData[2]); } catch(error) { + if(throwErrors) { + throw error; + } + return null; } }; +/** + * TODO_FUNC_DESC + * + * @function parseYouTubeLink + * @param {string} value - The string URL value to parse a YouTube video identifier from. + * @returns {(string|null)} A string value containing the YouTube video ID or null if the video ID could be determined from the specified value. + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.parseYouTubeLink("http://youtube.com/v/OEEEy1dMceI")); // OEEEy1dMceI + * console.log(utilities.parseYouTubeLink("https://www.youtube.com/watch?v=NUnwFHplBg4")); // NUnwFHplBg4 + * console.log(utilities.parseYouTubeLink("www.youtu.be/watch?v=Dkm8Hteeh6M")); // Dkm8Hteeh6M + * console.log(utilities.parseYouTubeLink("https://youtu.be/v/z874bjpO9d8")); // z874bjpO9d8 + * console.log(utilities.parseYouTubeLink("https://www.nitro404.com")); // null + * console.log(utilities.parseYouTubeLink(NaN)); // null + */ utilities.parseYouTubeLink = function parseYouTubeLink(value) { if(utilities.isEmptyString(value)) { return null; @@ -637,6 +1342,19 @@ utilities.parseYouTubeLink = function parseYouTubeLink(value) { return null; }; +/** + * TODO_FUNC_DESC + * + * @function formatValue + * @param {any} value - The value to format. + * @param {Object} format - The format specification. + * @param {Object} [options] - Formatting options. + * @returns {any} The formatted value. + * @since 1.1.1 + * @memberOf module:utilities + * @example + * console.log(utilities.formatValue()); // TODO_RESULT + */ utilities.formatValue = function formatValue(value, format, options) { if(utilities.isObjectStrict(options)) { options = { @@ -1257,6 +1975,22 @@ utilities.formatValue = function formatValue(value, format, options) { return formattedValue; }; +/** + * TODO_FUNC_DESC + * + * @function formatObject + * @param {Object} object - The object to format. + * @param {Object} format - The format specification. + * @param {(boolean|Object)} [removeExtra=false] - Remove extra flag or formatting options object. + * @param {boolean} [throwErrors=false] - Remove extra flag or formatting options object. + * @returns {Object} The formatted object. + * @deprecated Use formatValue instead. Will be removed in a future release. + * @see {@link module:utilities.formatValue|formatValue} + * @since 1.1.1 + * @memberOf module:utilities + * @example + * console.log(utilities.formatObject()); // TODO_RESULT + */ utilities.formatObject = function formatObject(object, format, removeExtra, throwErrors) { if(!utilities.isObjectStrict(object) && (!utilities.isObjectStrict(removeExtra) || !utilities.isFunction(removeExtra.parser))) { return { }; @@ -1335,6 +2069,19 @@ utilities.formatObject = function formatObject(object, format, removeExtra, thro return utilities.isObjectStrict(formattedObject) || (utilities.isObjectStrict(removeExtra) && utilities.isFunction(removeExtra.parser)) ? formattedObject : { }; }; +/** + * TODO_FUNC_DESC + * + * @function formatStringList + * @param {(string|string[])} value - The string list to format. + * @param {(boolean|null)} stringify - TODO_ARG_DESC + * @returns {string} The formatted string list. + * @see {@link module:utilities.parseStringList|parseStringList} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.formatStringList()); // TODO_RESULT + */ utilities.formatStringList = function formatStringList(value, stringify) { var data = null; @@ -1386,6 +2133,19 @@ utilities.formatStringList = function formatStringList(value, stringify) { return formattedList; }; +/** + * TODO_FUNC_DESC + * + * @function leftShift + * @param {number} number - The number value to bit shift. + * @param {number} bits - The number of bits to shift the value left by. + * @returns {number} The number value right shifted by the specified number of bits. + * @see {@link module:utilities.rightShift|rightShift} + * @since 1.2.19 + * @memberOf module:utilities + * @example + * console.log(utilities.leftShift()); // TODO_RESULT + */ utilities.leftShift = function leftShift(number, bits) { if(!Number.isInteger(number) || !Number.isInteger(bits)) { return NaN; @@ -1394,6 +2154,19 @@ utilities.leftShift = function leftShift(number, bits) { return number * Math.pow(2, bits); }; +/** + * TODO_FUNC_DESC + * + * @function rightShift + * @param {number} number - The number value to bit shift. + * @param {number} bits - The number of bits to shift the value right by. + * @returns {number} The number value right shifted by the specified number of bits. + * @see {@link module:utilities.leftShift|leftShift} + * @since 1.2.19 + * @memberOf module:utilities + * @example + * console.log(utilities.rightShift()); // TODO_RESULT + */ utilities.rightShift = function rightShift(number, bits) { if(!Number.isInteger(number) || !Number.isInteger(bits)) { return NaN; @@ -1402,13 +2175,49 @@ utilities.rightShift = function rightShift(number, bits) { return number / Math.pow(2, bits); }; +/** + * TODO_FUNC_DESC + * + * @function trimString + * @param {string} value - The string to trim. + * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.isEmptyString|isEmptyString} + * @see {@link module:utilities.isNonEmptyString|isNonEmptyString} + * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString} + * @see {@link module:utilities.trimWhitespace|trimWhitespace} + * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines} + * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.trimString()); // TODO_RESULT + */ utilities.trimString = function trimString(value, defaultValue) { - return typeof value === "string" ? value.trim() : (defaultValue === undefined ? null : defaultValue); -}; - + return typeof value === "string" ? value.trim() : (typeof defaultValue === "string" ? defaultValue : null); +}; + +/** + * TODO_FUNC_DESC + * + * @function trimNullTerminatedString + * @param {string} value - The null-terminated string to trim. + * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.isEmptyString|isEmptyString} + * @see {@link module:utilities.isNonEmptyString|isNonEmptyString} + * @see {@link module:utilities.trimString|trimString} + * @see {@link module:utilities.trimWhitespace|trimWhitespace} + * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines} + * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.trimNullTerminatedString()); // TODO_RESULT + */ utilities.trimNullTerminatedString = function trimNullTerminatedString(value, defaultValue) { if(typeof value !== "string") { - return defaultValue === undefined ? null : defaultValue; + return typeof defaultValue === "string" ? defaultValue : null; } var nullTerminatorIndex = value.indexOf("\0"); @@ -1420,9 +2229,28 @@ utilities.trimNullTerminatedString = function trimNullTerminatedString(value, de return value; }; -utilities.trimWhitespace = function trimWhitespace(value, trimNewlines) { +/** + * TODO_FUNC_DESC + * + * @function trimWhitespace + * @param {string} value - The string to trim whitespace characters from. + * @param {boolean} trimNewlines - TODO_ARG_DESC. + * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.isEmptyString|isEmptyString} + * @see {@link module:utilities.isNonEmptyString|isNonEmptyString} + * @see {@link module:utilities.trimString|trimString} + * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString} + * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines} + * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.trimWhitespace()); // TODO_RESULT + */ +utilities.trimWhitespace = function trimWhitespace(value, trimNewlines, defaultValue) { if(typeof value !== "string") { - return null; + return typeof defaultValue === "string" ? defaultValue : null; } var trimmedString = value.replace(/^[ \t]+|[ \t]+$/gm, ""); @@ -1434,9 +2262,27 @@ utilities.trimWhitespace = function trimWhitespace(value, trimNewlines) { return trimmedString; }; -utilities.trimTrailingNewlines = function trimTrailingNewlines(value) { +/** + * TODO_FUNC_DESC + * + * @function trimTrailingNewlines + * @param {string} value - The string to trim trailing newline characters from. + * @param {(string|null)} [defaultValue=null] - The default value to return if the specified value is not a string. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.isEmptyString|isEmptyString} + * @see {@link module:utilities.isNonEmptyString|isNonEmptyString} + * @see {@link module:utilities.trimString|trimString} + * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString} + * @see {@link module:utilities.trimWhitespace|trimWhitespace} + * @see {@link module:utilities.replaceNonBreakingSpaces|replaceNonBreakingSpaces} + * @since 1.1.5 + * @memberOf module:utilities + * @example + * console.log(utilities.trimTrailingNewlines()); // TODO_RESULT + */ +utilities.trimTrailingNewlines = function trimTrailingNewlines(value, defaultValue) { if(typeof value !== "string") { - return null; + return typeof defaultValue === "string" ? defaultValue : null; } if(utilities.isEmptyString(value)) { @@ -1446,10 +2292,41 @@ utilities.trimTrailingNewlines = function trimTrailingNewlines(value) { return value.replace(/[ \t\r\n]+$/, ""); }; +/** + * TODO_FUNC_DESC + * + * @function replaceNonBreakingSpaces + * @param {string} value - The string to replace non breaking spaces in. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.isEmptyString|isEmptyString} + * @see {@link module:utilities.isNonEmptyString|isNonEmptyString} + * @see {@link module:utilities.trimString|trimString} + * @see {@link module:utilities.trimNullTerminatedString|trimNullTerminatedString} + * @see {@link module:utilities.trimWhitespace|trimWhitespace} + * @see {@link module:utilities.trimTrailingNewlines|trimTrailingNewlines} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.replaceNonBreakingSpaces()); // TODO_RESULT + */ utilities.replaceNonBreakingSpaces = function replaceNonBreakingSpaces(value) { return typeof value === "string" ? value.replace(/ /gi, " ") : null; }; +/** + * TODO_FUNC_DESC + * + * @function indentText + * @param {string} value - The string to indent. + * @param {number} [amount=1] - The amount of times to indent the string. + * @param {indentation} [indentation="\t"] - The indentation string to use. + * @param {boolean} [clearEmptyLines=true] - Determines if empty lines should be trimmed or not. + * @returns {(string|null)} TODO_RETURN_DESC + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.indentText()); // TODO_RESULT + */ utilities.indentText = function indentText(value, amount, indentation, clearEmptyLines) { if(typeof value !== "string") { return null; @@ -1484,6 +2361,18 @@ utilities.indentText = function indentText(value, amount, indentation, clearEmpt return indentedParagraph; }; +/** + * TODO_FUNC_DESC + * + * @function trimLeadingZeroes + * @param {string} value - The string to remove leading zeroes from. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.addLeadingZeroes|addLeadingZeroes} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.trimLeadingZeroes()); // TODO_RESULT + */ utilities.trimLeadingZeroes = function trimLeadingZeroes(value) { if(typeof value !== "string") { return null; @@ -1505,6 +2394,19 @@ utilities.trimLeadingZeroes = function trimLeadingZeroes(value) { return formattedValue.replace(/^0+/, ""); }; +/** + * TODO_FUNC_DESC + * + * @function addLeadingZeroes + * @param {string} value - The string to add leading zeroes to. + * @param {number} [expectedLength=NaN] - The expected minimum length of the string after zeroes have been prepended to it. + * @returns {(string|null)} TODO_RETURN_DESC + * @see {@link module:utilities.trimLeadingZeroes|trimLeadingZeroes} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.addLeadingZeroes()); // TODO_RESULT + */ utilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) { if(utilities.isInvalid(value)) { return null; @@ -1526,6 +2428,26 @@ utilities.addLeadingZeroes = function addLeadingZeroes(value, expectedLength) { return value; }; +/** + * TODO_FUNC_DESC + * + * @function toString + * @param {any} value - The value to convert into a string. + * @returns {string} A string representation of the specified value. + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.toString(undefined)); // "undefined" + * console.log(utilities.toString(null)); // "null" + * console.log(utilities.toString(Infinity)); // "Infinity" + * console.log(utilities.toString(-Infinity)); // "-Infinity" + * console.log(utilities.toString(NaN)); // "NaN" + * console.log(utilities.toString("test")); // "\"test\"" + * console.log(utilities.toString(new Date(0))); // "1970-01-01T00:00:00.000Z" + * console.log(utilities.toString(function() { })); // "function() { }" + * console.log(utilities.toString({ door: "stuck" })); // "{\"door":\"stuck\"}" + * console.log(utilities.toString([4, 2, "0"])); // "[4,2,\"0\"]" + */ utilities.toString = function toString(value) { if(value === undefined) { return "undefined"; @@ -1545,10 +2467,10 @@ utilities.toString = function toString(value) { else if(typeof value === "number" && isNaN(value)) { return "NaN"; } - else if(utilities.isDate(value)) { + else if(value instanceof Date) { return value.toString(); } - else if(utilities.isRegularExpression(value)) { + else if(value instanceof RegExp) { var flags = ""; for(var flag in regExpFlags) { @@ -1559,22 +2481,30 @@ utilities.toString = function toString(value) { return "/" + value.source + "/" + flags; } - else if(utilities.isFunction(value)) { + else if(value instanceof Function) { return value.toString(); } - else if(utilities.isError(value)) { - var error = { message: value.message }; - - for(var attribute in value) { - error[attribute] = value[attribute]; - } - - return JSON.stringify(error); + else if(value instanceof Error) { + return value.stack; } return JSON.stringify(value); }; +/** + * TODO_FUNC_DESC + * + * @function compareDates + * @param {any} a - The first date to compare. + * @param {any} b - The second date to compare. + * @returns {number} TODO_RETURN_DESC + * @see {@link module:utilities.isDate|isDate} + * @see {@link module:utilities.parseDate|parseDate} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.compareDates()); // TODO_RESULT + */ utilities.compareDates = function compareDates(a, b) { a = utilities.parseDate(a); b = utilities.parseDate(b); @@ -1593,6 +2523,17 @@ utilities.compareDates = function compareDates(a, b) { return a.getTime() - b.getTime(); }; +/** + * TODO_FUNC_DESC + * + * @function compareCasePercentage + * @param {string} value - The string value to compare the case percentage of. + * @returns {number} TODO_RETURN_DESC + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.compareCasePercentage()); // TODO_RESULT + */ utilities.compareCasePercentage = function compareCasePercentage(value) { if(utilities.isEmptyString(value)) { return 0; @@ -1620,6 +2561,18 @@ utilities.compareCasePercentage = function compareCasePercentage(value) { return upper - lower; }; +/** + * Reverses a string value with special handling for unicode characters. + * + * @function reverseString + * @param {string} value - The string value to reverse. + * @returns {(string|null)} The reversed representation of the specified string value or a value of null if the specified value is not a string. + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.reverseString("backwards")); // "sdrawkcab" + * console.log(utilities.reverseString(NaN)); // null + */ utilities.reverseString = function reverseString(value) { if(typeof value !== "string") { return null; @@ -1641,12 +2594,38 @@ utilities.reverseString = function reverseString(value) { return reverse; }; +/** + * Creates an Error object instance with the specified message and HTTP status code. + * + * @function createError + * @param {string} message - The error message. + * @param {number} [status=500] - The HTTP status code of the error. + * @returns {Error} The error with the specified message and status code property. + * @deprecated Use new Error() instead. Will be removed in a future release. + * @see {@link module:utilities.isError|isError} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.createError("COOL HATS ONLY.", 401)); // new Error("COOL HATS ONLY.") (with status property set to 401) + */ utilities.createError = function createError(message, status) { var error = new Error(message); error.status = utilities.parseInteger(status, 500); return error; }; +/** + * TODO_FUNC_DESC + * + * @function clone + * @param {any} value - The value to clone. + * @returns {any} A copy of the specified value. + * @see {@link module:utilities.merge|merge} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.clone({ some: "value" })); // {"some":"value"} + */ utilities.clone = function clone(value) { if(!utilities.isObject(value)) { return value; @@ -1719,6 +2698,21 @@ utilities.clone = function clone(value) { return value; }; +/** + * TODO_FUNC_DESC + * + * @function merge + * @param {Object} a - The object to merge into. + * @param {Object} b - The object whose properties are being merged. + * @param {boolean} [copy=true] - Determines if a copy of the first object should be made before merging. + * @param {boolean} [deepMerge=true] - Determines if properties should be recursively merged or just the base properties. + * @returns {(Object|null)} TODO_RETURN_DESC + * @see {@link module:utilities.clone|clone} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.merge({ a: 1 }, { b: 2 })); // { a: 1, b: 2 } + */ utilities.merge = function merge(a, b, copy, deepMerge) { if(!utilities.isObject(a) || Array.isArray(a)) { return null; @@ -1768,6 +2762,27 @@ utilities.merge = function merge(a, b, copy, deepMerge) { return newObject; }; +/** + * TODO_FUNC_DESC + * + * @function getFileName + * @param {string} filePath - A file path string to retrieve the file name from. + * @returns {(string|null)} Returns a string value containing the name of the file or null if the file path was not a string. + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.truncateFileName|truncateFileName} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.getFileName("C:\settings.ini")); // "settings.ini" + * console.log(utilities.getFileName("/var/tmp/test.txt")); // "test.txt" + * console.log(utilities.getFileName("MyApp.wgt")); // "MyApp.wgt" + * console.log(utilities.getFileName(NaN)); // null + */ utilities.getFileName = function getFileName(filePath) { if(typeof filePath !== "string") { return null; @@ -1784,6 +2799,24 @@ utilities.getFileName = function getFileName(filePath) { return filePath; }; +/** + * TODO_FUNC_DESC + * + * @function getFilePath + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.truncateFileName|truncateFileName} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.getFilePath()); // TODO_RESULT + */ utilities.getFilePath = function getFilePath(filePath) { if(typeof filePath !== "string") { return null; @@ -1800,6 +2833,24 @@ utilities.getFilePath = function getFilePath(filePath) { return ""; }; +/** + * TODO_FUNC_DESC + * + * @function getFileNameNoExtension + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.truncateFileName|truncateFileName} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.getFileNameNoExtension()); // TODO_RESULT + */ utilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) { if(typeof fileName !== "string") { return null; @@ -1816,6 +2867,24 @@ utilities.getFileNameNoExtension = function getFileNameNoExtension(fileName) { return fileName; }; +/** + * TODO_FUNC_DESC + * + * @function getFileExtension + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.truncateFileName|truncateFileName} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.getFileExtension()); // TODO_RESULT + */ utilities.getFileExtension = function getFileExtension(fileName) { if(typeof fileName !== "string") { return null; @@ -1832,6 +2901,24 @@ utilities.getFileExtension = function getFileExtension(fileName) { return ""; }; +/** + * TODO_FUNC_DESC + * + * @function fileHasExtension + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.truncateFileName|truncateFileName} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.fileHasExtension()); // TODO_RESULT + */ utilities.fileHasExtension = function fileHasExtension(fileName, extension) { if(utilities.isEmptyString(fileName) || utilities.isEmptyString(extension)) { return false; @@ -1846,6 +2933,24 @@ utilities.fileHasExtension = function fileHasExtension(fileName, extension) { return actualFileExtension.toLowerCase() === extension.trim().toLowerCase(); }; +/** + * TODO_FUNC_DESC + * + * @function reverseFileExtension + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.truncateFileName|truncateFileName} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.reverseFileExtension()); // TODO_RESULT + */ utilities.reverseFileExtension = function reverseFileExtension(fileName) { if(typeof fileName !== "string") { return null; @@ -1862,6 +2967,24 @@ utilities.reverseFileExtension = function reverseFileExtension(fileName) { return fileName; }; +/** + * TODO_FUNC_DESC + * + * @function truncateFileName + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.joinPaths|joinPaths} + * @since 1.2.18 + * @memberOf module:utilities + * @example + * console.log(utilities.truncateFileName()); // TODO_RESULT + */ utilities.truncateFileName = function truncateFileName(fileName, maxLength) { if(typeof fileName !== "string") { return null; @@ -1905,6 +3028,19 @@ utilities.truncateFileName = function truncateFileName(fileName, maxLength) { return originalFileName.substring(0, maxLength - extension.length - (extension.length > 0 ? 1 : 0)) + (extension.length > 0 ? "." + extension : ""); }; +/** + * TODO_FUNC_DESC + * + * @function prependSlash + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.joinPaths|joinPaths} + * @see {@link module:utilities.appendSlash|appendSlash} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.prependSlash()); // TODO_RESULT + */ utilities.prependSlash = function prependSlash(value) { if(typeof value !== "string") { return null; @@ -1923,6 +3059,19 @@ utilities.prependSlash = function prependSlash(value) { return formattedValue; }; +/** + * TODO_FUNC_DESC + * + * @function appendSlash + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.joinPaths|joinPaths} + * @see {@link module:utilities.prependSlash|prependSlash} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.appendSlash()); // TODO_RESULT + */ utilities.appendSlash = function appendSlash(value) { if(typeof value !== "string") { return null; @@ -1941,26 +3090,90 @@ utilities.appendSlash = function appendSlash(value) { return formattedValue; }; -utilities.joinPaths = function joinPaths(base, path) { - var formattedBase = typeof base === "string" ? base.trim().replace(/[\/\\]+$/, "") : null; - var formattedPath = typeof path === "string" ? path.trim().replace(/^[\/\\]+/, "") : null; +/** + * TODO_FUNC_DESC + * + * @function joinPaths + * @param {...string|string[]} paths - TODO_ARG_DESC. + * @param {Object} [options] - TODO_ARG_DESC. + * @returns {string} TODO_RETURN_DESC + * @see {@link module:utilities.getFileName|getFileName} + * @see {@link module:utilities.getFilePath|getFilePath} + * @see {@link module:utilities.getFileNameNoExtension|getFileNameNoExtension} + * @see {@link module:utilities.getFileExtension|getFileExtension} + * @see {@link module:utilities.fileHasExtension|fileHasExtension} + * @see {@link module:utilities.reverseFileExtension|reverseFileExtension} + * @see {@link module:utilities.joinPaths|joinPaths} + * @see {@link module:utilities.prependSlash|prependSlash} + * @see {@link module:utilities.appendSlash|appendSlash} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.joinPaths()); // TODO_RESULT + */ +utilities.joinPaths = function joinPaths(paths, options) { + if(!Array.isArray(paths)) { + paths = Array.prototype.slice.call(arguments); + } + + if(paths.length !== 0 && utilities.isObjectStrict(paths[paths.length - 1])) { + options = paths.splice(paths.length - 1, 1)[0]; + } + + if(!utilities.isObjectStrict(options)) { + options = { }; + } + + options.separator = utilities.trimString(options.separator); + + if(options.separator !== "/" && options.separator !== "\\") { + options.separator = "/"; + } + var newPath = ""; - if(utilities.isNonEmptyString(formattedBase)) { - newPath += formattedBase; + for(var i = 0; i < paths.length; i++) { + var path = utilities.trimString(paths[i]); - if(utilities.isNonEmptyString(formattedPath)) { - newPath += "/"; + if(utilities.isEmptyString(path)) { + continue; } - } - if(utilities.isNonEmptyString(formattedPath)) { - newPath += formattedPath; + if(utilities.isEmptyString(newPath)) { + if(path === "/" || path === "\\") { + newPath = path; + } + else { + newPath = path.replace(/[\/\\]+$/, ""); + } + } + else { + path = path.replace(/^[\/\\]+/, ""); + + if(utilities.isNonEmptyString(path)) { + if(newPath[newPath.length - 1] !== options.separator) { + newPath += options.separator; + } + + newPath += path; + } + } } - return newPath; + return newPath.replace(/[\/\\]/g, options.separator); }; +/** + * TODO_FUNC_DESC + * + * @function createQueryString + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.createQueryString()); // TODO_RESULT + */ utilities.createQueryString = function createQueryString(value, includeQuestionMark) { if(!utilities.isObjectStrict(value)) { return ""; @@ -1977,6 +3190,18 @@ utilities.createQueryString = function createQueryString(value, includeQuestionM return (utilities.parseBoolean(includeQuestionMark, false) ? "?" : "") + parameters; }; +/** + * TODO_FUNC_DESC + * + * @function createRange + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @deprecated Determined to no longer be useful, will be removed in a future release. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.createRange()); // TODO_RESULT + */ utilities.createRange = function createRange(start, end) { var formattedStart = utilities.parseInteger(start); var formattedEnd = utilities.parseInteger(end); @@ -1999,6 +3224,17 @@ utilities.createRange = function createRange(start, end) { return range; }; +/** + * TODO_FUNC_DESC + * + * @function futureMonths + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.futureMonths()); // TODO_RESULT + */ utilities.futureMonths = function futureMonths(date, prependZero) { date = utilities.parseDate(date); @@ -2031,6 +3267,19 @@ utilities.futureMonths = function futureMonths(date, prependZero) { return months; }; +/** + * TODO_FUNC_DESC + * + * @function visibleElements + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @see {@link module:utilities.hiddenElements|hiddenElements} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.visibleElements()); // TODO_RESULT + */ utilities.visibleElements = function visibleElements(elements) { if(!Array.isArray(elements)) { return []; @@ -2047,6 +3296,19 @@ utilities.visibleElements = function visibleElements(elements) { return visibleElements; }; +/** + * TODO_FUNC_DESC + * + * @function hiddenElements + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @see {@link module:utilities.visibleElements|visibleElements} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.hiddenElements()); // TODO_RESULT + */ utilities.hiddenElements = function hiddenElements(elements) { if(!Array.isArray(elements)) { return []; @@ -2063,6 +3325,19 @@ utilities.hiddenElements = function hiddenElements(elements) { return hiddenElements; }; +/** + * TODO_FUNC_DESC + * + * @function enabledElements + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @see {@link module:utilities.disabledElements|disabledElements} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.enabledElements()); // TODO_RESULT + */ utilities.enabledElements = function enabledElements(elements) { if(!Array.isArray(elements)) { return []; @@ -2079,6 +3354,19 @@ utilities.enabledElements = function enabledElements(elements) { return enabledElements; }; +/** + * TODO_FUNC_DESC + * + * @function disabledElements + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @see {@link module:utilities.enabledElements|enabledElements} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.disabledElements()); // TODO_RESULT + */ utilities.disabledElements = function disabledElements(elements) { if(!Array.isArray(elements)) { return []; @@ -2095,6 +3383,19 @@ utilities.disabledElements = function disabledElements(elements) { return disabledElements; }; +/** + * TODO_FUNC_DESC + * + * @function elementsWithAttribute + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @see {@link module:utilities.elementsWithoutAttribute|elementsWithoutAttribute} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.elementsWithAttribute()); // TODO_RESULT + */ utilities.elementsWithAttribute = function elementsWithAttribute(elements, attribute, hasAttribute) { if(!Array.isArray(elements) || utilities.isEmptyString(attribute)) { return []; @@ -2128,10 +3429,35 @@ utilities.elementsWithAttribute = function elementsWithAttribute(elements, attri return filteredElements; }; +/** + * TODO_FUNC_DESC + * + * @function elementsWithoutAttribute + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @see {@link module:utilities.elementsWithAttribute|elementsWithAttribute} + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.elementsWithoutAttribute()); // TODO_RESULT + */ utilities.elementsWithoutAttribute = function elementsWithoutAttribute(elements, attribute) { return utilities.elementsWithAttribute(elements, attribute, false); }; +/** + * TODO_FUNC_DESC + * + * @function matchAttribute + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @deprecated Use Array.filter() instead. Will be removed in a future release. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @since 1.0.0 + * @memberOf module:utilities + * @example + * console.log(utilities.matchAttribute()); // TODO_RESULT + */ utilities.matchAttribute = function matchAttribute(element, attribute, value) { if(!utilities.isObject(element)) { return false; @@ -2144,6 +3470,19 @@ utilities.matchAttribute = function matchAttribute(element, attribute, value) { return element[attribute.trim()] === value; }; +/** + * TODO_FUNC_DESC + * + * @function generateVersions + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.parseVersion|parseVersion} + * @see {@link module:utilities.compareVersions|compareVersions} + * @since 1.0.3 + * @memberOf module:utilities + * @example + * console.log(utilities.generateVersions()); // TODO_RESULT + */ utilities.generateVersions = function generateVersions(version, prefix, suffix) { version = utilities.parseVersion(version); @@ -2182,6 +3521,19 @@ utilities.generateVersions = function generateVersions(version, prefix, suffix) return versions; }; +/** + * TODO_FUNC_DESC + * + * @function parseVersion + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.generateVersions|generateVersions} + * @see {@link module:utilities.compareVersions|compareVersions} + * @since 1.0.3 + * @memberOf module:utilities + * @example + * console.log(utilities.parseVersion()); // TODO_RESULT + */ utilities.parseVersion = function parseVersion(value, trimTrailingZeroes) { var formattedValue = utilities.isValidNumber(value) ? value.toString() : value; @@ -2199,7 +3551,7 @@ utilities.parseVersion = function parseVersion(value, trimTrailingZeroes) { var part = null; for(var i = 0; i < versionData.length; i++) { - if(validator.isInt(versionData[i])) { + if(utilities.isInteger(versionData[i])) { part = utilities.parseInteger(versionData[i]); if(utilities.isInvalidNumber(part) || part < 0) { @@ -2231,28 +3583,32 @@ utilities.parseVersion = function parseVersion(value, trimTrailingZeroes) { return version.length === 0 ? null : version; }; -utilities.compareVersions = function compareVersions(v1, v2, caseSensitive, throwErrors) { +/** + * TODO_FUNC_DESC + * + * @function compareVersions + * @param {TODO_ARG_TYPE} TODO_ARG_NAME - TODO_ARG_DESC. + * @returns {TODO_RETURN_TYPE} TODO_RETURN_DESC + * @see {@link module:utilities.generateVersions|generateVersions} + * @see {@link module:utilities.parseVersion|parseVersion} + * @since 1.0.3 + * @memberOf module:utilities + * @example + * console.log(utilities.compareVersions()); // TODO_RESULT + */ +utilities.compareVersions = function compareVersions(v1, v2, caseSensitive) { caseSensitive = utilities.parseBoolean(caseSensitive, false); - throwErrors = utilities.parseBoolean(throwErrors, false); v1 = utilities.parseVersion(v1); if(v1 === null) { - if(throwErrors) { - throw new Error("Cannot compare invalid or empty first version."); - } - - return null; + throw new Error("Cannot compare invalid or empty first version."); } v2 = utilities.parseVersion(v2); if(v2 === null) { - if(throwErrors) { - throw new Error("Cannot compare invalid or empty second version."); - } - - return null; + throw new Error("Cannot compare invalid or empty second version."); } var index = 0; diff --git a/test/test.js b/test/test.js index 3b2f6db..72002f3 100644 --- a/test/test.js +++ b/test/test.js @@ -118,6 +118,56 @@ describe("Utilities", function() { }); }); + describe("isInteger", function() { + const newTestData = testData.concat("8675309", "4.20", "007", new Number(88), new Number(3.141592654), new Number(-32), new Number(-6.9)); + + it("should be a function", function() { + expect(utilities.isInteger).to.be.an.instanceof(Function); + }); + + it("should produce the correct result for each test value", function() { + const results = [false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, true, false, true, false]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.isInteger(newTestData[i])).to.equal(results[i]); + expect(utilities.isInteger(newTestData[i], true)).to.equal(results[i]); + } + }); + + it("should produce the correct result for each test value with number objects disallowed", function() { + const results = [false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.isInteger(newTestData[i], false)).to.equal(results[i]); + } + }); + }); + + describe("isFloat", function() { + const newTestData = testData.concat("8008135", "3.50", "006", new Number(90210), new Number(1.234), new Number(-64), new Number(-9.6)); + + it("should be a function", function() { + expect(utilities.isFloat).to.be.an.instanceof(Function); + }); + + it("should produce the correct result for each test value", function() { + const results = [false, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, true, true, true, true]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.isFloat(newTestData[i])).to.equal(results[i]); + expect(utilities.isFloat(newTestData[i], true)).to.equal(results[i]); + } + }); + + it("should produce the correct result for each test value with number objects disallowed", function() { + const results = [false, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.isFloat(newTestData[i], false)).to.equal(results[i]); + } + }); + }); + describe("isEmptyString", function() { const newTestData = testData.concat(" ", "\t", " \t"); @@ -555,14 +605,14 @@ describe("Utilities", function() { }); describe("parseInteger", function() { - const newTestData = testData.concat(-69, -3.33333, 88, "-32", "-1", "0", "1", "64", "-1.1", "0.48", "2.71828"); + const newTestData = testData.concat(-69, -3.33333, 88, "-32", "-1", "0", "1", "64", "-1.1", "0.48", "2.71828", new Number(420), new Number(-3.141592654)); it("should be a function", function() { expect(utilities.parseInteger).to.be.an.instanceof(Function); }); it("should produce the correct result for each test value", function() { - const results = [NaN, NaN, NaN, NaN, NaN, NaN, 0, 1, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, -69, -3, 88, -32, -1, 0, 1, 64, -1, 0, 2]; + const results = [NaN, NaN, NaN, NaN, NaN, NaN, 0, 1, 3, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, -69, -3, 88, -32, -1, 0, 1, 64, -1, 0, 2, 420, -3]; for(let i = 0; i < newTestData.length; i++) { if(isNaN(results[i])) { @@ -576,7 +626,7 @@ describe("Utilities", function() { it("should produce the correct result for each test value with a custom default", function() { const defaultInteger = 420; - const results = [defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, 0, 1, 3, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, -69, -3, 88, -32, -1, 0, 1, 64, -1, 0, 2]; + const results = [defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, 0, 1, 3, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, defaultInteger, -69, -3, 88, -32, -1, 0, 1, 64, -1, 0, 2, 420, -3]; for(let i = 0; i < newTestData.length; i++) { expect(utilities.parseInteger(newTestData[i], defaultInteger)).to.equal(results[i]); @@ -584,45 +634,45 @@ describe("Utilities", function() { }); }); - describe("parseFloatingPointNumber", function() { - const newTestData = testData.concat(-69, -3.33333, 88, "-32", "-1", "0", "1", "64", "-1.1", "0.48", "2.71828"); + describe("parseFloat", function() { + const newTestData = testData.concat(-69, -3.33333, 88, "-32", "-1", "0", "1", "64", "-1.1", "0.48", "2.71828", new Number(21), new Number(-867.5309)); it("should be a function", function() { - expect(utilities.parseFloatingPointNumber).to.be.an.instanceof(Function); + expect(utilities.parseFloat).to.be.an.instanceof(Function); }); it("should produce the correct result for each test value", function() { - const results = [NaN, NaN, NaN, NaN, NaN, NaN, 0, 1, 3.141592654, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, -69, -3.33333, 88, -32, -1, 0, 1, 64, -1.1, 0.48, 2.71828]; + const results = [NaN, NaN, NaN, NaN, NaN, NaN, 0, 1, 3.141592654, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, -69, -3.33333, 88, -32, -1, 0, 1, 64, -1.1, 0.48, 2.71828, 21, -867.5309]; for(let i = 0; i < newTestData.length; i++) { if(isNaN(results[i])) { - expect(isNaN(utilities.parseFloatingPointNumber(newTestData[i]))).to.equal(true); + expect(isNaN(utilities.parseFloat(newTestData[i]))).to.equal(true); } else { - expect(utilities.parseFloatingPointNumber(newTestData[i])).to.equal(results[i]); + expect(utilities.parseFloat(newTestData[i])).to.equal(results[i]); } } }); it("should produce the correct result for each test value with a custom default", function() { const defaultFloat = 6.9; - const results = [defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, 0, 1, 3.141592654, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, -69, -3.33333, 88, -32, -1, 0, 1, 64, -1.1, 0.48, 2.71828]; + const results = [defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, 0, 1, 3.141592654, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, defaultFloat, -69, -3.33333, 88, -32, -1, 0, 1, 64, -1.1, 0.48, 2.71828, 21, -867.5309]; for(let i = 0; i < newTestData.length; i++) { - expect(utilities.parseFloatingPointNumber(newTestData[i], defaultFloat)).to.equal(results[i]); + expect(utilities.parseFloat(newTestData[i], defaultFloat)).to.equal(results[i]); } }); }); describe("parseDate", function() { - const newTestData = testData.concat("June 5, 2012", "June 18, 1987 3:30 PM", "2018-02-19T06:19:33Z", testDate.getTime(), testDate.toString(), testDate.getTime().toString()); + const newTestData = testData.concat("June 5, 2012", "June 18, 1987 3:30 PM", "2018-02-19T06:19:33Z", testDate.getTime(), testDate.toString(), testDate.getTime().toString(), -1); it("should be a function", function() { expect(utilities.parseDate).to.be.an.instanceof(Function); }); it("should produce the correct result for each test value", function() { - const results = [null, null, null, null, null, null, new Date(0), new Date(1), null, null, null, null, null, null, null, null, null, null, null, testDate, null, null, new Date("June 5, 2012"), new Date("June 18, 1987 3:30 PM"), new Date("2018-02-19T06:19:33Z"), testDate, new Date(testDate.toString()), testDate]; + const results = [null, null, null, null, null, null, new Date(0), new Date(1), null, null, null, null, null, null, null, null, null, null, null, testDate, null, null, new Date("June 5, 2012"), new Date("June 18, 1987 3:30 PM"), new Date("2018-02-19T06:19:33Z"), testDate, new Date(testDate.toString()), testDate, null]; for(let i = 0; i < newTestData.length; i++) { if(results[i] === null) { @@ -636,7 +686,7 @@ describe("Utilities", function() { it("should produce the correct result for each test value with a custom default", function() { const defaultDate = new Date("October 21, 2015 4:29 PM"); - const results = [defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, new Date(0), new Date(1), defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, testDate, defaultDate, defaultDate, new Date("June 5, 2012"), new Date("June 18, 1987 3:30 PM"), new Date("2018-02-19T06:19:33Z"), testDate, new Date(testDate.toString()), testDate]; + const results = [defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, new Date(0), new Date(1), defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, defaultDate, testDate, defaultDate, defaultDate, new Date("June 5, 2012"), new Date("June 18, 1987 3:30 PM"), new Date("2018-02-19T06:19:33Z"), testDate, new Date(testDate.toString()), testDate, defaultDate]; for(let i = 0; i < newTestData.length; i++) { expect(utilities.parseDate(newTestData[i], defaultDate)).to.deep.equal(results[i]); @@ -651,7 +701,7 @@ describe("Utilities", function() { expect(utilities.parseTime).to.be.an.instanceof(Function); }); - it("should produce the correct result for each test value and return null for invalid values", function() { + it("should produce the correct result for each test value and throw an error for invalid values", function() { const results = [ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, { regular: { raw: "9:30 AM", hour: 9, minutes: 30, period: "AM", morning: true }, military: { raw: "0930", hour: 9, minutes: 30 } }, @@ -674,53 +724,13 @@ describe("Utilities", function() { for(let i = 0; i < newTestData.length; i++) { if(results[i] === null) { - expect(utilities.parseTime(newTestData[i])).to.equal(null); + expect(function() { utilities.parseTime(newTestData[i], true); }).to.throw(); } else { expect(utilities.parseTime(newTestData[i])).to.deep.equal(results[i]); } } }); - - it("should produce the correct result for each test value and throw an error when specified for invalid values", function() { - const results = [ - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - { regular: { raw: "9:30 AM", hour: 9, minutes: 30, period: "AM", morning: true }, military: { raw: "0930", hour: 9, minutes: 30 } }, - { regular: { raw: "11:59 PM", hour: 11, minutes: 59, period: "PM", morning: false }, military: { raw: "2359", hour: 23, minutes: 59 } }, - { regular: { raw: "12:00 AM", hour: 12, minutes: 0, period: "AM", morning: true }, military: { raw: "0000", hour: 0, minutes: 0 } }, - { regular: { raw: "12:01 AM", hour: 12, minutes: 1, period: "AM", morning: true }, military: { raw: "0001", hour: 0, minutes: 1 } }, - { regular: { raw: "11:59 AM", hour: 11, minutes: 59, period: "AM", morning: true }, military: { raw: "1159", hour: 11, minutes: 59 } }, - { regular: { raw: "12:00 PM", hour: 12, minutes: 0, period: "PM", morning: false }, military: { raw: "1200", hour: 12, minutes: 0 } }, - { regular: { raw: "12:01 PM", hour: 12, minutes: 1, period: "PM", morning: false }, military: { raw: "1201", hour: 12, minutes: 1 } }, - { regular: { raw: "4:32 PM", hour: 4, minutes: 32, period: "PM", morning: false }, military: { raw: "1632", hour: 16, minutes: 32 } }, - { regular: { raw: "11:59 PM", hour: 11, minutes: 59, period: "PM", morning: false }, military: { raw: "2359", hour: 23, minutes: 59 } }, - { regular: { raw: "12:00 AM", hour: 12, minutes: 0, period: "AM", morning: true }, military: { raw: "0000", hour: 0, minutes: 0 } }, - { regular: { raw: "12:01 AM", hour: 12, minutes: 1, period: "AM", morning: true }, military: { raw: "0001", hour: 0, minutes: 1 } }, - { regular: { raw: "11:59 AM", hour: 11, minutes: 59, period: "AM", morning: true }, military: { raw: "1159", hour: 11, minutes: 59 } }, - { regular: { raw: "12:00 PM", hour: 12, minutes: 0, period: "PM", morning: false }, military: { raw: "1200", hour: 12, minutes: 0 } }, - { regular: { raw: "12:01 PM", hour: 12, minutes: 1, period: "PM", morning: false }, military: { raw: "1201", hour: 12, minutes: 1 } }, - { regular: { raw: "12:00 AM", hour: 12, minutes: 0, period: "AM", morning: true }, military: { raw: "0000", hour: 0, minutes: 0 } }, - null, null, null, null, null, null, null, null - ]; - - for(let i = 0; i < newTestData.length; i++) { - let errorThrown = false; - - try { - if(results[i] === null) { - utilities.parseTime(newTestData[i], true); - } - else { - expect(utilities.parseTime(newTestData[i], true)).to.deep.equal(results[i]); - } - } - catch(error) { - errorThrown = true; - } - - expect(errorThrown).to.equal(results[i] === null); - } - }); }); describe("parseEmail", function() { @@ -1246,9 +1256,11 @@ describe("Utilities", function() { it("should correctly format string values", function() { function func() { throw new Error("Do you like your new toy?"); }; - const values = testData.slice(2).concat(new Error("So here's this giant enemy crab."), utilities.createError("new fone who dis", 416), func, /but{1,2}s?/gmi); + const testError = new Error("So here's this giant enemy crab."); + const customTestError = utilities.createError("new fone who dis", 416); + const values = testData.slice(2).concat(testError, customTestError, func, /but{1,2}s?/gmi); const formats = [{ type: "string"}, { type: "StRiNg" }]; - const results = ["false", "true", "false", "true", "0", "1", "3.141592654", "NaN", "Infinity", "-Infinity", "", "test", " trim\t", "{}", "{\"nice\":\"meme\"}", "[]", "[0]", testDate.toString(), emptyFunctionString, "/.+/", "{\"message\":\"So here's this giant enemy crab.\"}", "{\"message\":\"new fone who dis\",\"status\":416}", func.toString(), "/but{1,2}s?/gmi"]; + const results = ["false", "true", "false", "true", "0", "1", "3.141592654", "NaN", "Infinity", "-Infinity", "", "test", " trim\t", "{}", "{\"nice\":\"meme\"}", "[]", "[0]", testDate.toString(), emptyFunctionString, "/.+/", testError.stack, customTestError.stack, func.toString(), "/but{1,2}s?/gmi"]; for(let i = 0; i < values.length; i++) { for(let j = 0; j < formats.length; j++) { @@ -2088,6 +2100,9 @@ describe("Utilities", function() { const objectResults = utilities.clone(objectValues); objectResults.concat(objectResults); + const testError = new Error("So here's this giant enemy crab."); + const customTestError = utilities.createError("new fone who dis", 416); + const typedArrayValues = [ { formats: [ @@ -2149,10 +2164,10 @@ describe("Utilities", function() { { type: "StRiNg" } ], values: [ - testData.slice(2).concat(new Error("So here's this giant enemy crab."), utilities.createError("new fone who dis", 416), func, /but{1,2}s?/gmi) + testData.slice(2).concat(testError, customTestError, func, /but{1,2}s?/gmi) ], results: [ - ["false", "true", "false", "true", "0", "1", "3.141592654", "NaN", "Infinity", "-Infinity", "", "test", " trim\t", "{}", "{\"nice\":\"meme\"}", "[]", "[0]", testDate.toString(), emptyFunctionString, "/.+/", "{\"message\":\"So here's this giant enemy crab.\"}", "{\"message\":\"new fone who dis\",\"status\":416}", func.toString(), "/but{1,2}s?/gmi"] + ["false", "true", "false", "true", "0", "1", "3.141592654", "NaN", "Infinity", "-Infinity", "", "test", " trim\t", "{}", "{\"nice\":\"meme\"}", "[]", "[0]", testDate.toString(), emptyFunctionString, "/.+/", testError.stack, customTestError.stack, func.toString(), "/but{1,2}s?/gmi"] ] }, { @@ -3040,6 +3055,14 @@ describe("Utilities", function() { expect(utilities.trimString(newTestData[i], "empty")).to.equal(results[i]); } }); + + it("should produce the correct result for each test value with an invalid custom default value", function() { + const results = [null, null, null, null, null, null, null, null, null, null, null, null, "", "test", "trim", null, null, null, null, null, null, null, "broden kelly"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimString(newTestData[i], 420)).to.equal(results[i]); + } + }); }); describe("trimNullTerminatedString", function() { @@ -3064,6 +3087,14 @@ describe("Utilities", function() { expect(utilities.trimNullTerminatedString(newTestData[i], "nil")).to.equal(results[i]); } }); + + it("should produce the correct result for each test value with an invalid custom default", function() { + const results = [null, null, null, null, null, null, null, null, null, null, null, null, "", "test", " trim\t", null, null, null, null, null, null, null, " \t broden kelly\t \t", "", "MODMGR.EXE", "", "2009.MAP", "EI.GRP", "1999.GRP"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimNullTerminatedString(newTestData[i], new Error("wat"))).to.equal(results[i]); + } + }); }); describe("trimWhitespace", function() { @@ -3088,6 +3119,38 @@ describe("Utilities", function() { expect(utilities.trimWhitespace(newTestData[i], true)).to.equal(results[i]); } }); + + it("should produce the correct result for each test value with trim new lines set to false and a valid default string value is provided", function() { + const results = ["wat", "wat", "wat", "wat", "wat", "wat", "wat", "wat", "wat", "wat", "wat", "wat", "", "test", "trim", "wat", "wat", "wat", "wat", "wat", "wat", "wat", "white space", "new\r\nlines\n"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimWhitespace(newTestData[i], false, "wat")).to.equal(results[i]); + } + }); + + it("should produce the correct result for each test value with trim new lines set to true and a valid default string value is provided", function() { + const results = ["huh", "huh", "huh", "huh", "huh", "huh", "huh", "huh", "huh", "huh", "huh", "huh", "", "test", "trim", "huh", "huh", "huh", "huh", "huh", "huh", "huh", "white space", "newlines"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimWhitespace(newTestData[i], true, "huh")).to.equal(results[i]); + } + }); + + it("should produce the correct result for each test value with trim new lines set to false and an invalid default value is provided", function() { + const results = [null, null, null, null, null, null, null, null, null, null, null, null, "", "test", "trim", null, null, null, null, null, null, null, "white space", "new\r\nlines\n"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimWhitespace(newTestData[i], false, NaN)).to.equal(results[i]); + } + }); + + it("should produce the correct result for each test value with trim new lines set to true and a valid default value is provided", function() { + const results = [null, null, null, null, null, null, null, null, null, null, null, null, "", "test", "trim", null, null, null, null, null, null, null, "white space", "newlines"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimWhitespace(newTestData[i], true, [])).to.equal(results[i]); + } + }); }); describe("trimTrailingNewlines", function() { @@ -3104,6 +3167,22 @@ describe("Utilities", function() { expect(utilities.trimTrailingNewlines(newTestData[i])).to.equal(results[i]); } }); + + it("should produce the correct result for each test value with a custom default string value", function() { + const results = ["no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "", "test", " trim", "no", "no", "no", "no", "no", "no", "no", "new\r\nlines", "windows", "mac"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimTrailingNewlines(newTestData[i], "no")).to.equal(results[i]); + } + }); + + it("should produce the correct result for each test value with an invalid custom default value", function() { + const results = [null, null, null, null, null, null, null, null, null, null, null, null, "", "test", " trim", null, null, null, null, null, null, null, "new\r\nlines", "windows", "mac"]; + + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.trimTrailingNewlines(newTestData[i], Infinity)).to.equal(results[i]); + } + }); }); describe("replaceNonBreakingSpaces", function() { @@ -3275,14 +3354,16 @@ describe("Utilities", function() { describe("toString", function() { function func() { console.log("All this talk of tea is getting me thirsty, shall I pop the kettle on?"); }; - const newTestData = testData.concat(new Error("There are tales of pots."), utilities.createError("A watched pot never boils.", 69), func, /delicious.*muggachini/gmi); + const testError = new Error("There are tales of pots."); + const customTestError = utilities.createError("A watched pot never boils.", 69); + const newTestData = testData.concat(testError, customTestError, func, /delicious.*muggachini/gmi); it("should be a function", function() { expect(utilities.toString).to.be.an.instanceof(Function); }); it("should produce the correct result for each test value", function() { - const results = ["undefined", "null", "false", "true", "false", "true", "0", "1", "3.141592654", "NaN", "Infinity", "-Infinity", "", "test", " trim\t", "{}", "{\"nice\":\"meme\"}", "[]", "[0]", testDate.toString(), emptyFunctionString, "/.+/", "{\"message\":\"There are tales of pots.\"}", "{\"message\":\"A watched pot never boils.\",\"status\":69}", func.toString(), "/delicious.*muggachini/gmi"]; + const results = ["undefined", "null", "false", "true", "false", "true", "0", "1", "3.141592654", "NaN", "Infinity", "-Infinity", "", "test", " trim\t", "{}", "{\"nice\":\"meme\"}", "[]", "[0]", testDate.toString(), emptyFunctionString, "/.+/", testError.stack, customTestError.stack, func.toString(), "/delicious.*muggachini/gmi"]; for(let i = 0; i < newTestData.length; i++) { expect(utilities.toString(newTestData[i])).to.equal(results[i]); @@ -4205,84 +4286,139 @@ describe("Utilities", function() { describe("joinPaths", function() { const newTestData = [ { - left: null, - right: null, - result: "" + paths: [], + result: "", + customResult: "" }, { - left: null, - right: "readme.txt", - result: "readme.txt" + paths: [null], + result: "", + customResult: "" }, { - left: "http://www.nitro404.com", - right: null, - result: "http://www.nitro404.com" + paths: [""], + result: "", + customResult: "" }, { - left: "https://api.test.com", - right: "status", - result: "https://api.test.com/status" + paths: ["/"], + result: "/", + customResult: "\\" }, { - left: "https://www.youtube.com/", - right: "watch?v=TBsdWW7MOew", - result: "https://www.youtube.com/watch?v=TBsdWW7MOew" + paths: ["."], + result: ".", + customResult: "." }, { - left: "https://www.reddit.com", - right: "/r/circlejerk", - result: "https://www.reddit.com/r/circlejerk" + paths: [null, null], + result: "", + customResult: "" }, { - left: "https://steamcommunity.com/id/", - right: "/gabelogannewell", - result: "https://steamcommunity.com/id/gabelogannewell" + paths: [null, "readme.txt"], + result: "readme.txt", + customResult: "readme.txt" }, { - left: "https://www.youtube.com\\", - right: "watch?v=FuraQCCsKgE", - result: "https://www.youtube.com/watch?v=FuraQCCsKgE" + paths: ["/", "/"], + result: "/", + customResult: "\\" }, { - left: "https://www.youtube.com", - right: "\\watch?v=eOrMzdXEfhA", - result: "https://www.youtube.com/watch?v=eOrMzdXEfhA" + paths: [".", "/"], + result: ".", + customResult: "." }, { - left: "https://www.youtube.com\\", - right: "\\watch?v=6HFw8TNexyU", - result: "https://www.youtube.com/watch?v=6HFw8TNexyU" + paths: ["./", "/test"], + result: "./test", + customResult: ".\\test" }, { - left: "https://www.youtube.com//", - right: "watch?v=NgWn7zbgxZ4", - result: "https://www.youtube.com/watch?v=NgWn7zbgxZ4" + paths: ["/var/", "/tmp"], + result: "/var/tmp", + customResult: "\\var\\tmp" }, { - left: "https://www.youtube.com", - right: "//watch?v=0tdyU_gW6WE", - result: "https://www.youtube.com/watch?v=0tdyU_gW6WE" + paths: ["/dev//", "\\/null"], + result: "/dev/null", + customResult: "\\dev\\null" }, { - left: "https://www.youtube.com//", - right: "//watch?v=ygI-2F8ApUM", - result: "https://www.youtube.com/watch?v=ygI-2F8ApUM" + paths: ["http://www.nitro404.com", null], + result: "http://www.nitro404.com", + customResult: "http:\\\\www.nitro404.com" }, { - left: "https://www.youtube.com\\/", - right: "watch?v=nxg4C365LbQ", - result: "https://www.youtube.com/watch?v=nxg4C365LbQ" + paths: ["https://api.test.com", "status"], + result: "https://api.test.com/status", + customResult: "https:\\\\api.test.com\\status" }, { - left: "https://www.youtube.com", - right: "\\/watch?v=1wl5BbUg05M", - result: "https://www.youtube.com/watch?v=1wl5BbUg05M" + paths: ["https://www.youtube.com/", "watch?v=TBsdWW7MOew"], + result: "https://www.youtube.com/watch?v=TBsdWW7MOew", + customResult: "https:\\\\www.youtube.com\\watch?v=TBsdWW7MOew" }, { - left: "https://www.youtube.com\\/", - right: "\\/watch?v=JjJ90jhS84A", - result: "https://www.youtube.com/watch?v=JjJ90jhS84A" + paths: ["https://www.reddit.com", "/r/circlejerk"], + result: "https://www.reddit.com/r/circlejerk", + customResult: "https:\\\\www.reddit.com\\r\\circlejerk" + }, + { + paths: ["https://steamcommunity.com/id/", "/gabelogannewell"], + result: "https://steamcommunity.com/id/gabelogannewell", + customResult: "https:\\\\steamcommunity.com\\id\\gabelogannewell" + }, + { + paths: ["https://www.youtube.com\\", "watch?v=FuraQCCsKgE"], + result: "https://www.youtube.com/watch?v=FuraQCCsKgE", + customResult: "https:\\\\www.youtube.com\\watch?v=FuraQCCsKgE" + }, + { + paths: ["https://www.youtube.com", "\\watch?v=eOrMzdXEfhA"], + result: "https://www.youtube.com/watch?v=eOrMzdXEfhA", + customResult: "https:\\\\www.youtube.com\\watch?v=eOrMzdXEfhA" + }, + { + paths: ["https://www.youtube.com\\", "\\watch?v=6HFw8TNexyU"], + result: "https://www.youtube.com/watch?v=6HFw8TNexyU", + customResult: "https:\\\\www.youtube.com\\watch?v=6HFw8TNexyU" + }, + { + paths: ["https://www.youtube.com//", "watch?v=NgWn7zbgxZ4"], + result: "https://www.youtube.com/watch?v=NgWn7zbgxZ4", + customResult: "https:\\\\www.youtube.com\\watch?v=NgWn7zbgxZ4" + }, + { + paths: ["https://www.youtube.com", "//watch?v=0tdyU_gW6WE"], + result: "https://www.youtube.com/watch?v=0tdyU_gW6WE", + customResult: "https:\\\\www.youtube.com\\watch?v=0tdyU_gW6WE" + }, + { + paths: ["https://www.youtube.com//", "//watch?v=ygI-2F8ApUM"], + result: "https://www.youtube.com/watch?v=ygI-2F8ApUM", + customResult: "https:\\\\www.youtube.com\\watch?v=ygI-2F8ApUM" + }, + { + paths: ["https://www.youtube.com\\/", "watch?v=nxg4C365LbQ"], + result: "https://www.youtube.com/watch?v=nxg4C365LbQ", + customResult: "https:\\\\www.youtube.com\\watch?v=nxg4C365LbQ" + }, + { + paths: ["https://www.youtube.com", "\\/watch?v=1wl5BbUg05M"], + result: "https://www.youtube.com/watch?v=1wl5BbUg05M", + customResult: "https:\\\\www.youtube.com\\watch?v=1wl5BbUg05M" + }, + { + paths: ["https://www.youtube.com\\/", "\\/watch?v=JjJ90jhS84A"], + result: "https://www.youtube.com/watch?v=JjJ90jhS84A", + customResult: "https:\\\\www.youtube.com\\watch?v=JjJ90jhS84A" + }, + { + paths: ["door", "stuck", "cant", "make", "it"], + result: "door/stuck/cant/make/it", + customResult: "door\\stuck\\cant\\make\\it" } ]; @@ -4292,7 +4428,24 @@ describe("Utilities", function() { it("should produce the correct result for each test value", function() { for(let i = 0; i < newTestData.length; i++) { - expect(utilities.joinPaths(newTestData[i].left, newTestData[i].right)).to.equal(newTestData[i].result); + expect(utilities.joinPaths(newTestData[i].paths)).to.equal(newTestData[i].result); + expect(utilities.joinPaths(...newTestData[i].paths)).to.equal(newTestData[i].result); + } + }); + + it("should produce the correct result for each test value with a custom separator character", function() { + for(let i = 0; i < newTestData.length; i++) { + expect(utilities.joinPaths(newTestData[i].paths, { separator: "/" })).to.equal(newTestData[i].result); + expect(utilities.joinPaths(newTestData[i].paths.concat({ separator: "/" }))).to.equal(newTestData[i].result); + expect(utilities.joinPaths(...newTestData[i].paths, { separator: "/" })).to.equal(newTestData[i].result); + + expect(utilities.joinPaths(newTestData[i].paths, { separator: "\\" })).to.equal(newTestData[i].customResult); + expect(utilities.joinPaths(newTestData[i].paths.concat({ separator: "\\" }))).to.equal(newTestData[i].customResult); + expect(utilities.joinPaths(...newTestData[i].paths, { separator: "\\" })).to.equal(newTestData[i].customResult); + + expect(utilities.joinPaths(newTestData[i].paths, { separator: "wat" })).to.equal(newTestData[i].result); + expect(utilities.joinPaths(newTestData[i].paths.concat({ separator: "is" }))).to.equal(newTestData[i].result); + expect(utilities.joinPaths(...newTestData[i].paths, { separator: "dis" })).to.equal(newTestData[i].result); } }); }); @@ -4781,13 +4934,13 @@ describe("Utilities", function() { it("should produce the correct result for each test value with no prefix or suffix", function() { const results = [ ["420"], - ["7"], + ["007"], ["2", "2_0"], ["3", "3_1", "3_1_0", "3_1_0_0"], - ["4", "4_2", "4_2_0", "4_2_0_0"], + ["04", "04_2", "04_2_00", "04_2_00_0"], ["can\'t", "can\'t_make", "can\'t_make_it"], null, - ["0","0_6", "0_6_4", "0_6_4_800", "0_6_4_800_0"] + ["00","00_6", "00_6_04", "00_6_04_00800", "00_6_04_00800_0"] ]; for(let i = 0; i < additionalTestData.length; i++) { @@ -4798,13 +4951,13 @@ describe("Utilities", function() { it("should produce the correct result for each test value and prefix", function() { const results = [ [["saint420"], ["vapor420"]], - [["saint7"], ["vapor7"]], + [["saint007"], ["vapor007"]], [["saint2", "saint2_0"], ["vapor2", "vapor2_0"]], [["saint3", "saint3_1", "saint3_1_0", "saint3_1_0_0"], ["vapor3", "vapor3_1", "vapor3_1_0", "vapor3_1_0_0"]], - [["saint4", "saint4_2", "saint4_2_0", "saint4_2_0_0"], ["vapor4", "vapor4_2", "vapor4_2_0", "vapor4_2_0_0"]], + [["saint04", "saint04_2", "saint04_2_00", "saint04_2_00_0"], ["vapor04", "vapor04_2", "vapor04_2_00", "vapor04_2_00_0"]], [["saintcan\'t", "saintcan\'t_make", "saintcan\'t_make_it"], ["vaporcan\'t", "vaporcan\'t_make", "vaporcan\'t_make_it"]], [null, null], - [["saint0", "saint0_6", "saint0_6_4", "saint0_6_4_800", "saint0_6_4_800_0"], ["vapor0", "vapor0_6", "vapor0_6_4", "vapor0_6_4_800", "vapor0_6_4_800_0"]] + [["saint00", "saint00_6", "saint00_6_04", "saint00_6_04_00800", "saint00_6_04_00800_0"], ["vapor00", "vapor00_6", "vapor00_6_04", "vapor00_6_04_00800", "vapor00_6_04_00800_0"]] ]; for(let i = 0; i < additionalTestData.length; i++) { @@ -4817,13 +4970,13 @@ describe("Utilities", function() { it("should produce the correct result for each test value and suffix", function() { const results = [ [["420pepsi"], ["420wave"]], - [["7pepsi"], ["7wave"]], + [["007pepsi"], ["007wave"]], [["2pepsi", "2_0pepsi"], ["2wave", "2_0wave"]], [["3pepsi", "3_1pepsi", "3_1_0pepsi", "3_1_0_0pepsi"], ["3wave", "3_1wave", "3_1_0wave", "3_1_0_0wave"]], - [["4pepsi", "4_2pepsi", "4_2_0pepsi", "4_2_0_0pepsi"], ["4wave", "4_2wave", "4_2_0wave", "4_2_0_0wave"]], + [["04pepsi", "04_2pepsi", "04_2_00pepsi", "04_2_00_0pepsi"], ["04wave", "04_2wave", "04_2_00wave", "04_2_00_0wave"]], [["can\'tpepsi", "can\'t_makepepsi", "can\'t_make_itpepsi"], ["can\'twave", "can\'t_makewave", "can\'t_make_itwave"]], [null, null], - [["0pepsi", "0_6pepsi", "0_6_4pepsi", "0_6_4_800pepsi", "0_6_4_800_0pepsi"], ["0wave", "0_6wave", "0_6_4wave", "0_6_4_800wave", "0_6_4_800_0wave"]] + [["00pepsi", "00_6pepsi", "00_6_04pepsi", "00_6_04_00800pepsi", "00_6_04_00800_0pepsi"], ["00wave", "00_6wave", "00_6_04wave", "00_6_04_00800wave", "00_6_04_00800_0wave"]] ]; for(let i = 0; i < additionalTestData.length; i++) { @@ -4840,8 +4993,8 @@ describe("Utilities", function() { [["vapor420pepsi"], ["vapor420wave"]] ], [ - [["saint7pepsi"], ["saint7wave"]], - [["vapor7pepsi"], ["vapor7wave"]] + [["saint007pepsi"], ["saint007wave"]], + [["vapor007pepsi"], ["vapor007wave"]] ], [ [["saint2pepsi", "saint2_0pepsi"], ["saint2wave", "saint2_0wave"]], @@ -4852,8 +5005,8 @@ describe("Utilities", function() { [["vapor3pepsi", "vapor3_1pepsi", "vapor3_1_0pepsi", "vapor3_1_0_0pepsi"], ["vapor3wave", "vapor3_1wave", "vapor3_1_0wave", "vapor3_1_0_0wave"]] ], [ - [["saint4pepsi", "saint4_2pepsi", "saint4_2_0pepsi", "saint4_2_0_0pepsi"], ["saint4wave", "saint4_2wave", "saint4_2_0wave", "saint4_2_0_0wave"]], - [["vapor4pepsi", "vapor4_2pepsi", "vapor4_2_0pepsi", "vapor4_2_0_0pepsi"], ["vapor4wave", "vapor4_2wave", "vapor4_2_0wave", "vapor4_2_0_0wave"]] + [["saint04pepsi", "saint04_2pepsi", "saint04_2_00pepsi", "saint04_2_00_0pepsi"], ["saint04wave", "saint04_2wave", "saint04_2_00wave", "saint04_2_00_0wave"]], + [["vapor04pepsi", "vapor04_2pepsi", "vapor04_2_00pepsi", "vapor04_2_00_0pepsi"], ["vapor04wave", "vapor04_2wave", "vapor04_2_00wave", "vapor04_2_00_0wave"]] ], [ [["saintcan\'tpepsi", "saintcan\'t_makepepsi", "saintcan\'t_make_itpepsi"], ["saintcan\'twave", "saintcan\'t_makewave", "saintcan\'t_make_itwave"]], @@ -4864,8 +5017,8 @@ describe("Utilities", function() { [null, null] ], [ - [["saint0pepsi", "saint0_6pepsi", "saint0_6_4pepsi", "saint0_6_4_800pepsi", "saint0_6_4_800_0pepsi"], ["saint0wave", "saint0_6wave", "saint0_6_4wave", "saint0_6_4_800wave", "saint0_6_4_800_0wave"]], - [["vapor0pepsi", "vapor0_6pepsi", "vapor0_6_4pepsi", "vapor0_6_4_800pepsi", "vapor0_6_4_800_0pepsi"], ["vapor0wave", "vapor0_6wave", "vapor0_6_4wave", "vapor0_6_4_800wave", "vapor0_6_4_800_0wave"]] + [["saint00pepsi", "saint00_6pepsi", "saint00_6_04pepsi", "saint00_6_04_00800pepsi", "saint00_6_04_00800_0pepsi"], ["saint00wave", "saint00_6wave", "saint00_6_04wave", "saint00_6_04_00800wave", "saint00_6_04_00800_0wave"]], + [["vapor00pepsi", "vapor00_6pepsi", "vapor00_6_04pepsi", "vapor00_6_04_00800pepsi", "vapor00_6_04_00800_0pepsi"], ["vapor00wave", "vapor00_6wave", "vapor00_6_04wave", "vapor00_6_04_00800wave", "vapor00_6_04_00800_0wave"]] ] ]; @@ -4888,7 +5041,7 @@ describe("Utilities", function() { it("should produce the correct result for each test value", function() { const results = [ - null, null, null, null, null, null, ["0"], ["1"], ["3", "141592654"], null, null, null, null, ["test"], ["trim"], null, null, null, null, null, null, null, ["420"], ["7"], ["2", "0"], ["3", "1", "0", "0"], ["4", "2", "0", "0"], ["can't", "make", "it"], null, ["0", "6", "4", "800", "0"] + null, null, null, null, null, null, ["0"], ["1"], ["3", "141592654"], null, null, null, null, ["test"], ["trim"], null, null, null, null, null, null, null, ["420"], ["007"], ["2", "0"], ["3", "1", "0", "0"], ["04", "2", "00", "0"], ["can't", "make", "it"], null, ["00", "6", "04", "00800", "0"] ]; for(let i = 0; i < newTestData.length; i++) { @@ -4902,7 +5055,7 @@ describe("Utilities", function() { it("should produce the correct result for each test value with trim trailing zeroes enabled", function() { const results = [ - null, null, null, null, null, null, ["0"], ["1"], ["3", "141592654"], null, null, null, null, ["test"], ["trim"], null, null, null, null, null, null, null, ["420"], ["7"], ["2"], ["3", "1"], ["4", "2"], ["can't", "make", "it"], null, ["0", "6", "4", "800"] + null, null, null, null, null, null, ["0"], ["1"], ["3", "141592654"], null, null, null, null, ["test"], ["trim"], null, null, null, null, null, null, null, ["420"], ["007"], ["2"], ["3", "1"], ["04", "2", "00"], ["can't", "make", "it"], null, ["00", "6", "04", "00800"] ]; for(let i = 0; i < newTestData.length; i++) { @@ -4973,25 +5126,25 @@ describe("Utilities", function() { const additionalResults = { caseInsensitive: [ - [ 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [ 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 0, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 1, 0, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 0, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 0, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 0, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 1, 1, 0, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 1, 1, 1, 0, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 0, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, null, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1 ], [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, 0, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, 0, 0, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, 0, 0, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1 ], @@ -5000,25 +5153,25 @@ describe("Utilities", function() { [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, null, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 ], ], caseSensitive: [ - [ 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [ 0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 0, -1, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 1, 0, -1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 0, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 0, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 0, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 0, 0, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 1, 1, 0, -1, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 1, 1, 1, 0, -1, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 0, -1, -1, null, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -1, null, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, null, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1 ], [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1 ], - [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1 ], + [ 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, null, 0, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1 ], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, null, -1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, 0, 1, -1, 1, 1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, -1, 0, -1, -1, -1, -1 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, null, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, -1 ], @@ -5032,116 +5185,66 @@ describe("Utilities", function() { expect(utilities.compareVersions).to.be.an.instanceof(Function); }); - it("should produce the correct result for each test value pair with case sensitivity disabled", function() { + it("should produce the correct result for each test value pair or throw an error for any invalid values with case sensitivity disabled", function() { for(let i = 0; i < newTestData.length; i++) { for(let j = 0; j < newTestData.length; j++) { - expect(utilities.compareVersions(newTestData[i], newTestData[j])).to.equal(newResults.caseInsensitive[i][j]); - expect(utilities.compareVersions(newTestData[i], newTestData[j], false)).to.equal(newResults.caseInsensitive[i][j]); - expect(utilities.compareVersions(newTestData[i], newTestData[j], false, false)).to.equal(newResults.caseInsensitive[i][j]); - } - } - }); + const result = newResults.caseInsensitive[i][j]; - it("should produce the correct result for each test value pair with case sensitivity enabled", function() { - for(let i = 0; i < newTestData.length; i++) { - for(let j = 0; j < newTestData.length; j++) { - expect(utilities.compareVersions(newTestData[i], newTestData[j], true)).to.equal(newResults.caseSensitive[i][j]); - expect(utilities.compareVersions(newTestData[i], newTestData[j], true, false)).to.equal(newResults.caseSensitive[i][j]); - } - } - }); - - it("should correctly throw errors when enabled for each test value pair with case sensitivity disabled", function() { - let errorThrown = null; - - for(let i = 0; i < newTestData.length; i++) { - for(let j = 0; j < newTestData.length; j++) { - errorThrown = false; - - try { - utilities.compareVersions(newTestData[i], newTestData[j], false, true); + if(result === null) { + expect(function() { utilities.compareVersions(newTestData[i], newTestData[j]); }).to.throw(); + expect(function() { utilities.compareVersions(newTestData[i], newTestData[j], false); }).to.throw(); } - catch(error) { - errorThrown = true; + else { + expect(utilities.compareVersions(newTestData[i], newTestData[j])).to.equal(result); + expect(utilities.compareVersions(newTestData[i], newTestData[j], false)).to.equal(result); } - - expect(errorThrown).to.equal(newResults.caseInsensitive[i][j] === null); } } }); - it("should correctly throw errors when enabled for each test value pair with case sensitivity enabled", function() { - let errorThrown = null; - + it("should produce the correct result for each test value pair or throw an error for any invalid values with case sensitivity enabled", function() { for(let i = 0; i < newTestData.length; i++) { for(let j = 0; j < newTestData.length; j++) { - errorThrown = false; + const result = newResults.caseSensitive[i][j]; - try { - utilities.compareVersions(newTestData[i], newTestData[j], true, true); + if(result === null) { + expect(function() { utilities.compareVersions(newTestData[i], newTestData[j], true); }).to.throw(); } - catch(error) { - errorThrown = true; + else { + expect(utilities.compareVersions(newTestData[i], newTestData[j], true)).to.equal(result); } - - expect(errorThrown).to.equal(newResults.caseSensitive[i][j] === null); - } - } - }); - - it("should produce the correct result for each additional test value pair with case sensitivity disabled", function() { - for(let i = 0; i < additionalTestData.length; i++) { - for(let j = 0; j < additionalTestData.length; j++) { - expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j])).to.equal(additionalResults.caseInsensitive[i][j]); - expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j], false)).to.equal(additionalResults.caseInsensitive[i][j]); - expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j], false, false)).to.equal(additionalResults.caseInsensitive[i][j]); - } - } - }); - - it("should produce the correct result for each additional test value pair with case sensitivity enabled", function() { - for(let i = 0; i < additionalTestData.length; i++) { - for(let j = 0; j < additionalTestData.length; j++) { - expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j], true)).to.equal(additionalResults.caseSensitive[i][j]); - expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j], true, false)).to.equal(additionalResults.caseSensitive[i][j]); } } }); - it("should correctly throw errors when enabled for each additional test value pair with case sensitivity disabled", function() { - let errorThrown = null; - + it("should produce the correct result for each additional test value pair or throw an error for any invalid values with case sensitivity disabled", function() { for(let i = 0; i < additionalTestData.length; i++) { for(let j = 0; j < additionalTestData.length; j++) { - errorThrown = false; + const result = additionalResults.caseInsensitive[i][j]; - try { - utilities.compareVersions(additionalTestData[i], additionalTestData[j], false, true); + if(result === null) { + expect(function() { utilities.compareVersions(additionalTestData[i], additionalTestData[j]); }).to.throw(); + expect(function() { utilities.compareVersions(additionalTestData[i], additionalTestData[j], false); }).to.throw(); } - catch(error) { - errorThrown = true; + else { + expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j])).to.equal(result); + expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j], false)).to.equal(result); } - - expect(errorThrown).to.equal(additionalResults.caseInsensitive[i][j] === null); } } }); - it("should correctly throw errors when enabled for each additional test value pair with case sensitivity enabled", function() { - let errorThrown = null; - + it("should produce the correct result for each additional test value pair or throw an error for any invalid values with case sensitivity enabled", function() { for(let i = 0; i < additionalTestData.length; i++) { for(let j = 0; j < additionalTestData.length; j++) { - errorThrown = false; + const result = additionalResults.caseSensitive[i][j]; - try { - utilities.compareVersions(additionalTestData[i], additionalTestData[j], true, true); + if(result === null) { + expect(function() { utilities.compareVersions(additionalTestData[i], additionalTestData[j], true); }).to.throw(); } - catch(error) { - errorThrown = true; + else { + expect(utilities.compareVersions(additionalTestData[i], additionalTestData[j], true)).to.equal(result); } - - expect(errorThrown).to.equal(additionalResults.caseSensitive[i][j] === null); } } });