فهرست منبع

Merge pull request #4940 from overleaf/bg-add-prettier-and-eslint-to-latex-log-parser

add prettier and eslint to latex log parser

GitOrigin-RevId: 6985fb253c0e4935fae0bbae34823ab058dfb34c
Brian Gough 5 سال پیش
والد
کامیت
88a69257dc

+ 73 - 0
libraries/latex-log-parser/.eslintrc

@@ -0,0 +1,73 @@
+// this file was auto-generated, do not edit it directly.
+// instead run bin/update_build_scripts from
+// https://github.com/sharelatex/sharelatex-dev-environment
+{
+  "extends": [
+    "eslint:recommended",
+    "standard",
+    "prettier"
+  ],
+  "parserOptions": {
+    "ecmaVersion": 2018
+  },
+  "plugins": [
+    "mocha",
+    "chai-expect",
+    "chai-friendly"
+  ],
+  "env": {
+    "node": true,
+    "mocha": true
+  },
+  "rules": {
+    // Swap the no-unused-expressions rule with a more chai-friendly one
+    "no-unused-expressions": 0,
+    "chai-friendly/no-unused-expressions": "error",
+
+    // Do not allow importing of implicit dependencies.
+    "import/no-extraneous-dependencies": "error"
+  },
+  "overrides": [
+    {
+      // Test specific rules
+      "files": ["test/**/*.js"],
+      "globals": {
+        "expect": true
+      },
+      "rules": {
+        // mocha-specific rules
+        "mocha/handle-done-callback": "error",
+        "mocha/no-exclusive-tests": "error",
+        "mocha/no-global-tests": "error",
+        "mocha/no-identical-title": "error",
+        "mocha/no-nested-tests": "error",
+        "mocha/no-pending-tests": "error",
+        "mocha/no-skipped-tests": "error",
+        "mocha/no-mocha-arrows": "error",
+
+        // chai-specific rules
+        "chai-expect/missing-assertion": "error",
+        "chai-expect/terminating-properties": "error",
+
+        // prefer-arrow-callback applies to all callbacks, not just ones in mocha tests.
+        // we don't enforce this at the top-level - just in tests to manage `this` scope
+        // based on mocha's context mechanism
+        "mocha/prefer-arrow-callback": "error"
+      }
+    },
+    {
+      // Backend specific rules
+      "files": ["lib/**/*.js", "index.js"],
+      "rules": {
+        // don't allow console.log in backend code
+        "no-console": "error",
+
+        // Do not allow importing of implicit dependencies.
+        "import/no-extraneous-dependencies": ["error", {
+          // Do not allow importing of devDependencies.
+          "devDependencies": false
+        }]
+      }
+    }
+  ]
+}

+ 11 - 0
libraries/latex-log-parser/.prettierrc

@@ -0,0 +1,11 @@
+# This file was auto-generated, do not edit it directly.
+# Instead run bin/update_build_scripts from
+# https://github.com/sharelatex/sharelatex-dev-environment
+{
+  "arrowParens": "avoid",
+  "semi": false,
+  "singleQuote": true,
+  "trailingComma": "es5",
+  "tabWidth": 2,
+  "useTabs": false
+}

+ 1779 - 6
libraries/latex-log-parser/package-lock.json

@@ -1,13 +1,1786 @@
 {
-	"name": "latex-log-parser-sharelatex",
-	"version": "1.0.0",
+	"name": "@overleaf/latex-log-parser",
+	"version": "2.0.0",
 	"lockfileVersion": 1,
 	"requires": true,
 	"dependencies": {
-		"coffee-script": {
-			"version": "1.12.7",
-			"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
-			"integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw=="
+		"@babel/code-frame": {
+			"version": "7.12.11",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+			"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+			"dev": true,
+			"requires": {
+				"@babel/highlight": "^7.10.4"
+			}
+		},
+		"@babel/helper-validator-identifier": {
+			"version": "7.14.9",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
+			"integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
+			"dev": true
+		},
+		"@babel/highlight": {
+			"version": "7.14.5",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+			"integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+			"dev": true,
+			"requires": {
+				"@babel/helper-validator-identifier": "^7.14.5",
+				"chalk": "^2.0.0",
+				"js-tokens": "^4.0.0"
+			},
+			"dependencies": {
+				"chalk": {
+					"version": "2.4.2",
+					"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+					"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+					"dev": true,
+					"requires": {
+						"ansi-styles": "^3.2.1",
+						"escape-string-regexp": "^1.0.5",
+						"supports-color": "^5.3.0"
+					}
+				},
+				"escape-string-regexp": {
+					"version": "1.0.5",
+					"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+					"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+					"dev": true
+				}
+			}
+		},
+		"@eslint/eslintrc": {
+			"version": "0.4.3",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
+			"integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+			"dev": true,
+			"requires": {
+				"ajv": "^6.12.4",
+				"debug": "^4.1.1",
+				"espree": "^7.3.0",
+				"globals": "^13.9.0",
+				"ignore": "^4.0.6",
+				"import-fresh": "^3.2.1",
+				"js-yaml": "^3.13.1",
+				"minimatch": "^3.0.4",
+				"strip-json-comments": "^3.1.1"
+			}
+		},
+		"@humanwhocodes/config-array": {
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
+			"integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+			"dev": true,
+			"requires": {
+				"@humanwhocodes/object-schema": "^1.2.0",
+				"debug": "^4.1.1",
+				"minimatch": "^3.0.4"
+			}
+		},
+		"@humanwhocodes/object-schema": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
+			"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+			"dev": true
+		},
+		"@types/json5": {
+			"version": "0.0.29",
+			"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+			"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
+			"dev": true
+		},
+		"acorn": {
+			"version": "7.4.1",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+			"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+			"dev": true
+		},
+		"acorn-jsx": {
+			"version": "5.3.2",
+			"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+			"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+			"dev": true
+		},
+		"ajv": {
+			"version": "6.12.6",
+			"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+			"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+			"dev": true,
+			"requires": {
+				"fast-deep-equal": "^3.1.1",
+				"fast-json-stable-stringify": "^2.0.0",
+				"json-schema-traverse": "^0.4.1",
+				"uri-js": "^4.2.2"
+			}
+		},
+		"ansi-colors": {
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+			"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+			"dev": true
+		},
+		"ansi-regex": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+			"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+			"dev": true
+		},
+		"ansi-styles": {
+			"version": "3.2.1",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+			"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+			"dev": true,
+			"requires": {
+				"color-convert": "^1.9.0"
+			}
+		},
+		"argparse": {
+			"version": "1.0.10",
+			"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+			"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+			"dev": true,
+			"requires": {
+				"sprintf-js": "~1.0.2"
+			}
+		},
+		"array-includes": {
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz",
+			"integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.18.0-next.2",
+				"get-intrinsic": "^1.1.1",
+				"is-string": "^1.0.5"
+			}
+		},
+		"array.prototype.flat": {
+			"version": "1.2.4",
+			"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz",
+			"integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.0",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.18.0-next.1"
+			}
+		},
+		"astral-regex": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+			"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+			"dev": true
+		},
+		"balanced-match": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+			"dev": true
+		},
+		"brace-expansion": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+			"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+			"dev": true,
+			"requires": {
+				"balanced-match": "^1.0.0",
+				"concat-map": "0.0.1"
+			}
+		},
+		"call-bind": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+			"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+			"dev": true,
+			"requires": {
+				"function-bind": "^1.1.1",
+				"get-intrinsic": "^1.0.2"
+			}
+		},
+		"callsites": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+			"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+			"dev": true
+		},
+		"chalk": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+			"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+			"dev": true,
+			"requires": {
+				"ansi-styles": "^4.1.0",
+				"supports-color": "^7.1.0"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "4.3.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+					"dev": true,
+					"requires": {
+						"color-convert": "^2.0.1"
+					}
+				},
+				"color-convert": {
+					"version": "2.0.1",
+					"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+					"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+					"dev": true,
+					"requires": {
+						"color-name": "~1.1.4"
+					}
+				},
+				"color-name": {
+					"version": "1.1.4",
+					"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+					"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+					"dev": true
+				},
+				"has-flag": {
+					"version": "4.0.0",
+					"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+					"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+					"dev": true
+				},
+				"supports-color": {
+					"version": "7.2.0",
+					"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+					"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+					"dev": true,
+					"requires": {
+						"has-flag": "^4.0.0"
+					}
+				}
+			}
+		},
+		"color-convert": {
+			"version": "1.9.3",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+			"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+			"dev": true,
+			"requires": {
+				"color-name": "1.1.3"
+			}
+		},
+		"color-name": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+			"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+			"dev": true
+		},
+		"concat-map": {
+			"version": "0.0.1",
+			"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+			"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+			"dev": true
+		},
+		"cross-spawn": {
+			"version": "7.0.3",
+			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+			"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+			"dev": true,
+			"requires": {
+				"path-key": "^3.1.0",
+				"shebang-command": "^2.0.0",
+				"which": "^2.0.1"
+			}
+		},
+		"debug": {
+			"version": "4.3.2",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+			"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+			"dev": true,
+			"requires": {
+				"ms": "2.1.2"
+			}
+		},
+		"deep-is": {
+			"version": "0.1.3",
+			"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+			"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+			"dev": true
+		},
+		"define-properties": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+			"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+			"dev": true,
+			"requires": {
+				"object-keys": "^1.0.12"
+			}
+		},
+		"doctrine": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+			"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+			"dev": true,
+			"requires": {
+				"esutils": "^2.0.2"
+			}
+		},
+		"emoji-regex": {
+			"version": "8.0.0",
+			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+			"dev": true
+		},
+		"enquirer": {
+			"version": "2.3.6",
+			"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+			"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+			"dev": true,
+			"requires": {
+				"ansi-colors": "^4.1.1"
+			}
+		},
+		"error-ex": {
+			"version": "1.3.2",
+			"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+			"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+			"dev": true,
+			"requires": {
+				"is-arrayish": "^0.2.1"
+			}
+		},
+		"es-abstract": {
+			"version": "1.18.5",
+			"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz",
+			"integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"es-to-primitive": "^1.2.1",
+				"function-bind": "^1.1.1",
+				"get-intrinsic": "^1.1.1",
+				"has": "^1.0.3",
+				"has-symbols": "^1.0.2",
+				"internal-slot": "^1.0.3",
+				"is-callable": "^1.2.3",
+				"is-negative-zero": "^2.0.1",
+				"is-regex": "^1.1.3",
+				"is-string": "^1.0.6",
+				"object-inspect": "^1.11.0",
+				"object-keys": "^1.1.1",
+				"object.assign": "^4.1.2",
+				"string.prototype.trimend": "^1.0.4",
+				"string.prototype.trimstart": "^1.0.4",
+				"unbox-primitive": "^1.0.1"
+			}
+		},
+		"es-to-primitive": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+			"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+			"dev": true,
+			"requires": {
+				"is-callable": "^1.1.4",
+				"is-date-object": "^1.0.1",
+				"is-symbol": "^1.0.2"
+			}
+		},
+		"escape-string-regexp": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+			"dev": true
+		},
+		"eslint": {
+			"version": "7.32.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
+			"integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+			"dev": true,
+			"requires": {
+				"@babel/code-frame": "7.12.11",
+				"@eslint/eslintrc": "^0.4.3",
+				"@humanwhocodes/config-array": "^0.5.0",
+				"ajv": "^6.10.0",
+				"chalk": "^4.0.0",
+				"cross-spawn": "^7.0.2",
+				"debug": "^4.0.1",
+				"doctrine": "^3.0.0",
+				"enquirer": "^2.3.5",
+				"escape-string-regexp": "^4.0.0",
+				"eslint-scope": "^5.1.1",
+				"eslint-utils": "^2.1.0",
+				"eslint-visitor-keys": "^2.0.0",
+				"espree": "^7.3.1",
+				"esquery": "^1.4.0",
+				"esutils": "^2.0.2",
+				"fast-deep-equal": "^3.1.3",
+				"file-entry-cache": "^6.0.1",
+				"functional-red-black-tree": "^1.0.1",
+				"glob-parent": "^5.1.2",
+				"globals": "^13.6.0",
+				"ignore": "^4.0.6",
+				"import-fresh": "^3.0.0",
+				"imurmurhash": "^0.1.4",
+				"is-glob": "^4.0.0",
+				"js-yaml": "^3.13.1",
+				"json-stable-stringify-without-jsonify": "^1.0.1",
+				"levn": "^0.4.1",
+				"lodash.merge": "^4.6.2",
+				"minimatch": "^3.0.4",
+				"natural-compare": "^1.4.0",
+				"optionator": "^0.9.1",
+				"progress": "^2.0.0",
+				"regexpp": "^3.1.0",
+				"semver": "^7.2.1",
+				"strip-ansi": "^6.0.0",
+				"strip-json-comments": "^3.1.0",
+				"table": "^6.0.9",
+				"text-table": "^0.2.0",
+				"v8-compile-cache": "^2.0.3"
+			}
+		},
+		"eslint-config-prettier": {
+			"version": "8.3.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz",
+			"integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==",
+			"dev": true
+		},
+		"eslint-config-standard": {
+			"version": "16.0.3",
+			"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz",
+			"integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==",
+			"dev": true
+		},
+		"eslint-import-resolver-node": {
+			"version": "0.3.6",
+			"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
+			"integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
+			"dev": true,
+			"requires": {
+				"debug": "^3.2.7",
+				"resolve": "^1.20.0"
+			},
+			"dependencies": {
+				"debug": {
+					"version": "3.2.7",
+					"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+					"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+					"dev": true,
+					"requires": {
+						"ms": "^2.1.1"
+					}
+				}
+			}
+		},
+		"eslint-module-utils": {
+			"version": "2.6.2",
+			"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz",
+			"integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==",
+			"dev": true,
+			"requires": {
+				"debug": "^3.2.7",
+				"pkg-dir": "^2.0.0"
+			},
+			"dependencies": {
+				"debug": {
+					"version": "3.2.7",
+					"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+					"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+					"dev": true,
+					"requires": {
+						"ms": "^2.1.1"
+					}
+				}
+			}
+		},
+		"eslint-plugin-chai-expect": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz",
+			"integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==",
+			"dev": true
+		},
+		"eslint-plugin-chai-friendly": {
+			"version": "0.7.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz",
+			"integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==",
+			"dev": true
+		},
+		"eslint-plugin-es": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
+			"integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
+			"dev": true,
+			"requires": {
+				"eslint-utils": "^2.0.0",
+				"regexpp": "^3.0.0"
+			}
+		},
+		"eslint-plugin-import": {
+			"version": "2.24.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz",
+			"integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==",
+			"dev": true,
+			"requires": {
+				"array-includes": "^3.1.3",
+				"array.prototype.flat": "^1.2.4",
+				"debug": "^2.6.9",
+				"doctrine": "^2.1.0",
+				"eslint-import-resolver-node": "^0.3.6",
+				"eslint-module-utils": "^2.6.2",
+				"find-up": "^2.0.0",
+				"has": "^1.0.3",
+				"is-core-module": "^2.6.0",
+				"minimatch": "^3.0.4",
+				"object.values": "^1.1.4",
+				"pkg-up": "^2.0.0",
+				"read-pkg-up": "^3.0.0",
+				"resolve": "^1.20.0",
+				"tsconfig-paths": "^3.11.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"
+					}
+				},
+				"doctrine": {
+					"version": "2.1.0",
+					"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+					"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+					"dev": true,
+					"requires": {
+						"esutils": "^2.0.2"
+					}
+				},
+				"ms": {
+					"version": "2.0.0",
+					"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+					"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+					"dev": true
+				}
+			}
+		},
+		"eslint-plugin-mocha": {
+			"version": "9.0.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz",
+			"integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==",
+			"dev": true,
+			"requires": {
+				"eslint-utils": "^3.0.0",
+				"ramda": "^0.27.1"
+			},
+			"dependencies": {
+				"eslint-utils": {
+					"version": "3.0.0",
+					"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+					"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+					"dev": true,
+					"requires": {
+						"eslint-visitor-keys": "^2.0.0"
+					}
+				}
+			}
+		},
+		"eslint-plugin-node": {
+			"version": "11.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
+			"integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
+			"dev": true,
+			"requires": {
+				"eslint-plugin-es": "^3.0.0",
+				"eslint-utils": "^2.0.0",
+				"ignore": "^5.1.1",
+				"minimatch": "^3.0.4",
+				"resolve": "^1.10.1",
+				"semver": "^6.1.0"
+			},
+			"dependencies": {
+				"ignore": {
+					"version": "5.1.8",
+					"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+					"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+					"dev": true
+				},
+				"semver": {
+					"version": "6.3.0",
+					"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+					"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+					"dev": true
+				}
+			}
+		},
+		"eslint-plugin-prettier": {
+			"version": "3.4.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz",
+			"integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==",
+			"dev": true,
+			"requires": {
+				"prettier-linter-helpers": "^1.0.0"
+			}
+		},
+		"eslint-plugin-promise": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz",
+			"integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==",
+			"dev": true
+		},
+		"eslint-scope": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+			"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+			"dev": true,
+			"requires": {
+				"esrecurse": "^4.3.0",
+				"estraverse": "^4.1.1"
+			}
+		},
+		"eslint-utils": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+			"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+			"dev": true,
+			"requires": {
+				"eslint-visitor-keys": "^1.1.0"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "1.3.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+					"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+					"dev": true
+				}
+			}
+		},
+		"eslint-visitor-keys": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+			"dev": true
+		},
+		"espree": {
+			"version": "7.3.1",
+			"resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+			"integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+			"dev": true,
+			"requires": {
+				"acorn": "^7.4.0",
+				"acorn-jsx": "^5.3.1",
+				"eslint-visitor-keys": "^1.3.0"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "1.3.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+					"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+					"dev": true
+				}
+			}
+		},
+		"esprima": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+			"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+			"dev": true
+		},
+		"esquery": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+			"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+			"dev": true,
+			"requires": {
+				"estraverse": "^5.1.0"
+			},
+			"dependencies": {
+				"estraverse": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+					"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+					"dev": true
+				}
+			}
+		},
+		"esrecurse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+			"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+			"dev": true,
+			"requires": {
+				"estraverse": "^5.2.0"
+			},
+			"dependencies": {
+				"estraverse": {
+					"version": "5.2.0",
+					"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+					"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+					"dev": true
+				}
+			}
+		},
+		"estraverse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+			"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+			"dev": true
+		},
+		"esutils": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+			"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+			"dev": true
+		},
+		"fast-deep-equal": {
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+			"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+			"dev": true
+		},
+		"fast-diff": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+			"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+			"dev": true
+		},
+		"fast-json-stable-stringify": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+			"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+			"dev": true
+		},
+		"fast-levenshtein": {
+			"version": "2.0.6",
+			"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+			"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+			"dev": true
+		},
+		"file-entry-cache": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+			"integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+			"dev": true,
+			"requires": {
+				"flat-cache": "^3.0.4"
+			}
+		},
+		"find-up": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+			"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+			"dev": true,
+			"requires": {
+				"locate-path": "^2.0.0"
+			}
+		},
+		"flat-cache": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+			"integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+			"dev": true,
+			"requires": {
+				"flatted": "^3.1.0",
+				"rimraf": "^3.0.2"
+			}
+		},
+		"flatted": {
+			"version": "3.2.2",
+			"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
+			"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
+			"dev": true
+		},
+		"fs.realpath": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+			"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+			"dev": true
+		},
+		"function-bind": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+			"dev": true
+		},
+		"functional-red-black-tree": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+			"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+			"dev": true
+		},
+		"get-intrinsic": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+			"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+			"dev": true,
+			"requires": {
+				"function-bind": "^1.1.1",
+				"has": "^1.0.3",
+				"has-symbols": "^1.0.1"
+			}
+		},
+		"glob": {
+			"version": "7.1.7",
+			"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+			"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+			"dev": true,
+			"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.2",
+			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+			"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+			"dev": true,
+			"requires": {
+				"is-glob": "^4.0.1"
+			}
+		},
+		"globals": {
+			"version": "13.11.0",
+			"resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
+			"integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
+			"dev": true,
+			"requires": {
+				"type-fest": "^0.20.2"
+			}
+		},
+		"graceful-fs": {
+			"version": "4.2.8",
+			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+			"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
+			"dev": true
+		},
+		"has": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+			"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+			"dev": true,
+			"requires": {
+				"function-bind": "^1.1.1"
+			}
+		},
+		"has-bigints": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
+			"integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+			"dev": true
+		},
+		"has-flag": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+			"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+			"dev": true
+		},
+		"has-symbols": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+			"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+			"dev": true
+		},
+		"has-tostringtag": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+			"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+			"dev": true,
+			"requires": {
+				"has-symbols": "^1.0.2"
+			}
+		},
+		"hosted-git-info": {
+			"version": "2.8.9",
+			"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+			"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+			"dev": true
+		},
+		"ignore": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+			"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+			"dev": true
+		},
+		"import-fresh": {
+			"version": "3.3.0",
+			"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+			"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+			"dev": true,
+			"requires": {
+				"parent-module": "^1.0.0",
+				"resolve-from": "^4.0.0"
+			}
+		},
+		"imurmurhash": {
+			"version": "0.1.4",
+			"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+			"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+			"dev": true
+		},
+		"inflight": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+			"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+			"dev": true,
+			"requires": {
+				"once": "^1.3.0",
+				"wrappy": "1"
+			}
+		},
+		"inherits": {
+			"version": "2.0.4",
+			"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+			"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+			"dev": true
+		},
+		"internal-slot": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+			"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+			"dev": true,
+			"requires": {
+				"get-intrinsic": "^1.1.0",
+				"has": "^1.0.3",
+				"side-channel": "^1.0.4"
+			}
+		},
+		"is-arrayish": {
+			"version": "0.2.1",
+			"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+			"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+			"dev": true
+		},
+		"is-bigint": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+			"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+			"dev": true,
+			"requires": {
+				"has-bigints": "^1.0.1"
+			}
+		},
+		"is-boolean-object": {
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+			"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-callable": {
+			"version": "1.2.4",
+			"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
+			"integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+			"dev": true
+		},
+		"is-core-module": {
+			"version": "2.6.0",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
+			"integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
+			"dev": true,
+			"requires": {
+				"has": "^1.0.3"
+			}
+		},
+		"is-date-object": {
+			"version": "1.0.5",
+			"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+			"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+			"dev": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-extglob": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+			"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+			"dev": true
+		},
+		"is-fullwidth-code-point": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+			"dev": true
+		},
+		"is-glob": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+			"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+			"dev": true,
+			"requires": {
+				"is-extglob": "^2.1.1"
+			}
+		},
+		"is-negative-zero": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+			"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+			"dev": true
+		},
+		"is-number-object": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
+			"integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+			"dev": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-regex": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+			"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-string": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+			"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+			"dev": true,
+			"requires": {
+				"has-tostringtag": "^1.0.0"
+			}
+		},
+		"is-symbol": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+			"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+			"dev": true,
+			"requires": {
+				"has-symbols": "^1.0.2"
+			}
+		},
+		"isexe": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+			"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+			"dev": true
+		},
+		"js-tokens": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+			"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+			"dev": true
+		},
+		"js-yaml": {
+			"version": "3.14.1",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+			"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+			"dev": true,
+			"requires": {
+				"argparse": "^1.0.7",
+				"esprima": "^4.0.0"
+			}
+		},
+		"json-parse-better-errors": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+			"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+			"dev": true
+		},
+		"json-schema-traverse": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+			"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+			"dev": true
+		},
+		"json-stable-stringify-without-jsonify": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+			"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+			"dev": true
+		},
+		"json5": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+			"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+			"dev": true,
+			"requires": {
+				"minimist": "^1.2.0"
+			}
+		},
+		"levn": {
+			"version": "0.4.1",
+			"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+			"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+			"dev": true,
+			"requires": {
+				"prelude-ls": "^1.2.1",
+				"type-check": "~0.4.0"
+			}
+		},
+		"load-json-file": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+			"integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+			"dev": true,
+			"requires": {
+				"graceful-fs": "^4.1.2",
+				"parse-json": "^4.0.0",
+				"pify": "^3.0.0",
+				"strip-bom": "^3.0.0"
+			}
+		},
+		"locate-path": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+			"integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+			"dev": true,
+			"requires": {
+				"p-locate": "^2.0.0",
+				"path-exists": "^3.0.0"
+			}
+		},
+		"lodash.clonedeep": {
+			"version": "4.5.0",
+			"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+			"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+			"dev": true
+		},
+		"lodash.merge": {
+			"version": "4.6.2",
+			"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+			"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+			"dev": true
+		},
+		"lodash.truncate": {
+			"version": "4.4.2",
+			"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+			"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+			"dev": true
+		},
+		"lru-cache": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+			"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+			"dev": true,
+			"requires": {
+				"yallist": "^4.0.0"
+			}
+		},
+		"minimatch": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+			"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+			"dev": true,
+			"requires": {
+				"brace-expansion": "^1.1.7"
+			}
+		},
+		"minimist": {
+			"version": "1.2.5",
+			"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+			"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+			"dev": true
+		},
+		"ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"dev": true
+		},
+		"natural-compare": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+			"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+			"dev": true
+		},
+		"normalize-package-data": {
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+			"integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+			"dev": true,
+			"requires": {
+				"hosted-git-info": "^2.1.4",
+				"resolve": "^1.10.0",
+				"semver": "2 || 3 || 4 || 5",
+				"validate-npm-package-license": "^3.0.1"
+			},
+			"dependencies": {
+				"semver": {
+					"version": "5.7.1",
+					"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+					"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+					"dev": true
+				}
+			}
+		},
+		"object-inspect": {
+			"version": "1.11.0",
+			"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
+			"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
+			"dev": true
+		},
+		"object-keys": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+			"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+			"dev": true
+		},
+		"object.assign": {
+			"version": "4.1.2",
+			"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+			"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.0",
+				"define-properties": "^1.1.3",
+				"has-symbols": "^1.0.1",
+				"object-keys": "^1.1.1"
+			}
+		},
+		"object.values": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz",
+			"integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3",
+				"es-abstract": "^1.18.2"
+			}
+		},
+		"once": {
+			"version": "1.4.0",
+			"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+			"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+			"dev": true,
+			"requires": {
+				"wrappy": "1"
+			}
+		},
+		"optionator": {
+			"version": "0.9.1",
+			"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+			"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+			"dev": true,
+			"requires": {
+				"deep-is": "^0.1.3",
+				"fast-levenshtein": "^2.0.6",
+				"levn": "^0.4.1",
+				"prelude-ls": "^1.2.1",
+				"type-check": "^0.4.0",
+				"word-wrap": "^1.2.3"
+			}
+		},
+		"p-limit": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+			"integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+			"dev": true,
+			"requires": {
+				"p-try": "^1.0.0"
+			}
+		},
+		"p-locate": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+			"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+			"dev": true,
+			"requires": {
+				"p-limit": "^1.1.0"
+			}
+		},
+		"p-try": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+			"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+			"dev": true
+		},
+		"parent-module": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+			"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+			"dev": true,
+			"requires": {
+				"callsites": "^3.0.0"
+			}
+		},
+		"parse-json": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+			"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+			"dev": true,
+			"requires": {
+				"error-ex": "^1.3.1",
+				"json-parse-better-errors": "^1.0.1"
+			}
+		},
+		"path-exists": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+			"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+			"dev": true
+		},
+		"path-is-absolute": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+			"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+			"dev": true
+		},
+		"path-key": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+			"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+			"dev": true
+		},
+		"path-parse": {
+			"version": "1.0.7",
+			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+			"dev": true
+		},
+		"path-type": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+			"integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+			"dev": true,
+			"requires": {
+				"pify": "^3.0.0"
+			}
+		},
+		"pify": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+			"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+			"dev": true
+		},
+		"pkg-dir": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+			"integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+			"dev": true,
+			"requires": {
+				"find-up": "^2.1.0"
+			}
+		},
+		"pkg-up": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
+			"integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
+			"dev": true,
+			"requires": {
+				"find-up": "^2.1.0"
+			}
+		},
+		"prelude-ls": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+			"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+			"dev": true
+		},
+		"prettier": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
+			"integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
+			"dev": true
+		},
+		"prettier-linter-helpers": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+			"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+			"dev": true,
+			"requires": {
+				"fast-diff": "^1.1.2"
+			}
+		},
+		"progress": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+			"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+			"dev": true
+		},
+		"punycode": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+			"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+			"dev": true
+		},
+		"ramda": {
+			"version": "0.27.1",
+			"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz",
+			"integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==",
+			"dev": true
+		},
+		"read-pkg": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+			"integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+			"dev": true,
+			"requires": {
+				"load-json-file": "^4.0.0",
+				"normalize-package-data": "^2.3.2",
+				"path-type": "^3.0.0"
+			}
+		},
+		"read-pkg-up": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
+			"integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+			"dev": true,
+			"requires": {
+				"find-up": "^2.0.0",
+				"read-pkg": "^3.0.0"
+			}
+		},
+		"regexpp": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+			"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+			"dev": true
+		},
+		"require-from-string": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+			"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+			"dev": true
+		},
+		"resolve": {
+			"version": "1.20.0",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+			"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+			"dev": true,
+			"requires": {
+				"is-core-module": "^2.2.0",
+				"path-parse": "^1.0.6"
+			}
+		},
+		"resolve-from": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+			"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+			"dev": true
+		},
+		"rimraf": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+			"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+			"dev": true,
+			"requires": {
+				"glob": "^7.1.3"
+			}
+		},
+		"semver": {
+			"version": "7.3.5",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+			"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+			"dev": true,
+			"requires": {
+				"lru-cache": "^6.0.0"
+			}
+		},
+		"shebang-command": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+			"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+			"dev": true,
+			"requires": {
+				"shebang-regex": "^3.0.0"
+			}
+		},
+		"shebang-regex": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+			"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+			"dev": true
+		},
+		"side-channel": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+			"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.0",
+				"get-intrinsic": "^1.0.2",
+				"object-inspect": "^1.9.0"
+			}
+		},
+		"slice-ansi": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+			"integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+			"dev": true,
+			"requires": {
+				"ansi-styles": "^4.0.0",
+				"astral-regex": "^2.0.0",
+				"is-fullwidth-code-point": "^3.0.0"
+			},
+			"dependencies": {
+				"ansi-styles": {
+					"version": "4.3.0",
+					"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+					"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+					"dev": true,
+					"requires": {
+						"color-convert": "^2.0.1"
+					}
+				},
+				"color-convert": {
+					"version": "2.0.1",
+					"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+					"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+					"dev": true,
+					"requires": {
+						"color-name": "~1.1.4"
+					}
+				},
+				"color-name": {
+					"version": "1.1.4",
+					"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+					"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+					"dev": true
+				}
+			}
+		},
+		"spdx-correct": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+			"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+			"dev": true,
+			"requires": {
+				"spdx-expression-parse": "^3.0.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
+		"spdx-exceptions": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+			"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+			"dev": true
+		},
+		"spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"requires": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
+		"spdx-license-ids": {
+			"version": "3.0.10",
+			"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
+			"integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+			"dev": true
+		},
+		"sprintf-js": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+			"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+			"dev": true
+		},
+		"string-width": {
+			"version": "4.2.2",
+			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+			"integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+			"dev": true,
+			"requires": {
+				"emoji-regex": "^8.0.0",
+				"is-fullwidth-code-point": "^3.0.0",
+				"strip-ansi": "^6.0.0"
+			}
+		},
+		"string.prototype.trimend": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+			"integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3"
+			}
+		},
+		"string.prototype.trimstart": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+			"integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+			"dev": true,
+			"requires": {
+				"call-bind": "^1.0.2",
+				"define-properties": "^1.1.3"
+			}
+		},
+		"strip-ansi": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+			"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+			"dev": true,
+			"requires": {
+				"ansi-regex": "^5.0.0"
+			}
+		},
+		"strip-bom": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+			"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+			"dev": true
+		},
+		"strip-json-comments": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+			"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+			"dev": true
+		},
+		"supports-color": {
+			"version": "5.5.0",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+			"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+			"dev": true,
+			"requires": {
+				"has-flag": "^3.0.0"
+			}
+		},
+		"table": {
+			"version": "6.7.1",
+			"resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
+			"integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==",
+			"dev": true,
+			"requires": {
+				"ajv": "^8.0.1",
+				"lodash.clonedeep": "^4.5.0",
+				"lodash.truncate": "^4.4.2",
+				"slice-ansi": "^4.0.0",
+				"string-width": "^4.2.0",
+				"strip-ansi": "^6.0.0"
+			},
+			"dependencies": {
+				"ajv": {
+					"version": "8.6.2",
+					"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+					"integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
+					"dev": true,
+					"requires": {
+						"fast-deep-equal": "^3.1.1",
+						"json-schema-traverse": "^1.0.0",
+						"require-from-string": "^2.0.2",
+						"uri-js": "^4.2.2"
+					}
+				},
+				"json-schema-traverse": {
+					"version": "1.0.0",
+					"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+					"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+					"dev": true
+				}
+			}
+		},
+		"text-table": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+			"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+			"dev": true
+		},
+		"tsconfig-paths": {
+			"version": "3.11.0",
+			"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
+			"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
+			"dev": true,
+			"requires": {
+				"@types/json5": "^0.0.29",
+				"json5": "^1.0.1",
+				"minimist": "^1.2.0",
+				"strip-bom": "^3.0.0"
+			}
+		},
+		"type-check": {
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+			"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+			"dev": true,
+			"requires": {
+				"prelude-ls": "^1.2.1"
+			}
+		},
+		"type-fest": {
+			"version": "0.20.2",
+			"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+			"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+			"dev": true
+		},
+		"unbox-primitive": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
+			"integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+			"dev": true,
+			"requires": {
+				"function-bind": "^1.1.1",
+				"has-bigints": "^1.0.1",
+				"has-symbols": "^1.0.2",
+				"which-boxed-primitive": "^1.0.2"
+			}
+		},
+		"uri-js": {
+			"version": "4.4.1",
+			"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+			"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+			"dev": true,
+			"requires": {
+				"punycode": "^2.1.0"
+			}
+		},
+		"v8-compile-cache": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+			"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+			"dev": true
+		},
+		"validate-npm-package-license": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+			"integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+			"dev": true,
+			"requires": {
+				"spdx-correct": "^3.0.0",
+				"spdx-expression-parse": "^3.0.0"
+			}
+		},
+		"which": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+			"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+			"dev": true,
+			"requires": {
+				"isexe": "^2.0.0"
+			}
+		},
+		"which-boxed-primitive": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+			"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+			"dev": true,
+			"requires": {
+				"is-bigint": "^1.0.1",
+				"is-boolean-object": "^1.1.0",
+				"is-number-object": "^1.0.4",
+				"is-string": "^1.0.5",
+				"is-symbol": "^1.0.3"
+			}
+		},
+		"word-wrap": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+			"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+			"dev": true
+		},
+		"wrappy": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+			"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+			"dev": true
+		},
+		"yallist": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+			"dev": true
 		}
 	}
 }

+ 18 - 6
libraries/latex-log-parser/package.json

@@ -3,14 +3,26 @@
   "version": "2.0.0",
   "description": "",
   "scripts": {
-    "lint": "echo noop",
-    "format": "echo noop",
-    "test:ci": "echo noop",
-    "test": "echo \"Error: no test specified\" && exit 1",
-    "compile": "sh ./bin/compile.sh"
+    "lint": "eslint --max-warnings 0 --format unix src || /bin/true",
+    "lint:fix": "eslint --fix src",
+    "format": "prettier --list-different $PWD/src/'**/*.js'",
+    "format:fix": "prettier --write $PWD/src/'**/*.js'",
+    "test:ci": "echo ci tests not implemented"
   },
   "author": "",
   "license": "MIT",
-  "dependencies": {
+  "dependencies": {},
+  "devDependencies": {
+    "eslint": "^7.21.0",
+    "eslint-config-prettier": "^8.1.0",
+    "eslint-config-standard": "^16.0.2",
+    "eslint-plugin-chai-expect": "^2.2.0",
+    "eslint-plugin-chai-friendly": "^0.7.2",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-mocha": "^9.0.0",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-prettier": "^3.1.2",
+    "eslint-plugin-promise": "^5.1.0",
+    "prettier": "^2.2.1"
   }
 }

+ 239 - 225
libraries/latex-log-parser/src/js/bib-log-parser.js

@@ -1,238 +1,252 @@
-define(function() {
+define(function () {
+  // [fullLine, lineNumber, messageType, message]
+  const LINE_SPLITTER_REGEX = /^\[(\d+)].*>\s(INFO|WARN|ERROR)\s-\s(.*)$/
 
-	// [fullLine, lineNumber, messageType, message]
-	const LINE_SPLITTER_REGEX = /^\[(\d+)].*>\s(INFO|WARN|ERROR)\s-\s(.*)$/;
+  const MESSAGE_LEVELS = {
+    INFO: 'info',
+    WARN: 'warning',
+    ERROR: 'error',
+  }
 
-	const MESSAGE_LEVELS = {
-		"INFO": "info",
-		"WARN": "warning",
-		"ERROR": "error"
-	};
-
-	const BibLogParser = function(text, options) {
-		if (typeof text !== 'string') {
-			throw new Error("BibLogParser Error: text parameter must be a string");
-		}
-		this.text = text.replace(/(\r\n)|\r/g, '\n');
-		this.options = options || {};
-		this.lines = text.split('\n');
-	};
+  const BibLogParser = function (text, options) {
+    if (typeof text !== 'string') {
+      throw new Error('BibLogParser Error: text parameter must be a string')
+    }
+    this.text = text.replace(/(\r\n)|\r/g, '\n')
+    this.options = options || {}
+    this.lines = text.split('\n')
+  }
 
-	const consume = function(logText, regex, process) {
-		let match;
-		let text = logText;
-		const result = [];
-		const re = regex;
-		let iterationCount = 0;
-		while ((match = re.exec(text))) {
-			iterationCount += 1;
-			const newEntry = process(match);
+  const consume = function (logText, regex, process) {
+    let match
+    let text = logText
+    const result = []
+    const re = regex
+    let iterationCount = 0
+    while ((match = re.exec(text))) {
+      iterationCount += 1
+      const newEntry = process(match)
 
-			// Too many log entries can cause browser crashes
-			// Construct a too many files error from the last match
-			var maxErrors = 100;
-			if (iterationCount >= maxErrors) {
-				var level = newEntry.level + "s";
-				newEntry.message = [
-					"Over",
-					maxErrors,
-					level,
-					"returned. Download raw logs to see full list"
-				].join(" ");
-				newEntry.line = undefined;
-				result.unshift(newEntry);
-				return [result, ""];
-			}
+      // Too many log entries can cause browser crashes
+      // Construct a too many files error from the last match
+      var maxErrors = 100
+      if (iterationCount >= maxErrors) {
+        var level = newEntry.level + 's'
+        newEntry.message = [
+          'Over',
+          maxErrors,
+          level,
+          'returned. Download raw logs to see full list',
+        ].join(' ')
+        newEntry.line = undefined
+        result.unshift(newEntry)
+        return [result, '']
+      }
 
-			result.push(newEntry);
-			text = (
-				(match.input.slice(0, match.index)) +
-				(match.input.slice(match.index+match[0].length+1, match.input.length))
-			);
-		}
-		return [result, text];
-	};
+      result.push(newEntry)
+      text =
+        match.input.slice(0, match.index) +
+        match.input.slice(match.index + match[0].length + 1, match.input.length)
+    }
+    return [result, text]
+  }
 
-	const MULTILINE_WARNING_REGEX = /^Warning--(.+)\n--line (\d+) of file (.+)$/m;
-	const SINGLELINE_WARNING_REGEX = /^Warning--(.+)$/m;
-	const MULTILINE_ERROR_REGEX = /^(.*)---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this entry$/m;
-	const BAD_CROSS_REFERENCE_REGEX = /^(A bad cross reference---entry ".+?"\nrefers to entry.+?, which doesn't exist)$/m;
-	const MULTILINE_COMMAND_ERROR_REGEX = /^(.*)\n?---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this command$/m;
-	// Errors hit in BST file have a slightly different format
-	const BST_ERROR_REGEX = /^(.*?)\nwhile executing---line (\d+) of file (.*)/m;
+  const MULTILINE_WARNING_REGEX = /^Warning--(.+)\n--line (\d+) of file (.+)$/m
+  const SINGLELINE_WARNING_REGEX = /^Warning--(.+)$/m
+  const MULTILINE_ERROR_REGEX =
+    /^(.*)---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this entry$/m
+  const BAD_CROSS_REFERENCE_REGEX =
+    /^(A bad cross reference---entry ".+?"\nrefers to entry.+?, which doesn't exist)$/m
+  const MULTILINE_COMMAND_ERROR_REGEX =
+    /^(.*)\n?---line (\d+) of file (.*)\n([^]+?)\nI'm skipping whatever remains of this command$/m
+  // Errors hit in BST file have a slightly different format
+  const BST_ERROR_REGEX = /^(.*?)\nwhile executing---line (\d+) of file (.*)/m
 
-	// each parser is a pair of [regex, processFunction], where processFunction
-	// describes how to transform the regex mactch into a log entry object.
-	const warningParsers = [
-		[
-			MULTILINE_WARNING_REGEX,
-			function(match) {
-				const [fullMatch, message, lineNumber, fileName] = match;
-				return {
-					file: fileName,
-					level: "warning",
-					message,
-					line: lineNumber,
-					raw: fullMatch
-				};
-			}
-		],
-		[
-			SINGLELINE_WARNING_REGEX,
-			function(match) {
-				const [fullMatch, message] = match;
-				return {
-					file: '',
-					level: "warning",
-					message,
-					line: '',
-					raw: fullMatch
-				};
-			}
-		]
-	];
-	const errorParsers = [
-		[
-			MULTILINE_ERROR_REGEX,
-			function(match) {
-				const [fullMatch, firstMessage, lineNumber, fileName, secondMessage] = match;
-				return {
-					file: fileName,
-					level: "error",
-					message: firstMessage + '\n' + secondMessage,
-					line: lineNumber,
-					raw: fullMatch
-				};
-			}
-		],
-		[
-			BAD_CROSS_REFERENCE_REGEX,
-			function(match) {
-				const [fullMatch, message] = match;
-				return {
-					file: '',
-					level: "error",
-					message,
-					line: '',
-					raw: fullMatch
-				};
-			}
-		],
-		[
-			MULTILINE_COMMAND_ERROR_REGEX,
-			function(match) {
-				const [fullMatch, firstMessage, lineNumber, fileName, secondMessage] = match;
-				return {
-					file: fileName,
-					level: "error",
-					message: firstMessage + '\n' + secondMessage,
-					line: lineNumber,
-					raw: fullMatch
-				};
-			}
-		],[
-			BST_ERROR_REGEX, function(match) {
-				var fileName, firstMessage, fullMatch, lineNumber, secondMessage;
-				fullMatch = match[0], firstMessage = match[1], lineNumber = match[2], fileName = match[3];
-				return {
-					file: fileName,
-					level: "error",
-					message: firstMessage,
-					line: lineNumber,
-					raw: fullMatch
-				};
-			}
-		]
-	];
+  // each parser is a pair of [regex, processFunction], where processFunction
+  // describes how to transform the regex mactch into a log entry object.
+  const warningParsers = [
+    [
+      MULTILINE_WARNING_REGEX,
+      function (match) {
+        const [fullMatch, message, lineNumber, fileName] = match
+        return {
+          file: fileName,
+          level: 'warning',
+          message,
+          line: lineNumber,
+          raw: fullMatch,
+        }
+      },
+    ],
+    [
+      SINGLELINE_WARNING_REGEX,
+      function (match) {
+        const [fullMatch, message] = match
+        return {
+          file: '',
+          level: 'warning',
+          message,
+          line: '',
+          raw: fullMatch,
+        }
+      },
+    ],
+  ]
+  const errorParsers = [
+    [
+      MULTILINE_ERROR_REGEX,
+      function (match) {
+        const [fullMatch, firstMessage, lineNumber, fileName, secondMessage] =
+          match
+        return {
+          file: fileName,
+          level: 'error',
+          message: firstMessage + '\n' + secondMessage,
+          line: lineNumber,
+          raw: fullMatch,
+        }
+      },
+    ],
+    [
+      BAD_CROSS_REFERENCE_REGEX,
+      function (match) {
+        const [fullMatch, message] = match
+        return {
+          file: '',
+          level: 'error',
+          message,
+          line: '',
+          raw: fullMatch,
+        }
+      },
+    ],
+    [
+      MULTILINE_COMMAND_ERROR_REGEX,
+      function (match) {
+        const [fullMatch, firstMessage, lineNumber, fileName, secondMessage] =
+          match
+        return {
+          file: fileName,
+          level: 'error',
+          message: firstMessage + '\n' + secondMessage,
+          line: lineNumber,
+          raw: fullMatch,
+        }
+      },
+    ],
+    [
+      BST_ERROR_REGEX,
+      function (match) {
+        var fileName, firstMessage, fullMatch, lineNumber, secondMessage
+        ;(fullMatch = match[0]),
+          (firstMessage = match[1]),
+          (lineNumber = match[2]),
+          (fileName = match[3])
+        return {
+          file: fileName,
+          level: 'error',
+          message: firstMessage,
+          line: lineNumber,
+          raw: fullMatch,
+        }
+      },
+    ],
+  ]
 
-	(function() {
-		this.parseBibtex = function() {
-			let allErrors;
-			const result = {
-				all: [],
-				errors: [],
-				warnings: [],
-				files: [],       // not used
-				typesetting: []  // not used
-			};
-			// reduce over the parsers, starting with the log text,
-			let [allWarnings, remainingText] = warningParsers.reduce(
-				function(accumulator, parser) {
-					const [currentWarnings, text] = accumulator;
-					const [regex, process] = parser;
-					const [warnings, _remainingText] = consume(text, regex, process);
-					return [currentWarnings.concat(warnings), _remainingText];
-				}
-				, [[], this.text]
-			);
-			[allErrors, remainingText] = errorParsers.reduce(
-				function(accumulator, parser) {
-					const [currentErrors, text] = accumulator;
-					const [regex, process] = parser;
-					const [errors, _remainingText] = consume(text, regex, process);
-					return [currentErrors.concat(errors), _remainingText];
-				}
-				, [[], remainingText]
-			);
-			result.warnings = allWarnings;
-			result.errors = allErrors;
-			result.all = allWarnings.concat(allErrors);
-			return result;
+  ;(function () {
+    this.parseBibtex = function () {
+      let allErrors
+      const result = {
+        all: [],
+        errors: [],
+        warnings: [],
+        files: [], // not used
+        typesetting: [], // not used
+      }
+      // reduce over the parsers, starting with the log text,
+      let [allWarnings, remainingText] = warningParsers.reduce(
+        function (accumulator, parser) {
+          const [currentWarnings, text] = accumulator
+          const [regex, process] = parser
+          const [warnings, _remainingText] = consume(text, regex, process)
+          return [currentWarnings.concat(warnings), _remainingText]
+        },
+        [[], this.text]
+      )
+      ;[allErrors, remainingText] = errorParsers.reduce(
+        function (accumulator, parser) {
+          const [currentErrors, text] = accumulator
+          const [regex, process] = parser
+          const [errors, _remainingText] = consume(text, regex, process)
+          return [currentErrors.concat(errors), _remainingText]
+        },
+        [[], remainingText]
+      )
+      result.warnings = allWarnings
+      result.errors = allErrors
+      result.all = allWarnings.concat(allErrors)
+      return result
     }
 
-		this.parseBiber = function() {
-			const result = {
-				all: [],
-				errors: [],
-				warnings: [],
-				files: [],       // not used
-				typesetting: []  // not used
-			};
-			this.lines.forEach(function(line) {
-				const match = line.match(LINE_SPLITTER_REGEX);
-				if (match) {
-					let [fullLine, lineNumber, messageType, message] = match;
-					const newEntry = {
-						file: '',
-						level: MESSAGE_LEVELS[messageType] || "INFO",
-						message,
-						line: '',
-						raw: fullLine
-					};
-					// try extract file, line-number and the 'real' message from lines like:
-					//   BibTeX subsystem: /.../original.bib_123.utf8, line 8, syntax error: it's bad
-					const lineMatch = newEntry.message.match(/^BibTeX subsystem: \/.+\/(\w+\.\w+)_.+, line (\d+), (.+)$/);
-					if (lineMatch && (lineMatch.length === 4)) {
-						let _, fileName, realMessage;
-						[_, fileName, lineNumber, realMessage] = lineMatch;
-						newEntry.file = fileName;
-						newEntry.line = lineNumber;
-						newEntry.message = realMessage;
-					}
-					result.all.push(newEntry);
-					switch (newEntry.level) {
-						case 'error': return result.errors.push(newEntry);
-						case 'warning':  return result.warnings.push(newEntry);
-					}
-				}
-			});
-			return result;
-		};
-
-		return this.parse = function() {
-			const firstLine = this.lines[0];
-			if (firstLine.match(/^.*INFO - This is Biber.*$/)) {
-				return this.parseBiber();
-			} else if (firstLine.match(/^This is BibTeX, Version.+$/)) {
-				return this.parseBibtex();
-			} else {
-				throw new Error("BibLogParser Error: cannot determine whether text is biber or bibtex output");
-			}
-		};
+    this.parseBiber = function () {
+      const result = {
+        all: [],
+        errors: [],
+        warnings: [],
+        files: [], // not used
+        typesetting: [], // not used
+      }
+      this.lines.forEach(function (line) {
+        const match = line.match(LINE_SPLITTER_REGEX)
+        if (match) {
+          let [fullLine, lineNumber, messageType, message] = match
+          const newEntry = {
+            file: '',
+            level: MESSAGE_LEVELS[messageType] || 'INFO',
+            message,
+            line: '',
+            raw: fullLine,
+          }
+          // try extract file, line-number and the 'real' message from lines like:
+          //   BibTeX subsystem: /.../original.bib_123.utf8, line 8, syntax error: it's bad
+          const lineMatch = newEntry.message.match(
+            /^BibTeX subsystem: \/.+\/(\w+\.\w+)_.+, line (\d+), (.+)$/
+          )
+          if (lineMatch && lineMatch.length === 4) {
+            let _, fileName, realMessage
+            ;[_, fileName, lineNumber, realMessage] = lineMatch
+            newEntry.file = fileName
+            newEntry.line = lineNumber
+            newEntry.message = realMessage
+          }
+          result.all.push(newEntry)
+          switch (newEntry.level) {
+            case 'error':
+              return result.errors.push(newEntry)
+            case 'warning':
+              return result.warnings.push(newEntry)
+          }
+        }
+      })
+      return result
+    }
 
-	}).call(BibLogParser.prototype);
+    return (this.parse = function () {
+      const firstLine = this.lines[0]
+      if (firstLine.match(/^.*INFO - This is Biber.*$/)) {
+        return this.parseBiber()
+      } else if (firstLine.match(/^This is BibTeX, Version.+$/)) {
+        return this.parseBibtex()
+      } else {
+        throw new Error(
+          'BibLogParser Error: cannot determine whether text is biber or bibtex output'
+        )
+      }
+    })
+  }.call(BibLogParser.prototype))
 
-	BibLogParser.parse = (text, options) => new BibLogParser(text, options).parse();
+  BibLogParser.parse = (text, options) =>
+    new BibLogParser(text, options).parse()
 
-	return BibLogParser;
-});
+  return BibLogParser
+})

+ 322 - 307
libraries/latex-log-parser/src/js/latex-log-parser.js

@@ -1,332 +1,347 @@
-define(function() {
-	// Define some constants
-	const LOG_WRAP_LIMIT = 79;
-	const LATEX_WARNING_REGEX = /^LaTeX Warning: (.*)$/;
-	const HBOX_WARNING_REGEX = /^(Over|Under)full \\(v|h)box/;
-	const PACKAGE_WARNING_REGEX = /^(Package \b.+\b Warning:.*)$/;
-	// This is used to parse the line number from common latex warnings
-	const LINES_REGEX = /lines? ([0-9]+)/;
-	// This is used to parse the package name from the package warnings
-	const PACKAGE_REGEX = /^Package (\b.+\b) Warning/;
+define(function () {
+  // Define some constants
+  const LOG_WRAP_LIMIT = 79
+  const LATEX_WARNING_REGEX = /^LaTeX Warning: (.*)$/
+  const HBOX_WARNING_REGEX = /^(Over|Under)full \\(v|h)box/
+  const PACKAGE_WARNING_REGEX = /^(Package \b.+\b Warning:.*)$/
+  // This is used to parse the line number from common latex warnings
+  const LINES_REGEX = /lines? ([0-9]+)/
+  // This is used to parse the package name from the package warnings
+  const PACKAGE_REGEX = /^Package (\b.+\b) Warning/
 
-	const LogText = function(text) {
-		this.text = text.replace(/(\r\n)|\r/g, '\n');
-		// Join any lines which look like they have wrapped.
-		const wrappedLines = this.text.split('\n');
-		this.lines = [ wrappedLines[0] ];
-		let i = 1;
-		while (i < wrappedLines.length) {
-			// If the previous line is as long as the wrap limit then
-			// append this line to it.
-			// Some lines end with ... when LaTeX knows it's hit the limit
-			// These shouldn't be wrapped.
-			if ((wrappedLines[i - 1].length === LOG_WRAP_LIMIT) && (wrappedLines[i - 1].slice(-3) !== '...')) {
-				this.lines[this.lines.length - 1] += wrappedLines[i];
-			} else {
-				this.lines.push(wrappedLines[i]);
-			}
-			i++;
-		}
-		this.row = 0;
-	};
+  const LogText = function (text) {
+    this.text = text.replace(/(\r\n)|\r/g, '\n')
+    // Join any lines which look like they have wrapped.
+    const wrappedLines = this.text.split('\n')
+    this.lines = [wrappedLines[0]]
+    let i = 1
+    while (i < wrappedLines.length) {
+      // If the previous line is as long as the wrap limit then
+      // append this line to it.
+      // Some lines end with ... when LaTeX knows it's hit the limit
+      // These shouldn't be wrapped.
+      if (
+        wrappedLines[i - 1].length === LOG_WRAP_LIMIT &&
+        wrappedLines[i - 1].slice(-3) !== '...'
+      ) {
+        this.lines[this.lines.length - 1] += wrappedLines[i]
+      } else {
+        this.lines.push(wrappedLines[i])
+      }
+      i++
+    }
+    this.row = 0
+  }
 
-	(function() {
-		this.nextLine = function() {
-			this.row++;
-			if (this.row >= this.lines.length) {
-				return false;
-			} else {
-				return this.lines[this.row];
-			}
-		};
+  ;(function () {
+    this.nextLine = function () {
+      this.row++
+      if (this.row >= this.lines.length) {
+        return false
+      } else {
+        return this.lines[this.row]
+      }
+    }
 
-		this.rewindLine = function() {
-			this.row--;
-		};
+    this.rewindLine = function () {
+      this.row--
+    }
 
-		this.linesUpToNextWhitespaceLine = function() {
-			return this.linesUpToNextMatchingLine(/^ *$/);
-		};
+    this.linesUpToNextWhitespaceLine = function () {
+      return this.linesUpToNextMatchingLine(/^ *$/)
+    }
 
-		this.linesUpToNextMatchingLine = function(match) {
-			const lines = [];
-			let nextLine = this.nextLine();
-			if (nextLine !== false) {
-				lines.push(nextLine);
-			}
-			while ((nextLine !== false) && !nextLine.match(match) && (nextLine !== false)) {
-				nextLine = this.nextLine();
-				if (nextLine !== false) {
-					lines.push(nextLine);
-				}
-			}
-			return lines;
-		};
+    this.linesUpToNextMatchingLine = function (match) {
+      const lines = []
+      let nextLine = this.nextLine()
+      if (nextLine !== false) {
+        lines.push(nextLine)
+      }
+      while (
+        nextLine !== false &&
+        !nextLine.match(match) &&
+        nextLine !== false
+      ) {
+        nextLine = this.nextLine()
+        if (nextLine !== false) {
+          lines.push(nextLine)
+        }
+      }
+      return lines
+    }
+  }.call(LogText.prototype))
 
-	}).call(LogText.prototype);
+  const state = {
+    NORMAL: 0,
+    ERROR: 1,
+  }
 
-	const state = {
-		NORMAL: 0,
-		ERROR: 1
-	};
+  const LatexParser = function (text, options) {
+    this.log = new LogText(text)
+    this.state = state.NORMAL
+    options = options || {}
+    this.fileBaseNames = options.fileBaseNames || [/compiles/, /\/usr\/local/]
+    this.ignoreDuplicates = options.ignoreDuplicates
+    this.data = []
+    this.fileStack = []
+    this.currentFileList = this.rootFileList = []
+    this.openParens = 0
+  }
 
-	const LatexParser = function(text, options) {
-		this.log = new LogText(text);
-		this.state = state.NORMAL;
-		options = options || {};
-		this.fileBaseNames = options.fileBaseNames || [
-			/compiles/,
-			/\/usr\/local/
-		];
-		this.ignoreDuplicates = options.ignoreDuplicates;
-		this.data = [];
-		this.fileStack = [];
-		this.currentFileList = (this.rootFileList = []);
-		this.openParens = 0;
-	};
+  ;(function () {
+    this.parse = function () {
+      while ((this.currentLine = this.log.nextLine()) !== false) {
+        if (this.state === state.NORMAL) {
+          if (this.currentLineIsError()) {
+            this.state = state.ERROR
+            this.currentError = {
+              line: null,
+              file: this.currentFilePath,
+              level: 'error',
+              message: this.currentLine.slice(2),
+              content: '',
+              raw: this.currentLine + '\n',
+            }
+          } else if (this.currentLineIsRunawayArgument()) {
+            this.parseRunawayArgumentError()
+          } else if (this.currentLineIsWarning()) {
+            this.parseSingleWarningLine(LATEX_WARNING_REGEX)
+          } else if (this.currentLineIsHboxWarning()) {
+            this.parseHboxLine()
+          } else if (this.currentLineIsPackageWarning()) {
+            this.parseMultipleWarningLine()
+          } else {
+            this.parseParensForFilenames()
+          }
+        }
+        if (this.state === state.ERROR) {
+          this.currentError.content += this.log
+            .linesUpToNextMatchingLine(/^l\.[0-9]+/)
+            .join('\n')
+          this.currentError.content += '\n'
+          this.currentError.content += this.log
+            .linesUpToNextWhitespaceLine()
+            .join('\n')
+          this.currentError.content += '\n'
+          this.currentError.content += this.log
+            .linesUpToNextWhitespaceLine()
+            .join('\n')
+          this.currentError.raw += this.currentError.content
+          const lineNo = this.currentError.raw.match(/l\.([0-9]+)/)
+          if (lineNo) {
+            this.currentError.line = parseInt(lineNo[1], 10)
+          }
+          this.data.push(this.currentError)
+          this.state = state.NORMAL
+        }
+      }
+      return this.postProcess(this.data)
+    }
 
-	(function() {
-		this.parse = function() {
-			while ((this.currentLine = this.log.nextLine()) !== false) {
-				if (this.state === state.NORMAL) {
-					if (this.currentLineIsError()) {
-						this.state = state.ERROR;
-						this.currentError = {
-							line: null,
-							file: this.currentFilePath,
-							level: 'error',
-							message: this.currentLine.slice(2),
-							content: '',
-							raw: this.currentLine + '\n'
-						};
-					} else if (this.currentLineIsRunawayArgument()) {
-						this.parseRunawayArgumentError();
-					} else if (this.currentLineIsWarning()) {
-						this.parseSingleWarningLine(LATEX_WARNING_REGEX);
-					} else if (this.currentLineIsHboxWarning()) {
-						this.parseHboxLine();
-					} else if (this.currentLineIsPackageWarning()) {
-						this.parseMultipleWarningLine();
-					} else {
-						this.parseParensForFilenames();
-					}
-				}
-				if (this.state === state.ERROR) {
-					this.currentError.content += this.log.linesUpToNextMatchingLine(/^l\.[0-9]+/).join('\n');
-					this.currentError.content += '\n';
-					this.currentError.content += this.log.linesUpToNextWhitespaceLine().join('\n');
-					this.currentError.content += '\n';
-					this.currentError.content += this.log.linesUpToNextWhitespaceLine().join('\n');
-					this.currentError.raw += this.currentError.content;
-					const lineNo = this.currentError.raw.match(/l\.([0-9]+)/);
-					if (lineNo) {
-						this.currentError.line = parseInt(lineNo[1], 10);
-					}
-					this.data.push(this.currentError);
-					this.state = state.NORMAL;
-				}
-			}
-			return this.postProcess(this.data);
-		};
+    this.currentLineIsError = function () {
+      return this.currentLine[0] === '!'
+    }
 
-		this.currentLineIsError = function() {
-			return this.currentLine[0] === '!';
-		};
+    this.currentLineIsRunawayArgument = function () {
+      return this.currentLine.match(/^Runaway argument/)
+    }
 
-		this.currentLineIsRunawayArgument = function() {
-			return this.currentLine.match(/^Runaway argument/);
-		};
+    this.currentLineIsWarning = function () {
+      return !!this.currentLine.match(LATEX_WARNING_REGEX)
+    }
 
-		this.currentLineIsWarning = function() {
-			return !!this.currentLine.match(LATEX_WARNING_REGEX);
-		};
+    this.currentLineIsPackageWarning = function () {
+      return !!this.currentLine.match(PACKAGE_WARNING_REGEX)
+    }
 
-		this.currentLineIsPackageWarning = function() {
-			return !!this.currentLine.match(PACKAGE_WARNING_REGEX);
-		};
+    this.currentLineIsHboxWarning = function () {
+      return !!this.currentLine.match(HBOX_WARNING_REGEX)
+    }
 
-		this.currentLineIsHboxWarning = function() {
-			return !!this.currentLine.match(HBOX_WARNING_REGEX);
-		};
+    this.parseRunawayArgumentError = function () {
+      this.currentError = {
+        line: null,
+        file: this.currentFilePath,
+        level: 'error',
+        message: this.currentLine,
+        content: '',
+        raw: this.currentLine + '\n',
+      }
+      this.currentError.content += this.log
+        .linesUpToNextWhitespaceLine()
+        .join('\n')
+      this.currentError.content += '\n'
+      this.currentError.content += this.log
+        .linesUpToNextWhitespaceLine()
+        .join('\n')
+      this.currentError.raw += this.currentError.content
+      const lineNo = this.currentError.raw.match(/l\.([0-9]+)/)
+      if (lineNo) {
+        this.currentError.line = parseInt(lineNo[1], 10)
+      }
+      return this.data.push(this.currentError)
+    }
 
-		this.parseRunawayArgumentError = function() {
-			this.currentError = {
-				line: null,
-				file: this.currentFilePath,
-				level: 'error',
-				message: this.currentLine,
-				content: '',
-				raw: this.currentLine + '\n'
-			};
-			this.currentError.content += this.log.linesUpToNextWhitespaceLine().join('\n');
-			this.currentError.content += '\n';
-			this.currentError.content += this.log.linesUpToNextWhitespaceLine().join('\n');
-			this.currentError.raw += this.currentError.content;
-			const lineNo = this.currentError.raw.match(/l\.([0-9]+)/);
-			if (lineNo) {
-				this.currentError.line = parseInt(lineNo[1], 10);
-			}
-			return this.data.push(this.currentError);
-		};
+    this.parseSingleWarningLine = function (prefix_regex) {
+      const warningMatch = this.currentLine.match(prefix_regex)
+      if (!warningMatch) {
+        return
+      }
+      const warning = warningMatch[1]
+      const lineMatch = warning.match(LINES_REGEX)
+      const line = lineMatch ? parseInt(lineMatch[1], 10) : null
+      this.data.push({
+        line,
+        file: this.currentFilePath,
+        level: 'warning',
+        message: warning,
+        raw: warning,
+      })
+    }
 
-		this.parseSingleWarningLine = function(prefix_regex) {
-			const warningMatch = this.currentLine.match(prefix_regex);
-			if (!warningMatch) {
-				return;
-			}
-			const warning = warningMatch[1];
-			const lineMatch = warning.match(LINES_REGEX);
-			const line = lineMatch ? parseInt(lineMatch[1], 10) : null;
-			this.data.push({
-				line,
-				file: this.currentFilePath,
-				level: 'warning',
-				message: warning,
-				raw: warning
-			});
-		};
+    this.parseMultipleWarningLine = function () {
+      // Some package warnings are multiple lines, let's parse the first line
+      let warningMatch = this.currentLine.match(PACKAGE_WARNING_REGEX)
+      if (!warningMatch) {
+        return
+      }
+      // Something strange happened, return early
+      const warning_lines = [warningMatch[1]]
+      let lineMatch = this.currentLine.match(LINES_REGEX)
+      let line = lineMatch ? parseInt(lineMatch[1], 10) : null
+      const packageMatch = this.currentLine.match(PACKAGE_REGEX)
+      const packageName = packageMatch[1]
+      // Regex to get rid of the unnecesary (packagename) prefix in most multi-line warnings
+      const prefixRegex = new RegExp(
+        '(?:\\(' + packageName + '\\))*[\\s]*(.*)',
+        'i'
+      )
+      // After every warning message there's a blank line, let's use it
+      while (!!(this.currentLine = this.log.nextLine())) {
+        lineMatch = this.currentLine.match(LINES_REGEX)
+        line = lineMatch ? parseInt(lineMatch[1], 10) : line
+        warningMatch = this.currentLine.match(prefixRegex)
+        warning_lines.push(warningMatch[1])
+      }
+      const raw_message = warning_lines.join(' ')
+      this.data.push({
+        line,
+        file: this.currentFilePath,
+        level: 'warning',
+        message: raw_message,
+        raw: raw_message,
+      })
+    }
 
-		this.parseMultipleWarningLine = function() {
-			// Some package warnings are multiple lines, let's parse the first line
-			let warningMatch = this.currentLine.match(PACKAGE_WARNING_REGEX);
-			if (!warningMatch) {
-				return;
-			}
-			// Something strange happened, return early
-			const warning_lines = [ warningMatch[1] ];
-			let lineMatch = this.currentLine.match(LINES_REGEX);
-			let line = lineMatch ? parseInt(lineMatch[1], 10) : null;
-			const packageMatch = this.currentLine.match(PACKAGE_REGEX);
-			const packageName = packageMatch[1];
-			// Regex to get rid of the unnecesary (packagename) prefix in most multi-line warnings
-			const prefixRegex = new RegExp('(?:\\(' + packageName + '\\))*[\\s]*(.*)', 'i');
-			// After every warning message there's a blank line, let's use it
-			while (!!(this.currentLine = this.log.nextLine())) {
-				lineMatch = this.currentLine.match(LINES_REGEX);
-				line = lineMatch ? parseInt(lineMatch[1], 10) : line;
-				warningMatch = this.currentLine.match(prefixRegex);
-				warning_lines.push(warningMatch[1]);
-			}
-			const raw_message = warning_lines.join(' ');
-			this.data.push({
-				line,
-				file: this.currentFilePath,
-				level: 'warning',
-				message: raw_message,
-				raw: raw_message
-			});
-		};
+    this.parseHboxLine = function () {
+      const lineMatch = this.currentLine.match(LINES_REGEX)
+      const line = lineMatch ? parseInt(lineMatch[1], 10) : null
+      this.data.push({
+        line,
+        file: this.currentFilePath,
+        level: 'typesetting',
+        message: this.currentLine,
+        raw: this.currentLine,
+      })
+    }
 
-		this.parseHboxLine = function() {
-			const lineMatch = this.currentLine.match(LINES_REGEX);
-			const line = lineMatch ? parseInt(lineMatch[1], 10) : null;
-			this.data.push({
-				line,
-				file: this.currentFilePath,
-				level: 'typesetting',
-				message: this.currentLine,
-				raw: this.currentLine
-			});
-		};
+    // Check if we're entering or leaving a new file in this line
 
-		// Check if we're entering or leaving a new file in this line
+    this.parseParensForFilenames = function () {
+      const pos = this.currentLine.search(/\(|\)/)
+      if (pos !== -1) {
+        const token = this.currentLine[pos]
+        this.currentLine = this.currentLine.slice(pos + 1)
+        if (token === '(') {
+          const filePath = this.consumeFilePath()
+          if (filePath) {
+            this.currentFilePath = filePath
+            const newFile = {
+              path: filePath,
+              files: [],
+            }
+            this.fileStack.push(newFile)
+            this.currentFileList.push(newFile)
+            this.currentFileList = newFile.files
+          } else {
+            this.openParens++
+          }
+        } else if (token === ')') {
+          if (this.openParens > 0) {
+            this.openParens--
+          } else {
+            if (this.fileStack.length > 1) {
+              this.fileStack.pop()
+              const previousFile = this.fileStack[this.fileStack.length - 1]
+              this.currentFilePath = previousFile.path
+              this.currentFileList = previousFile.files
+            }
+          }
+        }
+        // else {
+        //		 Something has gone wrong but all we can do now is ignore it :(
+        // }
+        // Process the rest of the line
+        this.parseParensForFilenames()
+      }
+    }
 
-		this.parseParensForFilenames = function() {
-			const pos = this.currentLine.search(/\(|\)/);
-			if (pos !== -1) {
-				const token = this.currentLine[pos];
-				this.currentLine = this.currentLine.slice(pos + 1);
-				if (token === '(') {
-					const filePath = this.consumeFilePath();
-					if (filePath) {
-						this.currentFilePath = filePath;
-						const newFile = {
-							path: filePath,
-							files: []
-						};
-						this.fileStack.push(newFile);
-						this.currentFileList.push(newFile);
-						this.currentFileList = newFile.files;
-					} else {
-						this.openParens++;
-					}
-				} else if (token === ')') {
-					if (this.openParens > 0) {
-						this.openParens--;
-					} else {
-						if (this.fileStack.length > 1) {
-							this.fileStack.pop();
-							const previousFile = this.fileStack[this.fileStack.length - 1];
-							this.currentFilePath = previousFile.path;
-							this.currentFileList = previousFile.files;
-						}
-					}
-				}
-						// else {
-						//		 Something has gone wrong but all we can do now is ignore it :(
-						// }
-				// Process the rest of the line
-				this.parseParensForFilenames();
-			}
-		};
+    this.consumeFilePath = function () {
+      // Our heuristic for detecting file names are rather crude
+      // A file may not contain a space, or ) in it
+      // To be a file path it must have at least one /
+      if (!this.currentLine.match(/^\/?([^ \)]+\/)+/)) {
+        return false
+      }
+      const endOfFilePath = this.currentLine.search(RegExp(' |\\)'))
+      let path = undefined
+      if (endOfFilePath === -1) {
+        path = this.currentLine
+        this.currentLine = ''
+      } else {
+        path = this.currentLine.slice(0, endOfFilePath)
+        this.currentLine = this.currentLine.slice(endOfFilePath)
+      }
+      return path
+    }
 
-		this.consumeFilePath = function() {
-			// Our heuristic for detecting file names are rather crude
-			// A file may not contain a space, or ) in it
-			// To be a file path it must have at least one /
-			if (!this.currentLine.match(/^\/?([^ \)]+\/)+/)) {
-				return false;
-			}
-			const endOfFilePath = this.currentLine.search(RegExp(' |\\)'));
-			let path = undefined;
-			if (endOfFilePath === -1) {
-				path = this.currentLine;
-				this.currentLine = '';
-			} else {
-				path = this.currentLine.slice(0, endOfFilePath);
-				this.currentLine = this.currentLine.slice(endOfFilePath);
-			}
-			return path;
-		};
+    this.postProcess = function (data) {
+      const all = []
+      const errors = []
+      const warnings = []
+      const typesetting = []
+      const hashes = []
 
-		this.postProcess = function(data) {
-			const all = [];
-			const errors = [];
-			const warnings = [];
-			const typesetting = [];
-			const hashes = [];
+      const hashEntry = entry => entry.raw
 
-			const hashEntry = entry => entry.raw;
+      let i = 0
+      while (i < data.length) {
+        if (this.ignoreDuplicates && hashes.indexOf(hashEntry(data[i])) > -1) {
+          i++
+          continue
+        }
+        if (data[i].level === 'error') {
+          errors.push(data[i])
+        } else if (data[i].level === 'typesetting') {
+          typesetting.push(data[i])
+        } else if (data[i].level === 'warning') {
+          warnings.push(data[i])
+        }
+        all.push(data[i])
+        hashes.push(hashEntry(data[i]))
+        i++
+      }
+      return {
+        errors,
+        warnings,
+        typesetting,
+        all,
+        files: this.rootFileList,
+      }
+    }
+  }.call(LatexParser.prototype))
 
-			let i = 0;
-			while (i < data.length) {
-				if (this.ignoreDuplicates && (hashes.indexOf(hashEntry(data[i])) > -1)) {
-					i++;
-					continue;
-				}
-				if (data[i].level === 'error') {
-					errors.push(data[i]);
-				} else if (data[i].level === 'typesetting') {
-					typesetting.push(data[i]);
-				} else if (data[i].level === 'warning') {
-					warnings.push(data[i]);
-				}
-				all.push(data[i]);
-				hashes.push(hashEntry(data[i]));
-				i++;
-			}
-			return {
-				errors,
-				warnings,
-				typesetting,
-				all,
-				files: this.rootFileList
-			};
-		};
+  LatexParser.parse = (text, options) => new LatexParser(text, options).parse()
 
-	}).call(LatexParser.prototype);
-
-	LatexParser.parse = (text, options) => new LatexParser(text, options).parse();
-
-	return LatexParser;
-});
+  return LatexParser
+})