diff --git a/7-quality-assurance/1-metric-imp-converter/.config/configstore/update-notifier-npm.json b/7-quality-assurance/1-metric-imp-converter/.config/configstore/update-notifier-npm.json new file mode 100644 index 0000000..359c17b --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/.config/configstore/update-notifier-npm.json @@ -0,0 +1,4 @@ +{ + "optOut": false, + "lastUpdateCheck": 1660315504033 +} \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/.gitattributes b/7-quality-assurance/1-metric-imp-converter/.gitattributes new file mode 100644 index 0000000..eb5e65d --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/.gitattributes @@ -0,0 +1,2 @@ +# Tell Linguist to exclude HTML files to help Replit language detection. +*.html linguist-vendored \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/.gitignore b/7-quality-assurance/1-metric-imp-converter/.gitignore new file mode 100644 index 0000000..6ed48a9 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/.gitignore @@ -0,0 +1,2 @@ +.env +node_modules diff --git a/7-quality-assurance/1-metric-imp-converter/.prettierignore b/7-quality-assurance/1-metric-imp-converter/.prettierignore new file mode 100644 index 0000000..9736424 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/.prettierignore @@ -0,0 +1 @@ +.replit \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/.replit b/7-quality-assurance/1-metric-imp-converter/.replit new file mode 100644 index 0000000..c57f33a --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/.replit @@ -0,0 +1,59 @@ +run = "npm start" +entrypoint = "server.js" + +[packager] +language = "nodejs" + + [packager.features] + packageSearch = true + guessImports = true + enabledForHosting = false + +[env] +XDG_CONFIG_HOME = "/home/runner/.config" +PATH = "/home/runner/$REPL_SLUG/.config/npm/node_global/bin:/home/runner/$REPL_SLUG/node_modules/.bin" +npm_config_prefix = "/home/runner/$REPL_SLUG/.config/npm/node_global" + +[nix] +channel = "stable-22_05" + +[debugger] +support = true + +[debugger.interactive] +transport = "localhost:0" +startCommand = ["dap-node"] + +[debugger.interactive.initializeMessage] +command = "initialize" +type = "request" + +[debugger.interactive.initializeMessage.arguments] +clientID = "replit" +clientName = "replit.com" +columnsStartAt1 = true +linesStartAt1 = true +locale = "en-us" +pathFormat = "path" +supportsInvalidatedEvent = true +supportsProgressReporting = true +supportsRunInTerminalRequest = true +supportsVariablePaging = true +supportsVariableType = true + +[debugger.interactive.launchMessage] +command = "launch" +type = "request" + +[debugger.interactive.launchMessage.arguments] +console = "externalTerminal" +cwd = "." +pauseForSourceMap = false +program = "./index.js" +request = "launch" +sourceMaps = true +stopOnEntry = false +type = "pwa-node" + +[unitTest] +language = "nodejs" diff --git a/7-quality-assurance/1-metric-imp-converter/.upm/store.json b/7-quality-assurance/1-metric-imp-converter/.upm/store.json new file mode 100644 index 0000000..bffc430 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/.upm/store.json @@ -0,0 +1 @@ +{"version":2,"languages":{"nodejs-npm":{"specfileHash":"b7193edd675f0fb97b8a16efc52d4e3c","lockfileHash":"db9ba5b054f4c040b4dc349779638bf2","guessedImports":["mocha","chai","cors","express","body-parser","dotenv"],"guessedImportsHash":"ebd5497271a4dced5969e250381705e0"}}} diff --git a/7-quality-assurance/1-metric-imp-converter/README.md b/7-quality-assurance/1-metric-imp-converter/README.md new file mode 100644 index 0000000..60d5bf5 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/README.md @@ -0,0 +1,3 @@ +# Metric-Imperial Converter + +This is the boilerplate for the Metric-Imperial Converter project. Instructions for building your project can be found at https://www.freecodecamp.org/learn/quality-assurance/quality-assurance-projects/metric-imperial-converter diff --git a/7-quality-assurance/1-metric-imp-converter/assertion-analyser.js b/7-quality-assurance/1-metric-imp-converter/assertion-analyser.js new file mode 100644 index 0000000..b007281 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/assertion-analyser.js @@ -0,0 +1,139 @@ +/* +* +* +* +* +* +* +* +* +* +* +* +* DO NOT EDIT THIS FILE +* For FCC testing purposes! +* +* +* +* +* +* +* +* +* +* +* +*/ + +function objParser(str, init) { + // finds objects, arrays, strings, and function arguments + // between parens, because they may contain ',' + let openSym = ['[', '{', '"', "'", '(']; + let closeSym = [']', '}', '"', "'", ')']; + let type; + let i; + for(i = (init || 0); i < str.length; i++ ) { + type = openSym.indexOf(str[i]); + if( type !== -1) break; + } + if (type === -1) return null; + let open = openSym[type]; + let close = closeSym[type]; + let count = 1; + let k; + for(k = i+1; k < str.length; k++) { + if(open === '"' || open === "'") { + if(str[k] === close) count--; + if(str[k] === '\\') k++; + } else { + if(str[k] === open) count++; + if(str[k] === close) count--; + } + if(count === 0) break; + } + if(count !== 0) return null; + let obj = str.slice(i, k+1); + return { + start : i, + end: k, + obj: obj + }; +} + +function replacer(str) { + // replace objects with a symbol ( __#n) + let obj; + let cnt = 0; + let data = []; + while(obj = objParser(str)) { + data[cnt] = obj.obj; + str = str.substring(0, obj.start) + '__#' + cnt++ + str.substring(obj.end+1) + } + return { + str : str, + dictionary : data + } +} + +function splitter(str) { + // split on commas, then restore the objects + let strObj = replacer(str); + let args = strObj.str.split(','); + args = args.map(function(a){ + let m = a.match(/__#(\d+)/); + while (m) { + a = a.replace(/__#(\d+)/, strObj.dictionary[m[1]]); + m = a.match(/__#(\d+)/); + } + return a.trim(); + }) + return args; +} + +function assertionAnalyser(body) { + + // already filtered in the test runner + // // remove comments + // body = body.replace(/\/\/.*\n|\/\*.*\*\//g, ''); + // // get test function body + // body = body.match(/\{\s*([\s\S]*)\}\s*$/)[1]; + + if(!body) return "invalid assertion"; + // replace assertions bodies, so that they cannot + // contain the word 'assertion' + + let cleanedBody = body.match(/(?:browser\s*\.\s*)?assert\s*\.\s*\w*\([\s\S]*\)/) + if(cleanedBody && Array.isArray(cleanedBody)) { + body = cleanedBody[0]; + } else { + // No assertions present + return []; + } + let s = replacer(body); + // split on 'assertion' + let splittedAssertions = s.str.split('assert'); + let assertions = splittedAssertions.slice(1); + // match the METHODS + + let assertionBodies = []; + let methods = assertions.map(function(a, i){ + let m = a.match(/^\s*\.\s*(\w+)__#(\d+)/); + assertionBodies.push(parseInt(m[2])); + let pre = splittedAssertions[i].match(/browser\s*\.\s*/) ? 'browser.' : ''; + return pre + m[1]; + }); + if(methods.some(function(m){ return !m })) return "invalid assertion"; + // remove parens from the assertions bodies + let bodies = assertionBodies.map(function(b){ + return s.dictionary[b].slice(1,-1).trim(); + }); + assertions = methods.map(function(m, i) { + return { + method: m, + args: splitter(bodies[i]) //replace objects, split on ',' ,then restore objects + } + }) + return assertions; +} + +module.exports = assertionAnalyser; diff --git a/7-quality-assurance/1-metric-imp-converter/controllers/convertHandler.js b/7-quality-assurance/1-metric-imp-converter/controllers/convertHandler.js new file mode 100644 index 0000000..4b03efb --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/controllers/convertHandler.js @@ -0,0 +1,91 @@ +function ConvertHandler() { + + this.getNum = function(input) { + let result = []; + if (/^(km|mi|gal|L|lbs|kg)$/.test(input)){return 1} + const tempResult = input.match(/(?!.*\/.*\/)(^\d+)([.]\d+)?(\/\d+([.]\d)?)?/) + if (!tempResult){return 'invalid number'} + result = tempResult[0] + if (result.includes('/')) { + let temp = result.split('/') + + if (temp.length !== 2) + return 'invalid number' + + result = parseFloat(temp[0]) / parseFloat(temp[1]) + } + return parseFloat(result); + }; + + this.getUnit = function(input) { + let result; + result = input.match(/(km|mi|gal|L|lbs|kg)$/i) + if (!result) {return 'invalid unit'} + if (result[0].toLowerCase() === 'l'){return 'L'} + + return result[0].toLowerCase(); + }; + + this.getReturnUnit = function(initUnit) { + switch(initUnit){ + case 'gal': + return 'L' + case 'L': + return 'gal' + case 'mi': + return 'km' + case 'km': + return 'mi' + case 'lbs': + return 'kg' + case 'kg': + return 'lbs' + } + return false; + }; + + this.spellOutUnit = function(unit) { + switch(unit){ + case 'gal': + return 'gallons' + case 'L': + return 'liters' + case 'mi': + return 'miles' + case 'km': + return 'kilometers' + case 'lbs': + return 'pounds' + case 'kg': + return 'kilograms' + } + return false; + }; + + this.convert = function(initNum, initUnit) { + const galToL = 3.78541; + const lbsToKg = 0.453592; + const miToKm = 1.60934; + switch (initUnit) { + case 'gal': + return (galToL * initNum) + case 'lbs': + return lbsToKg * initNum + case 'mi': + return miToKm * initNum + case 'L': + return initNum / galToL + case 'kg': + return initNum / lbsToKg + case 'km': + return initNum / miToKm + } + }; + + this.getString = function(initNum, initUnit, returnNum, returnUnit) { + return (initNum + ' ' + this.spellOutUnit(initUnit) + ' converts to ' + Number(returnNum).toFixed(5) + ' ' + this.spellOutUnit(returnUnit)) + }; + +} + +module.exports = ConvertHandler; diff --git a/7-quality-assurance/1-metric-imp-converter/package-lock.json b/7-quality-assurance/1-metric-imp-converter/package-lock.json new file mode 100644 index 0000000..785450e --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/package-lock.json @@ -0,0 +1,3123 @@ +{ + "name": "fcc-imperial-metric-converter-boilerplate", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "fcc-imperial-metric-converter-boilerplate", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "body-parser": "^1.19.0", + "chai": "^4.2.0", + "chai-http": "^4.3.0", + "cors": "^2.8.5", + "dotenv": "^8.2.0", + "express": "^4.17.1", + "mocha": "^8.1.3" + } + }, + "node_modules/@types/chai": { + "version": "4.2.12", + "license": "MIT" + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/@types/cookiejar": { + "version": "2.1.1", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "14.11.2", + "license": "MIT" + }, + "node_modules/@types/superagent": { + "version": "3.8.7", + "license": "MIT", + "dependencies": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "4.2.1", + "license": "MIT", + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.1", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/array.prototype.map": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.19.0", + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "license": "ISC" + }, + "node_modules/bytes": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-http": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "@types/chai": "4", + "@types/superagent": "^3.8.3", + "cookiejar": "^2.1.1", + "is-ip": "^2.0.0", + "methods": "^1.1.2", + "qs": "^6.5.1", + "superagent": "^3.7.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.4.2", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/cookiejar": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "license": "MIT" + }, + "node_modules/diff": { + "version": "4.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "8.2.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-abstract": { + "version": "1.17.6", + "license": "MIT", + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/es-get-iterator": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-abstract": "^1.17.4", + "has-symbols": "^1.0.1", + "is-arguments": "^1.0.4", + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.1", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "4.1.0", + "license": "BSD-3-Clause", + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formidable": { + "version": "1.2.2", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.1.3", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "license": "ISC" + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "2.0.4", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-ip": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "ip-regex": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-map": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/iterate-iterator": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/iterate-value": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-yaml": { + "version": "3.14.0", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/methods": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "license": "MIT", + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha": { + "version": "8.1.3", + "license": "MIT", + "dependencies": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.2", + "debug": "4.1.1", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "object.assign": "4.1.0", + "promise.allsettled": "1.0.2", + "serialize-javascript": "4.0.0", + "strip-json-comments": "3.0.1", + "supports-color": "7.1.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.0", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.1" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.1.1", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.8.0", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.2.2", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/promise.allsettled": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "array.prototype.map": "^1.0.1", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "iterate-value": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "license": "MIT", + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.4.0", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/send": { + "version": "0.17.1", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "license": "BSD-3-Clause" + }, + "node_modules/statuses": { + "version": "1.5.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/superagent": { + "version": "3.8.3", + "license": "MIT", + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "3.2.6", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/superagent/node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/wide-align": { + "version": "1.1.3", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/workerpool": { + "version": "6.0.0", + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/y18n": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "13.3.2", + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-unparser": { + "version": "1.6.1", + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "decamelize": "^1.2.0", + "flat": "^4.1.0", + "is-plain-obj": "^1.1.0", + "yargs": "^14.2.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/ansi-regex": { + "version": "4.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/find-up": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/locate-path": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/p-limit": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/p-locate": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/path-exists": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs-unparser/node_modules/string-width": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/strip-ansi": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/yargs": { + "version": "14.2.3", + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "node_modules/yargs-unparser/node_modules/yargs-parser": { + "version": "15.0.1", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/path-exists": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@types/chai": { + "version": "4.2.12" + }, + "@types/color-name": { + "version": "1.1.1" + }, + "@types/cookiejar": { + "version": "2.1.1" + }, + "@types/node": { + "version": "14.11.2" + }, + "@types/superagent": { + "version": "3.8.7", + "requires": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "accepts": { + "version": "1.3.7", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ansi-colors": { + "version": "4.1.1" + }, + "ansi-regex": { + "version": "3.0.0" + }, + "ansi-styles": { + "version": "4.2.1", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1" + }, + "array.prototype.map": { + "version": "1.0.2", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.4" + } + }, + "assertion-error": { + "version": "1.1.0" + }, + "asynckit": { + "version": "0.4.0" + }, + "balanced-match": { + "version": "1.0.0" + }, + "binary-extensions": { + "version": "2.1.0" + }, + "body-parser": { + "version": "1.19.0", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "brace-expansion": { + "version": "1.1.11", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1" + }, + "bytes": { + "version": "3.1.0" + }, + "camelcase": { + "version": "5.3.1" + }, + "chai": { + "version": "4.2.0", + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chai-http": { + "version": "4.3.0", + "requires": { + "@types/chai": "4", + "@types/superagent": "^3.8.3", + "cookiejar": "^2.1.1", + "is-ip": "^2.0.0", + "methods": "^1.1.2", + "qs": "^6.5.1", + "superagent": "^3.7.0" + } + }, + "chalk": { + "version": "4.1.0", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-error": { + "version": "1.0.2" + }, + "chokidar": { + "version": "3.4.2", + "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.4.0" + } + }, + "cliui": { + "version": "5.0.0", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0" + }, + "string-width": { + "version": "3.1.0", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4" + }, + "combined-stream": { + "version": "1.0.8", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0" + }, + "concat-map": { + "version": "0.0.1" + }, + "content-disposition": { + "version": "0.5.3", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4" + }, + "cookie": { + "version": "0.4.0" + }, + "cookie-signature": { + "version": "1.0.6" + }, + "cookiejar": { + "version": "2.1.2" + }, + "core-util-is": { + "version": "1.0.2" + }, + "cors": { + "version": "2.8.5", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "debug": { + "version": "2.6.9", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0" + }, + "deep-eql": { + "version": "3.0.1", + "requires": { + "type-detect": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0" + }, + "depd": { + "version": "1.1.2" + }, + "destroy": { + "version": "1.0.4" + }, + "diff": { + "version": "4.0.2" + }, + "dotenv": { + "version": "8.2.0" + }, + "ee-first": { + "version": "1.1.1" + }, + "emoji-regex": { + "version": "7.0.3" + }, + "encodeurl": { + "version": "1.0.2" + }, + "es-abstract": { + "version": "1.17.6", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0" + }, + "es-get-iterator": { + "version": "1.1.0", + "requires": { + "es-abstract": "^1.17.4", + "has-symbols": "^1.0.1", + "is-arguments": "^1.0.4", + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5" + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3" + }, + "escape-string-regexp": { + "version": "4.0.0" + }, + "esprima": { + "version": "4.0.1" + }, + "etag": { + "version": "1.8.1" + }, + "express": { + "version": "4.17.1", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "extend": { + "version": "3.0.2" + }, + "fill-range": { + "version": "7.0.1", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "5.0.0", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "4.1.0", + "requires": { + "is-buffer": "~2.0.3" + } + }, + "form-data": { + "version": "2.5.1", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.2" + }, + "forwarded": { + "version": "0.1.2" + }, + "fresh": { + "version": "0.5.2" + }, + "fs.realpath": { + "version": "1.0.0" + }, + "fsevents": { + "version": "2.1.3", + "optional": true + }, + "function-bind": { + "version": "1.1.1" + }, + "get-caller-file": { + "version": "2.0.5" + }, + "get-func-name": { + "version": "2.0.0" + }, + "glob": { + "version": "7.1.6", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5" + }, + "has": { + "version": "1.0.3", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0" + }, + "has-symbols": { + "version": "1.0.1" + }, + "he": { + "version": "1.2.0" + }, + "http-errors": { + "version": "1.7.2", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3" + }, + "ip-regex": { + "version": "2.1.0" + }, + "ipaddr.js": { + "version": "1.9.1" + }, + "is-arguments": { + "version": "1.0.4" + }, + "is-binary-path": { + "version": "2.1.0", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "2.0.4" + }, + "is-callable": { + "version": "1.2.2" + }, + "is-date-object": { + "version": "1.0.2" + }, + "is-extglob": { + "version": "2.1.1" + }, + "is-fullwidth-code-point": { + "version": "2.0.0" + }, + "is-glob": { + "version": "4.0.1", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-ip": { + "version": "2.0.0", + "requires": { + "ip-regex": "^2.0.0" + } + }, + "is-map": { + "version": "2.0.1" + }, + "is-number": { + "version": "7.0.0" + }, + "is-plain-obj": { + "version": "1.1.0" + }, + "is-regex": { + "version": "1.1.1", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-set": { + "version": "2.0.1" + }, + "is-string": { + "version": "1.0.5" + }, + "is-symbol": { + "version": "1.0.3", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0" + }, + "isexe": { + "version": "2.0.0" + }, + "iterate-iterator": { + "version": "1.0.1" + }, + "iterate-value": { + "version": "1.0.2", + "requires": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + } + }, + "js-yaml": { + "version": "3.14.0", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.0.0", + "requires": { + "chalk": "^4.0.0" + } + }, + "media-typer": { + "version": "0.3.0" + }, + "merge-descriptors": { + "version": "1.0.1" + }, + "methods": { + "version": "1.1.2" + }, + "mime": { + "version": "1.6.0" + }, + "mime-db": { + "version": "1.44.0" + }, + "mime-types": { + "version": "2.1.27", + "requires": { + "mime-db": "1.44.0" + } + }, + "minimatch": { + "version": "3.0.4", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mocha": { + "version": "8.1.3", + "requires": { + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.2", + "debug": "4.1.1", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "object.assign": "4.1.0", + "promise.allsettled": "1.0.2", + "serialize-javascript": "4.0.0", + "strip-json-comments": "3.0.1", + "supports-color": "7.1.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.0", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2" + } + } + }, + "ms": { + "version": "2.0.0" + }, + "negotiator": { + "version": "0.6.2" + }, + "normalize-path": { + "version": "3.0.0" + }, + "object-assign": { + "version": "4.1.1" + }, + "object-inspect": { + "version": "1.8.0" + }, + "object-keys": { + "version": "1.1.1" + }, + "object.assign": { + "version": "4.1.0", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "on-finished": { + "version": "2.3.0", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.0.2", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0" + }, + "parseurl": { + "version": "1.3.3" + }, + "path-exists": { + "version": "4.0.0" + }, + "path-is-absolute": { + "version": "1.0.1" + }, + "path-to-regexp": { + "version": "0.1.7" + }, + "pathval": { + "version": "1.1.0" + }, + "picomatch": { + "version": "2.2.2" + }, + "process-nextick-args": { + "version": "2.0.1" + }, + "promise.allsettled": { + "version": "1.0.2", + "requires": { + "array.prototype.map": "^1.0.1", + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "iterate-value": "^1.0.0" + } + }, + "proxy-addr": { + "version": "2.0.6", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.7.0" + }, + "randombytes": { + "version": "2.1.0", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1" + }, + "raw-body": { + "version": "2.4.0", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "3.4.0", + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1" + }, + "require-main-filename": { + "version": "2.0.0" + }, + "safe-buffer": { + "version": "5.1.2" + }, + "safer-buffer": { + "version": "2.1.2" + }, + "send": { + "version": "0.17.1", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1" + } + } + }, + "serialize-javascript": { + "version": "4.0.0", + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0" + }, + "setprototypeof": { + "version": "1.1.1" + }, + "sprintf-js": { + "version": "1.0.3" + }, + "statuses": { + "version": "1.5.0" + }, + "string_decoder": { + "version": "1.1.1", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "2.1.1", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "4.0.0", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "3.0.1" + }, + "superagent": { + "version": "3.8.3", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2" + } + } + }, + "supports-color": { + "version": "7.1.0", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0" + }, + "type-detect": { + "version": "4.0.8" + }, + "type-is": { + "version": "1.6.18", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0" + }, + "util-deprecate": { + "version": "1.0.2" + }, + "utils-merge": { + "version": "1.0.1" + }, + "vary": { + "version": "1.1.2" + }, + "which": { + "version": "2.0.2", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0" + }, + "wide-align": { + "version": "1.1.3", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "workerpool": { + "version": "6.0.0" + }, + "wrap-ansi": { + "version": "5.1.0", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0" + }, + "ansi-styles": { + "version": "3.2.1", + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3" + }, + "string-width": { + "version": "3.1.0", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2" + }, + "y18n": { + "version": "4.0.0" + }, + "yargs": { + "version": "13.3.2", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0" + }, + "find-up": { + "version": "3.0.0", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0" + }, + "string-width": { + "version": "3.1.0", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.6.1", + "requires": { + "camelcase": "^5.3.1", + "decamelize": "^1.2.0", + "flat": "^4.1.0", + "is-plain-obj": "^1.1.0", + "yargs": "^14.2.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0" + }, + "find-up": { + "version": "3.0.0", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0" + }, + "string-width": { + "version": "3.1.0", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "yargs": { + "version": "14.2.3", + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.1", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + } + } +} diff --git a/7-quality-assurance/1-metric-imp-converter/package.json b/7-quality-assurance/1-metric-imp-converter/package.json new file mode 100644 index 0000000..015da23 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/package.json @@ -0,0 +1,29 @@ +{ + "name": "fcc-imperial-metric-converter-boilerplate", + "version": "1.0.0", + "description": "Metric / Imperial Unit Converter", + "main": "server.js", + "scripts": { + "start": "node server.js", + "test": "mocha ./tests/ --ui tdd" + }, + "dependencies": { + "body-parser": "^1.19.0", + "chai": "^4.2.0", + "chai-http": "^4.3.0", + "cors": "^2.8.5", + "dotenv": "^8.2.0", + "express": "^4.17.1", + "mocha": "^8.1.3" + }, + "repository": { + "type": "git", + "url": "https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter" + }, + "keywords": [ + "node", + "freeCodeCamp", + "express" + ], + "license": "MIT" +} diff --git a/7-quality-assurance/1-metric-imp-converter/public/style.css b/7-quality-assurance/1-metric-imp-converter/public/style.css new file mode 100644 index 0000000..9064f01 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/public/style.css @@ -0,0 +1,7 @@ +code { + background-color: whitesmoke; +} + +section, header { + margin: 50px; +} \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/replit.nix b/7-quality-assurance/1-metric-imp-converter/replit.nix new file mode 100644 index 0000000..9d43337 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/replit.nix @@ -0,0 +1,8 @@ +{ pkgs }: { + deps = [ + pkgs.nodejs-16_x + pkgs.nodePackages.typescript-language-server + pkgs.yarn + pkgs.replitPackages.jest + ]; +} \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/replit_zip_error_log.txt b/7-quality-assurance/1-metric-imp-converter/replit_zip_error_log.txt new file mode 100644 index 0000000..3cf6259 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/replit_zip_error_log.txt @@ -0,0 +1,9 @@ +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/_mocha","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/esparse","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/esvalidate","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/flat","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/he","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/js-yaml","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/mime","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/mocha","time":"2022-11-02T14:18:01Z"} +{"error":".zip archives do not support non-regular files","level":"error","msg":"unable to write file node_modules/.bin/node-which","time":"2022-11-02T14:18:01Z"} diff --git a/7-quality-assurance/1-metric-imp-converter/routes/api.js b/7-quality-assurance/1-metric-imp-converter/routes/api.js new file mode 100644 index 0000000..55a4deb --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/routes/api.js @@ -0,0 +1,21 @@ +'use strict'; +const ConvertHandler = require('../controllers/convertHandler.js'); + + +module.exports = function (app) { + + const convertHandler = new ConvertHandler(); + app.get('/api/convert', (req, res) => { + let error + const input = req.query.input + const initNum = convertHandler.getNum(input) + const initUnit = convertHandler.getUnit(input) + if (initNum === 'invalid number') {error = 'invalid number'} + if (initUnit === 'invalid unit') {if (!error){ error = 'invalid unit'} else {error = 'invalid number and unit'}} + if (error){res.json(error)} + const returnNum = parseFloat(convertHandler.convert(initNum, initUnit).toFixed(5)) + const returnUnit = convertHandler.getReturnUnit(initUnit) + const string = convertHandler.getString(initNum, initUnit, returnNum, returnUnit) + res.json({ initNum, initUnit, returnNum, returnUnit, string }) + }) +}; diff --git a/7-quality-assurance/1-metric-imp-converter/routes/fcctesting.js b/7-quality-assurance/1-metric-imp-converter/routes/fcctesting.js new file mode 100644 index 0000000..9f0d2a2 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/routes/fcctesting.js @@ -0,0 +1,102 @@ +/* +* +* +* +* +* +* +* +* +* +* +* +* DO NOT EDIT THIS FILE +* For FCC testing purposes! +* +* +* +* +* +* +* +* +* +* +* +*/ + +'use strict'; + +const cors = require('cors'); +const fs = require('fs'); +const runner = require('../test-runner'); + +module.exports = function (app) { + + app.route('/_api/server.js') + .get(function(req, res, next) { + console.log('requested'); + fs.readFile(__dirname + '/server.js', function(err, data) { + if(err) return next(err); + res.send(data.toString()); + }); + }); + app.route('/_api/routes/api.js') + .get(function(req, res, next) { + console.log('requested'); + fs.readFile(__dirname + '/routes/api.js', function(err, data) { + if(err) return next(err); + res.type('txt').send(data.toString()); + }); + }); + app.route('/_api/controllers/convertHandler.js') + .get(function(req, res, next) { + console.log('requested'); + fs.readFile(__dirname + '/controllers/convertHandler.js', function(err, data) { + if(err) return next(err); + res.type('txt').send(data.toString()); + }); + }); + + app.get('/_api/get-tests', cors(), function(req, res, next){ + console.log('requested'); + if(process.env.NODE_ENV === 'test') return next(); + res.json({status: 'unavailable'}); + }, + function(req, res, next){ + if(!runner.report) return next(); + res.json(testFilter(runner.report, req.query.type, req.query.n)); + }, + function(req, res){ + runner.on('done', function(report){ + process.nextTick(() => res.json(testFilter(runner.report, req.query.type, req.query.n))); + }); + }); + app.get('/_api/app-info', function(req, res) { + let hs = Object.keys(res._headers) + .filter(h => !h.match(/^access-control-\w+/)); + let hObj = {}; + hs.forEach(h => {hObj[h] = res._headers[h]}); + delete res._headers['strict-transport-security']; + res.json({headers: hObj}); + }); + +}; + +function testFilter(tests, type, n) { + let out; + switch (type) { + case 'unit' : + out = tests.filter(t => t.context.match('Unit Tests')); + break; + case 'functional': + out = tests.filter(t => t.context.match('Functional Tests') && !t.title.match('#example')); + break; + default: + out = tests; + } + if(n !== undefined) { + return out[n] || out; + } + return out; +} \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/sample.env b/7-quality-assurance/1-metric-imp-converter/sample.env new file mode 100644 index 0000000..20ead7f --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/sample.env @@ -0,0 +1,2 @@ +PORT= +# NODE_ENV=test diff --git a/7-quality-assurance/1-metric-imp-converter/server.js b/7-quality-assurance/1-metric-imp-converter/server.js new file mode 100644 index 0000000..2707728 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/server.js @@ -0,0 +1,59 @@ +'use strict'; + +const express = require('express'); +const bodyParser = require('body-parser'); +const expect = require('chai').expect; +const cors = require('cors'); +require('dotenv').config(); + +const apiRoutes = require('./routes/api.js'); +const fccTestingRoutes = require('./routes/fcctesting.js'); +const runner = require('./test-runner'); + +let app = express(); + +app.use('/public', express.static(process.cwd() + '/public')); + +app.use(cors({origin: '*'})); //For FCC testing purposes only + +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); + +//Index page (static HTML) +app.route('/') + .get(function (req, res) { + res.sendFile(process.cwd() + '/views/index.html'); + }); + +//For FCC testing purposes +fccTestingRoutes(app); + +//Routing for API +apiRoutes(app); + +//404 Not Found Middleware +app.use(function(req, res, next) { + res.status(404) + .type('text') + .send('Not Found'); +}); + +const port = process.env.PORT || 3000; + +//Start our server and tests! +app.listen(port, function () { + console.log("Listening on port " + port); + if(process.env.NODE_ENV==='test') { + console.log('Running Tests...'); + setTimeout(function () { + try { + runner.run(); + } catch(e) { + console.log('Tests are not valid:'); + console.error(e); + } + }, 1500); + } +}); + +module.exports = app; //for testing diff --git a/7-quality-assurance/1-metric-imp-converter/test-runner.js b/7-quality-assurance/1-metric-imp-converter/test-runner.js new file mode 100644 index 0000000..1db1e93 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/test-runner.js @@ -0,0 +1,106 @@ +/* +* +* +* +* +* +* +* +* +* +* +* +* DO NOT EDIT THIS FILE +* For FCC testing purposes! +* +* +* +* +* +* +* +* +* +* +* +*/ + +const analyser = require('./assertion-analyser'); +const EventEmitter = require('events').EventEmitter; + +const Mocha = require('mocha'), + fs = require('fs'), + path = require('path'); + +let mocha = new Mocha(); +let testDir = './tests' + + +// Add each .js file to the mocha instance +fs.readdirSync(testDir).filter(function(file){ + // Only keep the .js files + return file.substr(-3) === '.js'; + +}).forEach(function(file){ + mocha.addFile( + path.join(testDir, file) + ); +}); + +let emitter = new EventEmitter(); +emitter.run = function() { + + let tests = []; + let context = ""; + let separator = ' -> '; + // Run the tests. + try { + let runner = mocha.ui('tdd').run() + .on('test end', function(test) { + // remove comments + let body = test.body.replace(/\/\/.*\n|\/\*.*\*\//g, ''); + // collapse spaces + body = body.replace(/\s+/g,' '); + let obj = { + title: test.title, + context: context.slice(0, -separator.length), + state: test.state, + // body: body, + assertions: analyser(body) + }; + tests.push(obj); + }) + .on('end', function() { + emitter.report = tests; + emitter.emit('done', tests) + }) + .on('suite', function(s) { + context += (s.title + separator); + + }) + .on('suite end', function(s) { + context = context.slice(0, -(s.title.length + separator.length)) + }) + } catch(e) { + throw(e); + } +}; + +module.exports = emitter; + +/* + * Mocha.runner Events: + * can be used to build a better custom report + * + * - `start` execution started + * - `end` execution complete + * - `suite` (suite) test suite execution started + * - `suite end` (suite) all tests (and sub-suites) have finished + * - `test` (test) test execution started + * - `test end` (test) test completed + * - `hook` (hook) hook execution started + * - `hook end` (hook) hook complete + * - `pass` (test) test passed + * - `fail` (test, err) test failed + * - `pending` (test) test pending + */ \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/tests/1_unit-tests.js b/7-quality-assurance/1-metric-imp-converter/tests/1_unit-tests.js new file mode 100644 index 0000000..6dec302 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/tests/1_unit-tests.js @@ -0,0 +1,75 @@ +const chai = require('chai'); +let assert = chai.assert; +const ConvertHandler = require('../controllers/convertHandler.js'); + +let convertHandler = new ConvertHandler(); + +suite('Unit Tests',() => { + + test('convertHandler should correctly read a whole number input.', () => { + assert.equal(convertHandler.getNum('5kg'), '5') + assert.equal(convertHandler.getNum('3mi'), '3') + }) + test('convertHandler should correctly read a decimal number input.', () => { + assert.equal(convertHandler.getNum('5.5km'), '5.5') + assert.equal(convertHandler.getNum('7.3mi'), '7.3') + }) + test('convertHandler should correctly read a fractional input.', () => { + assert.equal(convertHandler.getNum('3/4lbs'), '0.75') + }) + test('convertHandler should correctly read a fractional input with a decimal', () => { + assert.equal(convertHandler.getNum('1.5/3kg'), '0.5') + }) + test('convertHandler should correctly return an error on a double-fraction (i.e. 3/2/3).', () => { + assert.equal(convertHandler.getNum('3/2/3mi'), 'invalid number') + }) + test('convertHandler should correctly default to a numerical input of 1 when no numerical input is provided.', () => { + assert.equal(convertHandler.getNum('kg'), '1') + }) + test('convertHandler should correctly read each valid input unit.', () => { + assert.equal(convertHandler.getUnit('1gal'), 'gal') + assert.equal(convertHandler.getUnit('2L'), 'L') + assert.equal(convertHandler.getUnit('3/4l'), 'L') + assert.equal(convertHandler.getUnit('5.7mi'), 'mi') + assert.equal(convertHandler.getUnit('9/3km'), 'km') + assert.equal(convertHandler.getUnit('3000lbs'), 'lbs') + assert.equal(convertHandler.getUnit('2kg'), 'kg') + }) + test('convertHandler should correctly return an error for an invalid input unit.', () => { + assert.equal(convertHandler.getUnit('football fields'), 'invalid unit') + }) + test('convertHandler should return the correct return unit for each valid input unit.', () => { + assert.equal(convertHandler.getReturnUnit('gal'), 'L') + assert.equal(convertHandler.getReturnUnit('L'), 'gal') + assert.equal(convertHandler.getReturnUnit('mi'), 'km') + assert.equal(convertHandler.getReturnUnit('km'), 'mi') + assert.equal(convertHandler.getReturnUnit('lbs'), 'kg') + assert.equal(convertHandler.getReturnUnit('kg'), 'lbs') + }) + test('convertHandler should correctly return the spelled-out string unit for each valid input unit.', () => { + assert.equal(convertHandler.spellOutUnit('gal'), 'gallons') + assert.equal(convertHandler.spellOutUnit('L'), 'liters') + assert.equal(convertHandler.spellOutUnit('mi'), 'miles') + assert.equal(convertHandler.spellOutUnit('km'), 'kilometers') + assert.equal(convertHandler.spellOutUnit('lbs'), 'pounds') + assert.equal(convertHandler.spellOutUnit('kg'), 'kilograms') + }) + test('convertHandler should correctly convert gal to L', () => { + assert.approximately(convertHandler.convert(1, 'gal'), 3.78, 0.1) + }) + test('convertHandler should correctly convert L to gal.', () => { + assert.approximately(convertHandler.convert(1, 'L'), 0.26, 0.1) + }) + test('convertHandler should correctly convert mi to km.', () => { + assert.approximately(convertHandler.convert(1, 'mi'), 1.60, 0.1) + }) + test('convertHandler should correctly convert km to mi.', () => { + assert.approximately(convertHandler.convert(1, 'km'), 0.62, 0.1) + }) + test('convertHandler should correctly convert lbs to kg.', () => { + assert.approximately(convertHandler.convert(1, 'lbs'), 0.45, 0.1) + }) + test('convertHandler should correctly convert kg to lbs.', () => { + assert.approximately(convertHandler.convert(1, 'kg'), 2.2, 0.1) + }) +}); \ No newline at end of file diff --git a/7-quality-assurance/1-metric-imp-converter/tests/2_functional-tests.js b/7-quality-assurance/1-metric-imp-converter/tests/2_functional-tests.js new file mode 100644 index 0000000..5478d8f --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/tests/2_functional-tests.js @@ -0,0 +1,55 @@ +const chaiHttp = require('chai-http'); +const chai = require('chai'); +let assert = chai.assert; +const server = require('../server'); + +chai.use(chaiHttp); + +suite('Functional Tests', function() { + test('Convert a valid input such as 10L: GET request to /api/convert.', () => { + chai + .request(server) + .get('/api/convert') + .query({ input: '10L' }) + .end((err, res) => { + assert.equal(res.body.initNum, 10) + assert.equal(res.body.initUnit, 'L') + }) + }) + test('Convert an invalid input such as 32g: GET request to /api/convert.', () => { + chai + .request(server) + .get('/api/convert') + .query({ input: '32g' }) + .end((err, res) => { + assert.equal(res.body, 'invalid unit') + }) + }) + test('Convert an invalid number such as 3/7.2/4kg: GET request to /api/convert', () => { + chai + .request(server) + .get('/api/convert') + .query({ input: '3/7.2/4kg' }) + .end((err, res) => { + assert.equal(res.body, 'invalid number') + }) + }) + test('Convert an invalid number AND unit such as 3/7.2/4kilomegagram: GET request to /api/convert.', () => { + chai + .request(server) + .get('/api/convert') + .query({ input: '3/7.2/4kilomegagram' }) + .end((err, res) => { + assert.equal(res.body, 'invalid number and unit') + }) + }) + test('Convert with no number such as kg: GET request to /api/convert.', () => { + chai + .request(server) + .get('/api/convert') + .query({ input: 'kg' }) + .end((err, res) => { + assert.equal(res.body.initNum, 1) + }) + }) +}); diff --git a/7-quality-assurance/1-metric-imp-converter/views/index.html b/7-quality-assurance/1-metric-imp-converter/views/index.html new file mode 100644 index 0000000..6e4ad23 --- /dev/null +++ b/7-quality-assurance/1-metric-imp-converter/views/index.html @@ -0,0 +1,59 @@ + + + + Metric/Imperial Converter + + + + + + + + +
+

Metric/Imperial Converter

+
+
+
+

Example usage

+ /api/convert?input=4gal
+ /api/convert?input=1/2km
+ /api/convert?input=5.4/3lbs
+ /api/convert?input=kg
+

Example return

+ { initNum: 3.1, initUnit: 'mi', returnNum: 4.98895, returnUnit: 'km', string: '3.1 miles converts to 4.98895 kilometers' } +
+
+
+
+

Front-End

+
+ + +
+

+ +
+
+ + + + +