From f4395d8a65c1dc07e9369de08de482ab041c51bc Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Tue, 14 Feb 2023 13:33:20 -0500 Subject: [PATCH 1/9] First Draft --- package-lock.json | 2077 +++++++---------- package.json | 1 + .../shared_steps/equalizerApo.ts | 4 +- src/common/constants.ts | 20 +- src/common/constants.validator.ts | 136 ++ src/common/utils.ts | 19 +- src/main/flush.ts | 19 +- src/main/main.ts | 158 +- src/renderer/MainContent.tsx | 33 +- src/renderer/components/AddSliderDivider.tsx | 21 +- src/renderer/components/FrequencyBand.tsx | 10 +- src/renderer/graph/FrequencyResponseChart.tsx | 17 +- src/renderer/utils/AquaContext.tsx | 87 +- src/renderer/utils/equalizerApi.ts | 106 +- 14 files changed, 1237 insertions(+), 1471 deletions(-) create mode 100644 src/common/constants.validator.ts diff --git a/package-lock.json b/package-lock.json index a93ab5548..b43aabc18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { + "ajv": "^8.12.0", "d3": "^7.6.1", "electron-debug": "^3.2.0", "electron-log": "^4.4.7", @@ -738,6 +739,37 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/@develar/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@develar/schema-utils/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/@develar/schema-utils/node_modules/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 + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -779,9 +811,9 @@ } }, "node_modules/@electron/universal": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.2.0.tgz", - "integrity": "sha512-eu20BwNsrMPKoe2bZ3/l9c78LclDvxg3PlVXrQf3L50NaUuW5M59gbPytI+V4z7/QMrohUHetQaU0ou+p1UG9Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz", + "integrity": "sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ==", "dev": true, "dependencies": { "@malept/cross-spawn-promise": "^1.1.0", @@ -852,6 +884,28 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/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 + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -1385,6 +1439,30 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.13", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", @@ -1733,32 +1811,54 @@ } }, "node_modules/@teamsupercell/typings-for-css-modules-loader": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.1.tgz", - "integrity": "sha512-8Dz/2awNbkrFHf3IpF8YGUPniXAZW/z7OTiosO+xucIU1+jVg/cT4uyGZ7z9cmAsnExsxq4igazxwgGBXVpUgA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.2.tgz", + "integrity": "sha512-3sqH2B4itcm5XgV1IHENt4NOaW7bOC1CwJr63vrdKWWyKVxNxtBM+ABVhJZYFCCVAwNy7ulA64z6HyQqw96m4A==", "dev": true, "dependencies": { "camelcase": "^5.3.1", - "loader-utils": "1.2.3", + "loader-utils": "^1.4.2", "schema-utils": "^2.0.1" }, "optionalDependencies": { "prettier": "*" } }, - "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "engines": { - "node": ">= 0.10" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/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 + }, "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -1768,13 +1868,13 @@ } }, "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "dependencies": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", + "emojis-list": "^3.0.0", "json5": "^1.0.1" }, "engines": { @@ -2665,9 +2765,9 @@ "dev": true }, "node_modules/@types/verror": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz", - "integrity": "sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==", + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", + "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", "dev": true, "optional": true }, @@ -3643,14 +3743,13 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { @@ -3675,46 +3774,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/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 - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -3798,45 +3857,59 @@ "dev": true }, "node_modules/app-builder-lib": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.0.3.tgz", - "integrity": "sha512-1qrtXYHXJfXhzJnMtVGjIva3067F1qYQubl2oBjI61gCBoCHvhghdYJ57XxXTQQ0VxnUhg1/Iaez87uXp8mD8w==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz", + "integrity": "sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA==", "dev": true, "dependencies": { "@develar/schema-utils": "~2.6.5", - "@electron/universal": "1.2.0", + "@electron/universal": "1.2.1", "@malept/flatpak-bundler": "^0.4.0", "7zip-bin": "~5.1.1", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.2", - "ejs": "^3.1.6", + "debug": "^4.3.4", + "ejs": "^3.1.7", "electron-osx-sign": "^0.6.0", - "electron-publish": "23.0.2", + "electron-publish": "23.6.0", "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "hosted-git-info": "^4.0.2", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", "is-ci": "^3.0.0", - "isbinaryfile": "^4.0.8", + "isbinaryfile": "^4.0.10", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "read-config-file": "6.2.0", "sanitize-filename": "^1.6.3", - "semver": "^7.3.5", + "semver": "^7.3.7", + "tar": "^6.1.11", "temp-file": "^3.4.0" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/app-builder-lib/node_modules/builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/app-builder-lib/node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -3859,6 +3932,21 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/app-builder-lib/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/app-builder-lib/node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -4085,9 +4173,10 @@ } }, "node_modules/asar": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-3.1.0.tgz", - "integrity": "sha512-vyxPxP5arcAqN4F/ebHd/HhwnAiZtwhglvdmc7BR2f0ywbVNTOpSeyhLDbGXtE/y58hv1oC75TaNIXutnsOZsQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz", + "integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==", + "deprecated": "Please use @electron/asar moving forward. There is no API change, just a package name change", "dev": true, "dependencies": { "chromium-pickle-js": "^0.2.0", @@ -4108,7 +4197,7 @@ "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, "optional": true, "engines": { @@ -4504,40 +4593,6 @@ "dev": true, "optional": true }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4677,7 +4732,7 @@ "node_modules/buffer-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", "dev": true, "engines": { "node": ">=0.4.0" @@ -4686,7 +4741,7 @@ "node_modules/buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", "dev": true }, "node_modules/buffer-from": { @@ -4696,9 +4751,9 @@ "dev": true }, "node_modules/builder-util": { - "version": "23.0.2", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.0.2.tgz", - "integrity": "sha512-HaNHL3axNW/Ms8O1mDx3I07G+ZnZ/TKSWWvorOAPau128cdt9S+lNx5ocbx8deSaHHX4WFXSZVHh3mxlaKJNgg==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz", + "integrity": "sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ==", "dev": true, "dependencies": { "@types/debug": "^4.1.6", @@ -4706,10 +4761,10 @@ "7zip-bin": "~5.1.1", "app-builder-bin": "4.0.0", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.0.0", + "builder-util-runtime": "9.1.1", "chalk": "^4.1.1", "cross-spawn": "^7.0.3", - "debug": "^4.3.2", + "debug": "^4.3.4", "fs-extra": "^10.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", @@ -4732,10 +4787,23 @@ "node": ">=12.0.0" } }, + "node_modules/builder-util/node_modules/builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/builder-util/node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -5121,7 +5189,7 @@ "node_modules/chromium-pickle-js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", "dev": true }, "node_modules/ci-info": { @@ -5264,18 +5332,6 @@ "node": ">=6" } }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -5430,7 +5486,7 @@ "node_modules/colors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", "dev": true, "engines": { "node": ">=0.1.90" @@ -5466,7 +5522,7 @@ "node_modules/compare-version": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", "dev": true, "engines": { "node": ">=0.10.0" @@ -5640,23 +5696,6 @@ "proto-list": "~1.2.1" } }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", @@ -5875,15 +5914,6 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/css": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", @@ -5971,22 +6001,6 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -5999,12 +6013,6 @@ "ajv": "^8.8.2" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/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 - }, "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -6717,9 +6725,9 @@ "dev": true }, "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true, "engines": { "node": ">=0.10" @@ -6743,15 +6751,6 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6991,7 +6990,7 @@ "node_modules/dir-compare/node_modules/commander": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==", "dev": true, "dependencies": { "graceful-readlink": ">= 1.0.0" @@ -7025,26 +7024,39 @@ } }, "node_modules/dmg-builder": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.0.3.tgz", - "integrity": "sha512-mBYrHHnSM5PC656TDE+xTGmXIuWHAGmmRfyM+dV0kP+AxtwPof4pAXNQ8COd0/exZQ4dqf72FiPS3B9G9aB5IA==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz", + "integrity": "sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA==", "dev": true, "dependencies": { - "app-builder-lib": "23.0.3", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "app-builder-lib": "23.6.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "fs-extra": "^10.0.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { - "dmg-license": "^1.0.9" + "dmg-license": "^1.0.11" + } + }, + "node_modules/dmg-builder/node_modules/builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" } }, "node_modules/dmg-builder/node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -7080,7 +7092,6 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "deprecated": "Disk image license agreements are deprecated by Apple and will probably be removed in a future macOS release. Discussion at: https://github.com/argv-minus-one/dmg-license/issues/11", "dev": true, "optional": true, "os": [ @@ -7103,6 +7114,30 @@ "node": ">=8" } }, + "node_modules/dmg-license/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/dmg-license/node_modules/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, + "optional": true + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -7225,18 +7260,6 @@ "tslib": "^2.0.3" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dotenv": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", @@ -7302,9 +7325,9 @@ } }, "node_modules/electron": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-18.2.3.tgz", - "integrity": "sha512-DJWX03hCRKTscsfXxmW4gmgFuseop+g+m4ml7NfOMfankD8uYyr2Xyi3Ui02inL9qZOlbLMeLVCu6jKCKs8p/w==", + "version": "18.3.15", + "resolved": "https://registry.npmjs.org/electron/-/electron-18.3.15.tgz", + "integrity": "sha512-frkBt8skyo8SmlG4TbByDxZw6/tqttRYYIBaeTBfkoG18OyD59IVwVaXXHO8UYKB5/1C2Rce0Gj6uoxlAHQHzQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -7320,23 +7343,23 @@ } }, "node_modules/electron-builder": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.0.3.tgz", - "integrity": "sha512-0lnTsljAgcOMuIiOjPcoFf+WxOOe/O04hZPgIvvUBXIbz3kolbNu0Xdch1f5WuQ40NdeZI7oqs8Eo395PcuGHQ==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz", + "integrity": "sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw==", "dev": true, "dependencies": { "@types/yargs": "^17.0.1", - "app-builder-lib": "23.0.3", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "app-builder-lib": "23.6.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "chalk": "^4.1.1", - "dmg-builder": "23.0.3", + "dmg-builder": "23.6.0", "fs-extra": "^10.0.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", "read-config-file": "6.2.0", - "update-notifier": "^5.1.0", - "yargs": "^17.0.1" + "simple-update-notifier": "^1.0.7", + "yargs": "^17.5.1" }, "bin": { "electron-builder": "cli.js", @@ -7346,6 +7369,33 @@ "node": ">=14.0.0" } }, + "node_modules/electron-builder/node_modules/builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/electron-builder/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/electron-builder/node_modules/fs-extra": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", @@ -7382,27 +7432,27 @@ } }, "node_modules/electron-builder/node_modules/yargs": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.0.tgz", - "integrity": "sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/electron-builder/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { "node": ">=12" @@ -7563,6 +7613,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz", "integrity": "sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg==", + "deprecated": "Please use @electron/osx-sign moving forward. Be aware the API is slightly different", "dev": true, "dependencies": { "bluebird": "^3.5.0", @@ -7604,28 +7655,41 @@ "node_modules/electron-osx-sign/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "node_modules/electron-publish": { - "version": "23.0.2", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.0.2.tgz", - "integrity": "sha512-8gMYgWqv96lc83FCm85wd+tEyxNTJQK7WKyPkNkO8GxModZqt1GO8S+/vAnFGxilS/7vsrVRXFfqiCDUCSuxEg==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz", + "integrity": "sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg==", "dev": true, "dependencies": { "@types/fs-extra": "^9.0.11", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "chalk": "^4.1.1", "fs-extra": "^10.0.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, + "node_modules/electron-publish/node_modules/builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/electron-publish/node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -7864,9 +7928,9 @@ } }, "node_modules/electron-rebuild/node_modules/got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, "dependencies": { "@sindresorhus/is": "^4.0.0", @@ -8418,15 +8482,6 @@ "node": ">=6" } }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -9443,6 +9498,22 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -9456,6 +9527,12 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/node_modules/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 + }, "node_modules/espree": { "version": "9.3.2", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", @@ -10023,8 +10100,7 @@ "node_modules/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 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.2.0", @@ -10168,9 +10244,9 @@ } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10584,30 +10660,6 @@ "node": ">=10.0" } }, - "node_modules/global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/global-tunnel-ng": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", @@ -10705,7 +10757,7 @@ "node_modules/graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, "node_modules/grapheme-splitter": { @@ -10874,15 +10926,6 @@ "node": ">=0.10.0" } }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -11021,9 +11064,9 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "node_modules/http-deceiver": { @@ -11300,15 +11343,6 @@ "node": ">=8" } }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -11371,7 +11405,8 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "optional": true }, "node_modules/internal-slot": { "version": "1.0.3", @@ -11626,22 +11661,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -11669,18 +11688,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -11705,24 +11712,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -11874,12 +11863,6 @@ "node": ">=8" } }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -15592,10 +15575,9 @@ "dev": true }, "node_modules/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 + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -15611,9 +15593,9 @@ "optional": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -15729,18 +15711,6 @@ "language-subtag-registry": "~0.3.2" } }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", @@ -16036,9 +16006,9 @@ } }, "node_modules/loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "dependencies": { "big.js": "^5.2.2", @@ -16594,22 +16564,6 @@ "webpack": "^5.0.0" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -16622,12 +16576,6 @@ "ajv": "^8.8.2" } }, - "node_modules/mini-css-extract-plugin/node_modules/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 - }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -17597,30 +17545,6 @@ "node": ">=6" } }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -17869,27 +17793,18 @@ } }, "node_modules/plist": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz", - "integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", + "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", "dev": true, "dependencies": { "base64-js": "^1.5.1", - "xmlbuilder": "^9.0.7" + "xmlbuilder": "^15.1.1" }, "engines": { "node": ">=6" } }, - "node_modules/plist/node_modules/xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -18643,23 +18558,10 @@ "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, "engines": { "node": ">=6" } }, - "node_modules/pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "dependencies": { - "escape-goat": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/puppeteer-core": { "version": "13.7.0", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.7.0.tgz", @@ -18849,30 +18751,6 @@ "node": ">=0.10.0" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react/-/react-18.1.0.tgz", @@ -19204,30 +19082,6 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -19287,7 +19141,6 @@ "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, "engines": { "node": ">=0.10.0" } @@ -19961,6 +19814,37 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/schema-utils/node_modules/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 + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -20000,27 +19884,6 @@ "dev": true, "optional": true }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/semver/node_modules/lru-cache": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", @@ -20316,6 +20179,27 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/sirv": { "version": "1.0.19", "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", @@ -21312,9 +21196,9 @@ } }, "node_modules/temp-file/node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -21363,14 +21247,14 @@ } }, "node_modules/terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.16.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", + "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", "dev": true, "dependencies": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "bin": { @@ -21649,7 +21533,7 @@ "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "dev": true, "dependencies": { "utf8-byte-length": "^1.0.1" @@ -21795,9 +21679,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -21927,9 +21811,9 @@ } }, "node_modules/ua-parser-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", - "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==", + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", + "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==", "dev": true, "funding": [ { @@ -22023,18 +21907,6 @@ "imurmurhash": "^0.1.4" } }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -22136,57 +22008,10 @@ "yaku": "^0.16.6" } }, - "node_modules/update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "dependencies": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/update-notifier/node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -22249,7 +22074,7 @@ "node_modules/utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", "dev": true }, "node_modules/util-deprecate": { @@ -22345,7 +22170,7 @@ "node_modules/verror/node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true, "optional": true }, @@ -22923,22 +22748,6 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -22951,12 +22760,6 @@ "ajv": "^8.8.2" } }, - "node_modules/webpack-dev-middleware/node_modules/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 - }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -23026,22 +22829,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/webpack-dev-server/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -23054,12 +22841,6 @@ "ajv": "^8.8.2" } }, - "node_modules/webpack-dev-server/node_modules/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 - }, "node_modules/webpack-dev-server/node_modules/schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -23238,18 +23019,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -23321,15 +23090,6 @@ } } }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -23344,7 +23104,6 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true, - "optional": true, "engines": { "node": ">=8.0" } @@ -23964,6 +23723,33 @@ "requires": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" + }, + "dependencies": { + "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" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "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 + } } }, "@discoveryjs/json-ext": { @@ -23998,9 +23784,9 @@ } }, "@electron/universal": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.2.0.tgz", - "integrity": "sha512-eu20BwNsrMPKoe2bZ3/l9c78LclDvxg3PlVXrQf3L50NaUuW5M59gbPytI+V4z7/QMrohUHetQaU0ou+p1UG9Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.2.1.tgz", + "integrity": "sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ==", "dev": true, "requires": { "@malept/cross-spawn-promise": "^1.1.0", @@ -24057,6 +23843,26 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "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" + } + }, + "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 + } } }, "@gar/promisify": { @@ -24485,6 +24291,29 @@ "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", "dev": true }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, "@jridgewell/sourcemap-codec": { "version": "1.4.13", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", @@ -24750,40 +24579,59 @@ } }, "@teamsupercell/typings-for-css-modules-loader": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.1.tgz", - "integrity": "sha512-8Dz/2awNbkrFHf3IpF8YGUPniXAZW/z7OTiosO+xucIU1+jVg/cT4uyGZ7z9cmAsnExsxq4igazxwgGBXVpUgA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.2.tgz", + "integrity": "sha512-3sqH2B4itcm5XgV1IHENt4NOaW7bOC1CwJr63vrdKWWyKVxNxtBM+ABVhJZYFCCVAwNy7ulA64z6HyQqw96m4A==", "dev": true, "requires": { "camelcase": "^5.3.1", - "loader-utils": "1.2.3", + "loader-utils": "^1.4.2", "prettier": "*", "schema-utils": "^2.0.1" }, "dependencies": { - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "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" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "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 }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", + "emojis-list": "^3.0.0", "json5": "^1.0.1" } }, @@ -25637,9 +25485,9 @@ "dev": true }, "@types/verror": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz", - "integrity": "sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==", + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", + "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", "dev": true, "optional": true }, @@ -26360,14 +26208,13 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, @@ -26378,42 +26225,6 @@ "dev": true, "requires": { "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "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 - } - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" } }, "ansi-escapes": { @@ -26471,42 +26282,53 @@ "dev": true }, "app-builder-lib": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.0.3.tgz", - "integrity": "sha512-1qrtXYHXJfXhzJnMtVGjIva3067F1qYQubl2oBjI61gCBoCHvhghdYJ57XxXTQQ0VxnUhg1/Iaez87uXp8mD8w==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-23.6.0.tgz", + "integrity": "sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA==", "dev": true, "requires": { "@develar/schema-utils": "~2.6.5", - "@electron/universal": "1.2.0", + "@electron/universal": "1.2.1", "@malept/flatpak-bundler": "^0.4.0", "7zip-bin": "~5.1.1", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.2", - "ejs": "^3.1.6", + "debug": "^4.3.4", + "ejs": "^3.1.7", "electron-osx-sign": "^0.6.0", - "electron-publish": "23.0.2", + "electron-publish": "23.6.0", "form-data": "^4.0.0", - "fs-extra": "^10.0.0", - "hosted-git-info": "^4.0.2", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", "is-ci": "^3.0.0", - "isbinaryfile": "^4.0.8", + "isbinaryfile": "^4.0.10", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "read-config-file": "6.2.0", "sanitize-filename": "^1.6.3", - "semver": "^7.3.5", + "semver": "^7.3.7", + "tar": "^6.1.11", "temp-file": "^3.4.0" }, "dependencies": { + "builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -26524,6 +26346,15 @@ "universalify": "^2.0.0" } }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -26702,9 +26533,9 @@ } }, "asar": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-3.1.0.tgz", - "integrity": "sha512-vyxPxP5arcAqN4F/ebHd/HhwnAiZtwhglvdmc7BR2f0ywbVNTOpSeyhLDbGXtE/y58hv1oC75TaNIXutnsOZsQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz", + "integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==", "dev": true, "requires": { "@types/glob": "^7.1.1", @@ -26717,7 +26548,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, "optional": true }, @@ -27038,30 +26869,6 @@ "dev": true, "optional": true }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -27160,13 +26967,13 @@ "buffer-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", "dev": true }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", "dev": true }, "buffer-from": { @@ -27176,9 +26983,9 @@ "dev": true }, "builder-util": { - "version": "23.0.2", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.0.2.tgz", - "integrity": "sha512-HaNHL3axNW/Ms8O1mDx3I07G+ZnZ/TKSWWvorOAPau128cdt9S+lNx5ocbx8deSaHHX4WFXSZVHh3mxlaKJNgg==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.6.0.tgz", + "integrity": "sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ==", "dev": true, "requires": { "@types/debug": "^4.1.6", @@ -27186,10 +26993,10 @@ "7zip-bin": "~5.1.1", "app-builder-bin": "4.0.0", "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.0.0", + "builder-util-runtime": "9.1.1", "chalk": "^4.1.1", "cross-spawn": "^7.0.3", - "debug": "^4.3.2", + "debug": "^4.3.4", "fs-extra": "^10.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", @@ -27200,10 +27007,20 @@ "temp-file": "^3.4.0" }, "dependencies": { + "builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -27499,7 +27316,7 @@ "chromium-pickle-js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", "dev": true }, "ci-info": { @@ -27617,12 +27434,6 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -27743,7 +27554,7 @@ "colors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==", "dev": true }, "combined-stream": { @@ -27770,7 +27581,7 @@ "compare-version": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", "dev": true }, "component-emitter": { @@ -27919,20 +27730,6 @@ "proto-list": "~1.2.1" } }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, "confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", @@ -28092,12 +27889,6 @@ "which": "^2.0.1" } }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, "css": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", @@ -28154,18 +27945,6 @@ "source-map": "^0.6.1" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "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" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -28175,12 +27954,6 @@ "fast-deep-equal": "^3.1.3" } }, - "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 - }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -28700,9 +28473,9 @@ "dev": true }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true }, "decompress-response": { @@ -28720,12 +28493,6 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -28918,7 +28685,7 @@ "commander": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "integrity": "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==", "dev": true, "requires": { "graceful-readlink": ">= 1.0.0" @@ -28945,24 +28712,34 @@ } }, "dmg-builder": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.0.3.tgz", - "integrity": "sha512-mBYrHHnSM5PC656TDE+xTGmXIuWHAGmmRfyM+dV0kP+AxtwPof4pAXNQ8COd0/exZQ4dqf72FiPS3B9G9aB5IA==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-23.6.0.tgz", + "integrity": "sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA==", "dev": true, "requires": { - "app-builder-lib": "23.0.3", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", - "dmg-license": "^1.0.9", + "app-builder-lib": "23.6.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", + "dmg-license": "^1.0.11", "fs-extra": "^10.0.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "dependencies": { + "builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -29003,6 +28780,28 @@ "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "optional": 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" + } + }, + "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, + "optional": true + } } }, "dns-equal": { @@ -29100,15 +28899,6 @@ "tslib": "^2.0.3" } }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, "dotenv": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", @@ -29165,9 +28955,9 @@ } }, "electron": { - "version": "18.2.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-18.2.3.tgz", - "integrity": "sha512-DJWX03hCRKTscsfXxmW4gmgFuseop+g+m4ml7NfOMfankD8uYyr2Xyi3Ui02inL9qZOlbLMeLVCu6jKCKs8p/w==", + "version": "18.3.15", + "resolved": "https://registry.npmjs.org/electron/-/electron-18.3.15.tgz", + "integrity": "sha512-frkBt8skyo8SmlG4TbByDxZw6/tqttRYYIBaeTBfkoG18OyD59IVwVaXXHO8UYKB5/1C2Rce0Gj6uoxlAHQHzQ==", "dev": true, "requires": { "@electron/get": "^1.13.0", @@ -29184,25 +28974,46 @@ } }, "electron-builder": { - "version": "23.0.3", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.0.3.tgz", - "integrity": "sha512-0lnTsljAgcOMuIiOjPcoFf+WxOOe/O04hZPgIvvUBXIbz3kolbNu0Xdch1f5WuQ40NdeZI7oqs8Eo395PcuGHQ==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-23.6.0.tgz", + "integrity": "sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw==", "dev": true, "requires": { "@types/yargs": "^17.0.1", - "app-builder-lib": "23.0.3", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "app-builder-lib": "23.6.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "chalk": "^4.1.1", - "dmg-builder": "23.0.3", + "dmg-builder": "23.6.0", "fs-extra": "^10.0.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", "read-config-file": "6.2.0", - "update-notifier": "^5.1.0", - "yargs": "^17.0.1" + "simple-update-notifier": "^1.0.7", + "yargs": "^17.5.1" }, "dependencies": { + "builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, "fs-extra": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", @@ -29231,24 +29042,24 @@ "dev": true }, "yargs": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.0.tgz", - "integrity": "sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } @@ -29408,30 +29219,40 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, "electron-publish": { - "version": "23.0.2", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.0.2.tgz", - "integrity": "sha512-8gMYgWqv96lc83FCm85wd+tEyxNTJQK7WKyPkNkO8GxModZqt1GO8S+/vAnFGxilS/7vsrVRXFfqiCDUCSuxEg==", + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-23.6.0.tgz", + "integrity": "sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg==", "dev": true, "requires": { "@types/fs-extra": "^9.0.11", - "builder-util": "23.0.2", - "builder-util-runtime": "9.0.0", + "builder-util": "23.6.0", + "builder-util-runtime": "9.1.1", "chalk": "^4.1.1", "fs-extra": "^10.0.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" }, "dependencies": { + "builder-util-runtime": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz", + "integrity": "sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -29606,9 +29427,9 @@ } }, "got": { - "version": "11.8.3", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", - "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, "requires": { "@sindresorhus/is": "^4.0.0", @@ -30036,12 +29857,6 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -30158,6 +29973,18 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "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" + } + }, "eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -30167,6 +29994,12 @@ "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } + }, + "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 } } }, @@ -31221,8 +31054,7 @@ "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 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-diff": { "version": "1.2.0", @@ -31346,9 +31178,9 @@ } }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -31663,23 +31495,6 @@ "serialize-error": "^7.0.1" } }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - } - } - }, "global-tunnel-ng": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", @@ -31753,7 +31568,7 @@ "graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, "grapheme-splitter": { @@ -31884,12 +31699,6 @@ } } }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -31995,9 +31804,9 @@ } }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "http-deceiver": { @@ -32192,12 +32001,6 @@ } } }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -32245,7 +32048,8 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "optional": true }, "internal-slot": { "version": "1.0.3", @@ -32425,16 +32229,6 @@ "is-extglob": "^2.1.1" } }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, "is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -32453,12 +32247,6 @@ "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, - "is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true - }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -32474,18 +32262,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, "is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -32586,12 +32362,6 @@ "is-docker": "^2.0.0" } }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -35539,10 +35309,9 @@ "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 + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -35558,9 +35327,9 @@ "optional": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonfile": { @@ -35652,15 +35421,6 @@ "language-subtag-registry": "~0.3.2" } }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, "lazy-val": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", @@ -35873,9 +35633,9 @@ "dev": true }, "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -36310,18 +36070,6 @@ "schema-utils": "^4.0.0" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "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" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -36331,12 +36079,6 @@ "fast-deep-equal": "^3.1.3" } }, - "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 - }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -37074,26 +36816,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -37281,21 +37003,13 @@ } }, "plist": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz", - "integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", + "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", "dev": true, "requires": { "base64-js": "^1.5.1", - "xmlbuilder": "^9.0.7" - }, - "dependencies": { - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true - } + "xmlbuilder": "^15.1.1" } }, "posix-character-classes": { @@ -37809,17 +37523,7 @@ "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 - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "requires": { - "escape-goat": "^2.0.0" - } + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer-core": { "version": "13.7.0", @@ -37945,26 +37649,6 @@ } } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - } - } - }, "react": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/react/-/react-18.1.0.tgz", @@ -38223,24 +37907,6 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -38287,8 +37953,7 @@ "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 + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", @@ -38799,6 +38464,33 @@ "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" + }, + "dependencies": { + "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" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "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 + } } }, "select-hose": { @@ -38838,23 +38530,6 @@ "dev": true, "optional": true }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "send": { "version": "0.17.2", "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", @@ -39098,6 +38773,23 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, "sirv": { "version": "1.0.19", "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", @@ -39905,9 +39597,9 @@ }, "dependencies": { "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -39944,14 +39636,14 @@ } }, "terser": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz", - "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==", + "version": "5.16.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", + "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", "dev": true, "requires": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "dependencies": { @@ -40169,7 +39861,7 @@ "truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", "dev": true, "requires": { "utf8-byte-length": "^1.0.1" @@ -40257,9 +39949,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -40356,9 +40048,9 @@ "dev": true }, "ua-parser-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", - "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==", + "version": "1.0.33", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", + "integrity": "sha512-RqshF7TPTE0XLYAqmjlu5cLLuGdKrNu9O1KLA/qp39QtbZwuzwv1dT46DZSopoUMsYgXpB3Cv8a03FI8b74oFQ==", "dev": true }, "uid": { @@ -40429,15 +40121,6 @@ "imurmurhash": "^0.1.4" } }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -40521,50 +40204,10 @@ "yaku": "^0.16.6" } }, - "update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "requires": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - } - } - }, "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" } @@ -40604,7 +40247,7 @@ "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", "dev": true }, "util-deprecate": { @@ -40685,7 +40328,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true, "optional": true } @@ -41132,18 +40775,6 @@ "schema-utils": "^4.0.0" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "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" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -41153,12 +40784,6 @@ "fast-deep-equal": "^3.1.3" } }, - "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 - }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -41209,18 +40834,6 @@ "ws": "^8.4.2" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "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" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -41230,12 +40843,6 @@ "fast-deep-equal": "^3.1.3" } }, - "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 - }, "schema-utils": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", @@ -41352,15 +40959,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -41409,12 +41007,6 @@ "dev": true, "requires": {} }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, "xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -41425,8 +41017,7 @@ "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "optional": true + "dev": true }, "xmlchars": { "version": "2.2.0", diff --git a/package.json b/package.json index 19d5e3d8d..16500c2bc 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,7 @@ ] }, "dependencies": { + "ajv": "^8.12.0", "d3": "^7.6.1", "electron-debug": "^3.2.0", "electron-log": "^4.4.7", diff --git a/src/__tests__/cucumber_tests/shared_steps/equalizerApo.ts b/src/__tests__/cucumber_tests/shared_steps/equalizerApo.ts index efb396ca7..8141cea17 100644 --- a/src/__tests__/cucumber_tests/shared_steps/equalizerApo.ts +++ b/src/__tests__/cucumber_tests/shared_steps/equalizerApo.ts @@ -1,5 +1,5 @@ import { DefineStepFunction } from 'jest-cucumber'; -import { IState } from 'common/constants'; +import { getDefaultFilterWithId, IState } from 'common/constants'; import { flush } from 'main/flush'; import { getConfigPath, isEqualizerAPOInstalled } from 'main/registry'; @@ -19,7 +19,7 @@ export const givenCanWriteToAquaConfig = (given: DefineStepFunction) => { isAutoPreAmpOn: false, isGraphViewOn: false, preAmp: 0, - filters: [], + filters: { unique_id: getDefaultFilterWithId() }, }; const configDirPath = await getConfigPath(); flush(emptyState, configDirPath); diff --git a/src/common/constants.ts b/src/common/constants.ts index ae0536a56..0c8ae3a8e 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -54,6 +54,10 @@ export const FILTER_REGEX = new RegExp( /** ----- Application Interfaces ----- */ +export interface Filters { + [key: string]: IFilter; +} // key is the same id as whats in IFilter + export interface IFilter { id: string; frequency: number; @@ -67,12 +71,12 @@ export interface IState { isAutoPreAmpOn: boolean; isGraphViewOn: boolean; preAmp: number; - filters: IFilter[]; + filters: Filters; } export interface IPreset { preAmp: number; - filters: IFilter[]; + filters: Filters; } /** ----- Default Values ----- */ @@ -88,17 +92,21 @@ const DEFAULT_FILTER_TEMPLATE = { type: FilterTypeEnum.PK, }; -export const getDefaultFilter = () => { +export const getDefaultFilterWithId = (): IFilter => { return { id: uid(8), ...DEFAULT_FILTER_TEMPLATE, }; }; -const getDefaultFilters = (): IFilter[] => - FIXED_FREQUENCIES.map((f) => { - return { ...getDefaultFilter(), frequency: f }; +const getDefaultFilters = (): Filters => { + const filters: Filters = {}; + FIXED_FREQUENCIES.forEach((f) => { + const filter: IFilter = { ...getDefaultFilterWithId(), frequency: f }; + filters[filter.id] = filter; }); + return filters; +}; export const getDefaultState = (): IState => { return { diff --git a/src/common/constants.validator.ts b/src/common/constants.validator.ts new file mode 100644 index 000000000..988191f40 --- /dev/null +++ b/src/common/constants.validator.ts @@ -0,0 +1,136 @@ +// Heavily modified from the validator generated from @rkesters/typescript-json-validator +const Ajv = require('ajv'); + +export const ajv = new Ajv({ + allErrors: true, + coerceTypes: false, + removeAdditional: false, + strict: false, + strictNumbers: false, + strictRequired: false, + strictSchema: false, + strictTuples: false, + strictTypes: false, + useDefaults: true, +}); +ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json')); + +const IStateSchema = { + $schema: 'http://json-schema.org/draft-07/schema#', + defaultProperties: [], + definitions: { + FilterTypeEnum: { + enum: ['HSC', 'LSC', 'PK'], + type: 'string', + }, + Filters: { + additionalProperties: { + $ref: '#/definitions/IFilter', + }, + defaultProperties: [], + description: '----- Application Interfaces -----', + type: 'object', + }, + IFilter: { + defaultProperties: [], + properties: { + frequency: { + type: 'number', + }, + gain: { + type: 'number', + }, + id: { + type: 'string', + }, + quality: { + type: 'number', + }, + type: { + $ref: '#/definitions/FilterTypeEnum', + }, + }, + required: ['frequency', 'gain', 'id', 'quality', 'type'], + type: 'object', + }, + }, + properties: { + filters: { + $ref: '#/definitions/Filters', + }, + isAutoPreAmpOn: { + type: 'boolean', + }, + isEnabled: { + type: 'boolean', + }, + isGraphViewOn: { + type: 'boolean', + }, + preAmp: { + type: 'number', + }, + }, + required: [ + 'filters', + 'isAutoPreAmpOn', + 'isEnabled', + 'isGraphViewOn', + 'preAmp', + ], + type: 'object', +}; + +const IPresetSchema = { + $schema: 'http://json-schema.org/draft-07/schema#', + defaultProperties: [], + definitions: { + FilterTypeEnum: { + enum: ['HSC', 'LSC', 'PK'], + type: 'string', + }, + Filters: { + additionalProperties: { + $ref: '#/definitions/IFilter', + }, + defaultProperties: [], + description: '----- Application Interfaces -----', + type: 'object', + }, + IFilter: { + defaultProperties: [], + properties: { + frequency: { + type: 'number', + }, + gain: { + type: 'number', + }, + id: { + type: 'string', + }, + quality: { + type: 'number', + }, + type: { + $ref: '#/definitions/FilterTypeEnum', + }, + }, + required: ['frequency', 'gain', 'id', 'quality', 'type'], + type: 'object', + }, + }, + properties: { + filters: { + $ref: '#/definitions/Filters', + }, + preAmp: { + type: 'number', + }, + }, + required: ['filters', 'preAmp'], + type: 'object', +}; + +export const validateState = ajv.compile(IStateSchema); +export const validatePreset = ajv.compile(IPresetSchema); diff --git a/src/common/utils.ts b/src/common/utils.ts index f26ab4930..837204ea1 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -1,4 +1,5 @@ import { + Filters, IFilter, MAX_FREQUENCY, MIN_FREQUENCY, @@ -10,10 +11,12 @@ export const roundToPrecision = (value: number, precision: number) => { return Math.round(value * precisionFactor) / precisionFactor; }; -export const computeAvgFreq = (filters: IFilter[], index: number) => { - const lo = index === 0 ? MIN_FREQUENCY : filters[index - 1].frequency; - const hi = - index === filters.length ? MAX_FREQUENCY : filters[index].frequency; +export const computeAvgFreq = ( + leftFilter: IFilter | null, + rightFilter: IFilter | null +) => { + const lo = leftFilter ? leftFilter.frequency : MIN_FREQUENCY; + const hi = rightFilter ? rightFilter.frequency : MAX_FREQUENCY; const exponent = (Math.log10(lo) + Math.log10(hi)) / 2; return roundToPrecision(10 ** exponent, 0); }; @@ -23,3 +26,11 @@ export const computeAvgFreq = (filters: IFilter[], index: number) => { // have manually confirmed this. export const isRestrictedPresetName = (newName: string) => RESERVED_FILE_NAMES_SET.has(newName.toUpperCase()); + +export const cloneFilters = (filters: Filters) => { + const filtersClone: Filters = {}; + Object.entries(filters).forEach(([id, filter]) => { + filtersClone[id] = filter; + }); + return filtersClone; +}; diff --git a/src/main/flush.ts b/src/main/flush.ts index 9ef8c41d9..9273cdb4d 100644 --- a/src/main/flush.ts +++ b/src/main/flush.ts @@ -6,6 +6,7 @@ import { IState, PRESETS_DIR, } from '../common/constants'; +import { validatePreset, validateState } from '../common/constants.validator'; export const stateToString = (state: IState) => { if (!state.isEnabled) { @@ -21,9 +22,10 @@ export const stateToString = (state: IState) => { // Using individual filter bands output = output.concat( - state.filters.flatMap( - ({ frequency, gain, type, quality }, index) => - `Filter${index}: ON ${type} Fc ${frequency} Hz Gain ${gain} dB Q ${quality}` + Object.values(state.filters).map( + ({ frequency, gain, type, quality }, index) => { + return `Filter${index}: ON ${type} Fc ${frequency} Hz Gain ${gain} dB Q ${quality}`; + } ) ); @@ -55,8 +57,13 @@ export const fetchSettings = () => { const content = fs.readFileSync(AQUA_LOCAL_CONFIG_FILENAME, { encoding: 'utf8', }); - return JSON.parse(content) as IState; + const input = JSON.parse(content); + if (!validateState(input)) { + throw new Error('Invalid state file loaded. Using default state.'); + } + return input as IState; } catch (ex) { + console.log(ex); // if unable to fetch the state, use a default one return getDefaultState(); } @@ -79,9 +86,13 @@ export const fetchPreset = (presetName: string) => { const content = fs.readFileSync(presetPath, { encoding: 'utf8', }); + if (!validatePreset(content)) { + throw new Error('Invalid preset file'); + } return JSON.parse(content) as IPreset; } catch (ex) { console.log('Failed to get presets!!'); + console.log(ex); throw ex; } }; diff --git a/src/main/main.ts b/src/main/main.ts index 105c0bc8c..48ab104b9 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -46,11 +46,11 @@ import { WINDOW_HEIGHT_EXPANDED, WINDOW_WIDTH, PRESETS_DIR, + getDefaultFilterWithId, } from '../common/constants'; import { ErrorCode } from '../common/errors'; -import { computeAvgFreq, isRestrictedPresetName } from '../common/utils'; +import { isRestrictedPresetName } from '../common/utils'; import { TSuccess, TError } from '../renderer/utils/equalizerApi'; -import { sortHelper } from '../renderer/utils/utils'; import { getAutoEqDeviceList, getAutoEqPreset, @@ -199,6 +199,19 @@ const handleUpdate = async ( return handleUpdateHelper(event, channel, undefined); }; +const checkFilterIdExistence = ( + event: Electron.IpcMainEvent, + channel: ChannelEnum, + filterId: string +) => { + // Filter id must exist + if (!(filterId in state.filters)) { + handleError(event, channel + filterId, ErrorCode.INVALID_PARAMETER); + return false; + } + return true; +}; + ipcMain.on(ChannelEnum.HEALTH_CHECK, async (event) => { const channel = ChannelEnum.HEALTH_CHECK; const res = await updateConfigPath(event, channel); @@ -369,8 +382,8 @@ ipcMain.on(ChannelEnum.GET_ENABLE, async (event) => { }); ipcMain.on(ChannelEnum.SET_ENABLE, async (event, arg) => { - const value = parseInt(arg[0], 10) || 0; - state.isEnabled = value !== 0; + // eslint-disable-next-line prefer-destructuring + state.isEnabled = arg[0]; await handleUpdate(event, ChannelEnum.SET_ENABLE); }); @@ -406,197 +419,188 @@ ipcMain.on(ChannelEnum.SET_PREAMP, async (event, arg) => { ipcMain.on(ChannelEnum.GET_FILTER_GAIN, async (event, arg) => { const channel = ChannelEnum.GET_FILTER_GAIN; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } const reply: TSuccess = { - result: state.filters[filterIndex].gain || 0, + result: state.filters[filterId].gain || 0, }; - event.reply(channel + filterIndex, reply); + event.reply(channel + filterId, reply); }); ipcMain.on(ChannelEnum.SET_FILTER_GAIN, async (event, arg) => { const channel = ChannelEnum.SET_FILTER_GAIN; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; const gain = parseFloat(arg[1]) || 0; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } if (gain < MIN_GAIN || gain > MAX_GAIN) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + handleError(event, channel + filterId, ErrorCode.INVALID_PARAMETER); return; } - state.filters[filterIndex].gain = gain; - await handleUpdate(event, channel + filterIndex); + state.filters[filterId].gain = gain; + await handleUpdate(event, channel + filterId); }); ipcMain.on(ChannelEnum.GET_FILTER_FREQUENCY, async (event, arg) => { const channel = ChannelEnum.GET_FILTER_FREQUENCY; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } const reply: TSuccess = { - result: state.filters[filterIndex].frequency || 10, + result: state.filters[filterId].frequency || 10, }; - event.reply(channel + filterIndex, reply); + event.reply(channel + filterId, reply); }); ipcMain.on(ChannelEnum.SET_FILTER_FREQUENCY, async (event, arg) => { const channel = ChannelEnum.SET_FILTER_FREQUENCY; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; const frequency = parseInt(arg[1], 10) || 0; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } if (frequency < MIN_FREQUENCY || frequency > MAX_FREQUENCY) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + handleError(event, channel + filterId, ErrorCode.INVALID_PARAMETER); return; } - state.filters[filterIndex].frequency = frequency; - state.filters.sort(sortHelper); - await handleUpdate(event, channel + filterIndex); + state.filters[filterId].frequency = frequency; + await handleUpdate(event, channel + filterId); }); ipcMain.on(ChannelEnum.GET_FILTER_QUALITY, async (event, arg) => { const channel = ChannelEnum.GET_FILTER_QUALITY; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } const reply: TSuccess = { - result: state.filters[filterIndex].quality || 10, + result: state.filters[filterId].quality || 10, }; - event.reply(channel + filterIndex, reply); + event.reply(channel + filterId, reply); }); ipcMain.on(ChannelEnum.SET_FILTER_QUALITY, async (event, arg) => { const channel = ChannelEnum.SET_FILTER_QUALITY; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; const quality = parseFloat(arg[1]) || 0; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } if (quality < MIN_QUALITY || quality > MAX_QUALITY) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + handleError(event, channel + filterId, ErrorCode.INVALID_PARAMETER); return; } - state.filters[filterIndex].quality = quality; - await handleUpdate(event, channel + filterIndex); + state.filters[filterId].quality = quality; + await handleUpdate(event, channel + filterId); }); ipcMain.on(ChannelEnum.GET_FILTER_TYPE, async (event, arg) => { const channel = ChannelEnum.GET_FILTER_TYPE; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } const reply: TSuccess = { - result: state.filters[filterIndex].type, + result: state.filters[filterId].type, }; - event.reply(channel + filterIndex, reply); + event.reply(channel + filterId, reply); }); ipcMain.on(ChannelEnum.SET_FILTER_TYPE, async (event, arg) => { const channel = ChannelEnum.SET_FILTER_TYPE; - const filterIndex = parseInt(arg[0], 10) || 0; + const filterId = arg[0]; const filterType = arg[1]; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } if (!Object.values(FilterTypeEnum).includes(filterType)) { - handleError(event, channel + filterIndex, ErrorCode.INVALID_PARAMETER); + handleError(event, channel + filterId, ErrorCode.INVALID_PARAMETER); return; } - state.filters[filterIndex].type = filterType as FilterTypeEnum; - await handleUpdate(event, channel + filterIndex); + state.filters[filterId].type = filterType as FilterTypeEnum; + await handleUpdate(event, channel + filterId); }); ipcMain.on(ChannelEnum.GET_FILTER_COUNT, async (event) => { const reply: TSuccess = { - result: state.filters.length, + result: Object.keys(state.filters).length, }; event.reply(ChannelEnum.GET_FILTER_COUNT, reply); }); ipcMain.on(ChannelEnum.ADD_FILTER, async (event, arg) => { const channel = ChannelEnum.ADD_FILTER; - const insertIndex: number = arg[0]; + const frequency: number = arg[0]; // Cannot exceed the maximum number of filters - if (state.filters.length === MAX_NUM_FILTERS) { + // Frequency must be in valid range + if ( + Object.keys(state.filters).length === MAX_NUM_FILTERS || + frequency < MIN_FREQUENCY || + frequency > MAX_FREQUENCY + ) { handleError(event, channel, ErrorCode.INVALID_PARAMETER); return; } - const frequency = computeAvgFreq(state.filters, insertIndex); const filterId = uid(8); - state.filters - .splice(insertIndex, 0, { - id: filterId, - frequency, - gain: 0, - quality: 1, - type: FilterTypeEnum.PK, - }) - .sort(sortHelper); + state.filters[filterId] = { + ...getDefaultFilterWithId(), + id: filterId, + frequency, + }; await handleUpdateHelper(event, channel, filterId); }); ipcMain.on(ChannelEnum.REMOVE_FILTER, async (event, arg) => { const channel = ChannelEnum.REMOVE_FILTER; - const filterIndex: number = arg[0]; + const filterId: string = arg[0]; - // Filter index must be within the length of the filters array - if (filterIndex < 0 || filterIndex >= state.filters.length) { + // Cannot fall below the minimum number of filters + if (Object.keys(state.filters).length === MIN_NUM_FILTERS) { handleError(event, channel, ErrorCode.INVALID_PARAMETER); return; } - // Cannot fall below the minimum number of filters - if (state.filters.length === MIN_NUM_FILTERS) { - handleError(event, channel, ErrorCode.INVALID_PARAMETER); + // Filter id must exist + if (!checkFilterIdExistence(event, channel, filterId)) { return; } - state.filters.splice(filterIndex, 1); + // delete does not throw exception even if the filterId does not exist + delete state.filters[filterId]; await handleUpdate(event, channel); }); diff --git a/src/renderer/MainContent.tsx b/src/renderer/MainContent.tsx index 39d03cb7b..5b11ddf89 100644 --- a/src/renderer/MainContent.tsx +++ b/src/renderer/MainContent.tsx @@ -1,5 +1,6 @@ import { Fragment, useMemo } from 'react'; import { MAX_NUM_FILTERS, MIN_NUM_FILTERS } from 'common/constants'; +import { computeAvgFreq } from 'common/utils'; import FrequencyBand from './components/FrequencyBand'; import { useAquaContext } from './utils/AquaContext'; import './styles/MainContent.scss'; @@ -7,26 +8,35 @@ import AddSliderDivider from './components/AddSliderDivider'; import Spinner from './icons/Spinner'; const MainContent = () => { - const { filters: freqSortedFilters, isLoading } = useAquaContext(); + const { filters, isLoading } = useAquaContext(); // Store widths for AddSliderDividers and FrequencyBands so we can manually position them const DIVIDER_WIDTH = 28; const BAND_WIDTH = 72.94; - const [idSortedFilters, sortIndexMap] = useMemo(() => { + const [idSortedFilters, freqSortedFilters, sortIndexMap] = useMemo(() => { // Obtain a fixed order list of the filters - const fixedSort = freqSortedFilters - .slice() - .sort((a, b) => a.id.localeCompare(b.id)); + const fixedSort = Object.values(filters).sort((a, b) => + a.id.localeCompare(b.id) + ); + + // Obtain a visually sorted list of the filters + const visualSort = Object.values(filters).sort( + (a, b) => + a.frequency - b.frequency || + a.gain - b.gain || + a.quality - b.quality || + a.type.localeCompare(b.type) + ); // Compute a mapping from a filter id to its sorted index const map: { [key: string]: number } = {}; - freqSortedFilters.forEach((f, index) => { + Object.values(visualSort).forEach((f, index) => { map[f.id] = index; }); - return [fixedSort, map]; - }, [freqSortedFilters]); + return [fixedSort, visualSort, map]; + }, [filters]); return isLoading ? (
@@ -51,7 +61,7 @@ const MainContent = () => {
= MAX_NUM_FILTERS} /> {idSortedFilters.map((filter) => { @@ -70,7 +80,10 @@ const MainContent = () => { }} /> = MAX_NUM_FILTERS} // Manually position the divider style={{ diff --git a/src/renderer/components/AddSliderDivider.tsx b/src/renderer/components/AddSliderDivider.tsx index 5c579a99f..4036c5c99 100644 --- a/src/renderer/components/AddSliderDivider.tsx +++ b/src/renderer/components/AddSliderDivider.tsx @@ -6,13 +6,13 @@ import { FilterActionEnum, useAquaContext } from '../utils/AquaContext'; import '../styles/AddSliderDivider.scss'; interface IAddSliderDividerProps { - sliderIndex: number; + newSliderFrequency: number; isMaxSliderCount: boolean; style?: CSSProperties; } const AddSliderDivider = ({ - sliderIndex, + newSliderFrequency, isMaxSliderCount, style, }: IAddSliderDividerProps) => { @@ -24,18 +24,18 @@ const AddSliderDivider = ({ [isLoading, isMaxSliderCount] ); - const onAddEqualizerSlider = async (insertIndex: number) => { + const onAddEqualizerSlider = async (sliderFrequency: number) => { if (isAddDisabled) { return; } setIsLoading(true); try { - const filterId = await addEqualizerSlider(insertIndex); + const filterId = await addEqualizerSlider(sliderFrequency); dispatchFilter({ type: FilterActionEnum.ADD, id: filterId, - index: insertIndex, + frequency: sliderFrequency, }); } catch (e) { setGlobalError(e as ErrorDescription); @@ -44,12 +44,9 @@ const AddSliderDivider = ({ setIsLoading(false); }; - const handleKeyUp = ( - e: KeyboardEvent, - insertIndex: number - ) => { + const handleKeyUp = (e: KeyboardEvent) => { if (e.code === 'Enter') { - onAddEqualizerSlider(insertIndex); + onAddEqualizerSlider(newSliderFrequency); } }; @@ -58,8 +55,8 @@ const AddSliderDivider = ({ role="button" ref={ref} className="col center addFilter" - onClick={() => onAddEqualizerSlider(sliderIndex + 1)} - onKeyUp={(e) => handleKeyUp(e, sliderIndex + 1)} + onClick={() => onAddEqualizerSlider(newSliderFrequency)} + onKeyUp={(e) => handleKeyUp(e)} tabIndex={0} aria-disabled={isAddDisabled} style={style} diff --git a/src/renderer/components/FrequencyBand.tsx b/src/renderer/components/FrequencyBand.tsx index 0c95d7c9b..312d5226b 100644 --- a/src/renderer/components/FrequencyBand.tsx +++ b/src/renderer/components/FrequencyBand.tsx @@ -75,7 +75,7 @@ const FrequencyBand = forwardRef( id: filter.id, newValue, }); - await setGain(sliderIndex, newValue); + await setGain(filter.id, newValue); }, [dispatchFilter, filter.id, sliderIndex] ); @@ -92,7 +92,7 @@ const FrequencyBand = forwardRef( id: filter.id, newValue, }); - await setQuality(sliderIndex, newValue); + await setQuality(filter.id, newValue); }, [dispatchFilter, filter.id, sliderIndex] ); @@ -116,7 +116,7 @@ const FrequencyBand = forwardRef( const handleFrequencySubmit = async (newValue: number) => { try { - await setFrequency(sliderIndex, newValue); + await setFrequency(filter.id, newValue); dispatchFilter({ type: FilterActionEnum.FREQUENCY, id: filter.id, @@ -137,7 +137,7 @@ const FrequencyBand = forwardRef( const handleFilterTypeSubmit = async (newValue: string) => { try { - await setType(sliderIndex, newValue); + await setType(filter.id, newValue); dispatchFilter({ type: FilterActionEnum.TYPE, id: filter.id, @@ -155,7 +155,7 @@ const FrequencyBand = forwardRef( setIsLoading(true); try { - await removeEqualizerSlider(sliderIndex); + await removeEqualizerSlider(filter.id); dispatchFilter({ type: FilterActionEnum.REMOVE, id: filter.id }); } catch (e) { setGlobalError(e as ErrorDescription); diff --git a/src/renderer/graph/FrequencyResponseChart.tsx b/src/renderer/graph/FrequencyResponseChart.tsx index a9d5f6540..1e7cb51e3 100644 --- a/src/renderer/graph/FrequencyResponseChart.tsx +++ b/src/renderer/graph/FrequencyResponseChart.tsx @@ -1,4 +1,4 @@ -import { IFilter } from 'common/constants'; +import { Filters, IFilter } from 'common/constants'; import { useCallback, useEffect, @@ -47,22 +47,16 @@ const FrequencyResponseChart = () => { preAmp, setPreAmp, } = useAquaContext(); - const prevFilters = useRef([]); + const prevFilters = useRef({}); const prevFilterLines = useRef({}); const { chartData, autoPreAmpValue }: IGraphData = useMemo(() => { const controlPointByCurveId: { [id: string]: IChartPointData } = {}; - // Identify the index of each filter by id from previous render - const prevIndices: { [id: string]: number } = {}; - prevFilters.current.forEach((f, i) => { - prevIndices[f.id] = i; - }); - const updatedFilterLines: IChartLineDataPointsById = {}; // Update filter lines that have changed - filters.forEach((filter) => { + Object.values(filters).forEach((filter) => { // Store control point info controlPointByCurveId[filter.id] = { x: filter.frequency, @@ -70,14 +64,13 @@ const FrequencyResponseChart = () => { }; // New filters have no previous data - const prevIndex = prevIndices[filter.id]; - if (!prevIndex) { + if (!prevFilters.current[filter.id]) { updatedFilterLines[filter.id] = getFilterLineData(filter); return; } // Recompute filter line if it has been adjusted - if (!isFilterEqual(filter, prevFilters.current[prevIndex])) { + if (!isFilterEqual(filter, prevFilters.current[filter.id])) { updatedFilterLines[filter.id] = getFilterLineData(filter); } else { // Otherwise, reuse previous data diff --git a/src/renderer/utils/AquaContext.tsx b/src/renderer/utils/AquaContext.tsx index 449932ec9..97404c12f 100644 --- a/src/renderer/utils/AquaContext.tsx +++ b/src/renderer/utils/AquaContext.tsx @@ -7,18 +7,16 @@ import { useReducer, useState, } from 'react'; -import { uid } from 'uid'; import { FilterTypeEnum, - getDefaultFilter, + getDefaultFilterWithId, getDefaultState, - IFilter, + Filters, IState, } from '../../common/constants'; import { ErrorDescription } from '../../common/errors'; -import { computeAvgFreq } from '../../common/utils'; +import { cloneFilters } from '../../common/utils'; import { getEqualizerState } from './equalizerApi'; -import { sortHelper } from './utils'; export enum FilterActionEnum { INIT, @@ -36,10 +34,10 @@ type NumericalFilterAction = | FilterActionEnum.QUALITY; export type FilterAction = - | { type: FilterActionEnum.INIT; filters: IFilter[] } + | { type: FilterActionEnum.INIT; filters: Filters } | { type: NumericalFilterAction; id: string; newValue: number } | { type: FilterActionEnum.TYPE; id: string; newValue: FilterTypeEnum } - | { type: FilterActionEnum.ADD; id: string; index: number } + | { type: FilterActionEnum.ADD; id: string; frequency: number } | { type: FilterActionEnum.REMOVE; id: string }; type FilterDispatch = (action: FilterAction) => void; @@ -58,49 +56,50 @@ export interface IAquaContext extends IState { const AquaContext = createContext(undefined); -type IFilterReducer = (filters: IFilter[], action: FilterAction) => IFilter[]; +type IFilterReducer = (filters: Filters, action: FilterAction) => Filters; const filterReducer: IFilterReducer = ( - filters: IFilter[], + filters: Filters, action: FilterAction ) => { switch (action.type) { case FilterActionEnum.INIT: - // Keeping the check for the id for backwards compatibility - // TODO: Remove the id check once this is no longer a concern - return action.filters - .map((filter) => (filter.id ? filter : { ...filter, id: uid(8) })) - .sort(sortHelper); - case FilterActionEnum.FREQUENCY: - return filters - .map((f) => - f.id === action.id ? { ...f, frequency: action.newValue } : f - ) - .sort(sortHelper); - case FilterActionEnum.GAIN: - return filters.map((f) => - f.id === action.id ? { ...f, gain: action.newValue } : f - ); - case FilterActionEnum.QUALITY: - return filters.map((f) => - f.id === action.id ? { ...f, quality: action.newValue } : f - ); - case FilterActionEnum.TYPE: - return filters.map((f) => - f.id === action.id ? { ...f, type: action.newValue } : f - ); - case FilterActionEnum.ADD: - return [ - ...filters.slice(0, action.index), - { - ...getDefaultFilter(), - id: action.id, - frequency: computeAvgFreq(filters, action.index), - }, - ...filters.slice(action.index), - ].sort(sortHelper); - case FilterActionEnum.REMOVE: - return filters.filter(({ id }) => id !== action.id); + return action.filters; + case FilterActionEnum.FREQUENCY: { + const filtersCloned = cloneFilters(filters); + filtersCloned[action.id].frequency = action.newValue; + return filtersCloned; + } + case FilterActionEnum.GAIN: { + const filtersCloned = cloneFilters(filters); + console.log(filters); + filtersCloned[action.id].gain = action.newValue; + return filtersCloned; + } + case FilterActionEnum.QUALITY: { + const filtersCloned = cloneFilters(filters); + filtersCloned[action.id].quality = action.newValue; + return filtersCloned; + } + case FilterActionEnum.TYPE: { + const filtersCloned = cloneFilters(filters); + filtersCloned[action.id].type = action.newValue; + return filtersCloned; + } + case FilterActionEnum.ADD: { + const filtersCloned = cloneFilters(filters); + filtersCloned[action.id] = { + ...getDefaultFilterWithId(), + id: action.id, + frequency: action.frequency, + }; + return filtersCloned; + } + case FilterActionEnum.REMOVE: { + const filtersCloned = cloneFilters(filters); + delete filtersCloned[action.id]; + return filtersCloned; + } default: // This throw does not actually do anything because // we are in a reducer diff --git a/src/renderer/utils/equalizerApi.ts b/src/renderer/utils/equalizerApi.ts index 1be37d991..7bede1214 100644 --- a/src/renderer/utils/equalizerApi.ts +++ b/src/renderer/utils/equalizerApi.ts @@ -196,13 +196,25 @@ export const getEqualizerState = (): Promise => { return promisifyResult(simpleResponseHandler(), channel); }; +/** + * Get the current equalizer status + * @deprecated - Removing with the context refactor + * @returns { Promise } true for on, false for off, exception otherwise + */ +export const getEqualizerStatus = (): Promise => { + const channel = ChannelEnum.GET_ENABLE; + window.electron.ipcRenderer.sendMessage(channel, []); + + return promisifyResult(simpleResponseHandler(), channel); +}; + /** * Enable Equalizer * @returns { Promise } exception if failed. */ export const enableEqualizer = (): Promise => { const channel = ChannelEnum.SET_ENABLE; - window.electron.ipcRenderer.sendMessage(channel, [1]); + window.electron.ipcRenderer.sendMessage(channel, [true]); return promisifyResult(setterResponseHandler, channel); }; @@ -212,7 +224,7 @@ export const enableEqualizer = (): Promise => { */ export const disableEqualizer = (): Promise => { const channel = ChannelEnum.SET_ENABLE; - window.electron.ipcRenderer.sendMessage(channel, [0]); + window.electron.ipcRenderer.sendMessage(channel, [false]); return promisifyResult(setterResponseHandler, channel); }; @@ -256,18 +268,6 @@ export const disableGraphView = (): Promise => { return promisifyResult(setterResponseHandler, channel); }; -/** - * Get the current equalizer status - * @deprecated - Removing with the context refactor - * @returns { Promise } true for on, false for off, exception otherwise - */ -export const getEqualizerStatus = (): Promise => { - const channel = ChannelEnum.GET_ENABLE; - window.electron.ipcRenderer.sendMessage(channel, []); - - return promisifyResult(simpleResponseHandler(), channel); -}; - /** * Get the current main preamplification gain value * @deprecated - Removing with the context refactor @@ -297,111 +297,111 @@ export const setMainPreAmp = (gain: number) => { /** * Get the a slider's gain value * @deprecated - Removing with the context refactor - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @returns { Promise } gain - current system gain value in the range [-30, 30] */ -export const getGain = (index: number): Promise => { +export const getGain = (filterId: string): Promise => { const channel = ChannelEnum.GET_FILTER_GAIN; - window.electron.ipcRenderer.sendMessage(channel, [index]); - return promisifyResult(simpleResponseHandler(), channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId]); + return promisifyResult(simpleResponseHandler(), channel + filterId); }; /** * Adjusts a slider's gain value - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @param {number} gain - new gain value in [-30, 30] */ -export const setGain = (index: number, gain: number) => { +export const setGain = (filterId: string, gain: number) => { const channel = ChannelEnum.SET_FILTER_GAIN; if (gain > MAX_GAIN || gain < MIN_GAIN) { throw new Error( `Invalid gain value - outside of range [${MIN_GAIN}, ${MAX_GAIN}]` ); } - window.electron.ipcRenderer.sendMessage(channel, [index, gain]); - return promisifyResult(setterResponseHandler, channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId, gain]); + return promisifyResult(setterResponseHandler, channel + filterId); }; /** * Get a slider's frequency * @deprecated - Removing with the context refactor - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @returns { Promise } frequency - frequency value in the range [0, 20000] */ -export const getFrequency = (index: number): Promise => { +export const getFrequency = (filterId: string): Promise => { const channel = ChannelEnum.GET_FILTER_FREQUENCY; - window.electron.ipcRenderer.sendMessage(channel, [index]); - return promisifyResult(simpleResponseHandler(), channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId]); + return promisifyResult(simpleResponseHandler(), channel + filterId); }; /** * Adjusts a slider's frequency - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @param {frequency} frequency - new frequency value in [0, 20000] */ -export const setFrequency = (index: number, frequency: number) => { +export const setFrequency = (filterId: string, frequency: number) => { const channel = ChannelEnum.SET_FILTER_FREQUENCY; if (frequency < MIN_FREQUENCY || frequency > MAX_FREQUENCY) { throw new Error( `Invalid gain value - outside of range (${MIN_FREQUENCY}, ${MAX_FREQUENCY}]` ); } - window.electron.ipcRenderer.sendMessage(channel, [index, frequency]); - return promisifyResult(setterResponseHandler, channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId, frequency]); + return promisifyResult(setterResponseHandler, channel + filterId); }; /** * Get a slider's quality * @deprecated - Removing with the context refactor - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @returns { Promise } quality - value in the range [0.001, 999.999] */ -export const getQuality = (index: number): Promise => { +export const getQuality = (filterId: string): Promise => { const channel = ChannelEnum.GET_FILTER_QUALITY; - window.electron.ipcRenderer.sendMessage(channel, [index]); - return promisifyResult(simpleResponseHandler(), channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId]); + return promisifyResult(simpleResponseHandler(), channel + filterId); }; /** * Adjusts a slider's quality - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @param {number} quality - new quality value in [0.001, 999.999] */ -export const setQuality = (index: number, quality: number) => { +export const setQuality = (filterId: string, quality: number) => { const channel = ChannelEnum.SET_FILTER_QUALITY; if (quality < MIN_QUALITY || quality > MAX_QUALITY) { throw new Error( `Invalid quality value - outside of range [${MIN_QUALITY}, ${MAX_QUALITY}]` ); } - window.electron.ipcRenderer.sendMessage(channel, [index, quality]); - return promisifyResult(setterResponseHandler, channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId, quality]); + return promisifyResult(setterResponseHandler, channel + filterId); }; /** - * Get a slider's quality + * Get a slider's filter type * @deprecated - Removing with the context refactor - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @returns { Promise } filter type - value in FilterTypeEnum */ -export const getType = (index: number): Promise => { +export const getType = (filterId: string): Promise => { const channel = ChannelEnum.GET_FILTER_TYPE; - window.electron.ipcRenderer.sendMessage(channel, [index]); + window.electron.ipcRenderer.sendMessage(channel, [filterId]); return promisifyResult( simpleResponseHandler(), - channel + index + channel + filterId ); }; /** * Adjusts a slider's quality - * @param {number} index - index of the slider being adjusted + * @param {string} filterId - id of the slider being adjusted * @param {string} filterType - new filter type */ -export const setType = (index: number, filterType: string) => { +export const setType = (filterId: string, filterType: string) => { const channel = ChannelEnum.SET_FILTER_TYPE; - window.electron.ipcRenderer.sendMessage(channel, [index, filterType]); - return promisifyResult(setterResponseHandler, channel + index); + window.electron.ipcRenderer.sendMessage(channel, [filterId, filterType]); + return promisifyResult(setterResponseHandler, channel + filterId); }; /** @@ -417,21 +417,23 @@ export const getEqualizerSliderCount = (): Promise => { /** * Add another slider + * @param {number} frequency - frequency of the new slider * @returns { Promise } exception if failed */ -export const addEqualizerSlider = (index: number): Promise => { +export const addEqualizerSlider = (frequency: number): Promise => { const channel = ChannelEnum.ADD_FILTER; - window.electron.ipcRenderer.sendMessage(channel, [index]); + window.electron.ipcRenderer.sendMessage(channel, [frequency]); return promisifyResult(simpleResponseHandler(), channel); }; /** - * Remove rightmost slider + * Remove slider + * @param {string} filterId - id of the slider to be removed * @returns { Promise } exception if failed */ -export const removeEqualizerSlider = (index: number): Promise => { +export const removeEqualizerSlider = (filterId: string): Promise => { const channel = ChannelEnum.REMOVE_FILTER; - window.electron.ipcRenderer.sendMessage(channel, [index]); + window.electron.ipcRenderer.sendMessage(channel, [filterId]); return promisifyResult(setterResponseHandler, channel); }; From fdbe7bf2b39ce214d602c400aa7e922d43e63950 Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Wed, 15 Feb 2023 21:09:16 -0500 Subject: [PATCH 2/9] Address PR Comments --- src/common/constants.ts | 10 +++--- src/common/utils.ts | 8 ++--- src/main/main.ts | 32 ++++++++----------- src/renderer/MainContent.tsx | 9 ++---- src/renderer/graph/FrequencyResponseChart.tsx | 6 ++-- src/renderer/utils/AquaContext.tsx | 12 ++++--- src/renderer/utils/utils.ts | 6 +++- 7 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/common/constants.ts b/src/common/constants.ts index 0c8ae3a8e..b9bc8f1ad 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -54,7 +54,7 @@ export const FILTER_REGEX = new RegExp( /** ----- Application Interfaces ----- */ -export interface Filters { +export interface IFiltersMap { [key: string]: IFilter; } // key is the same id as whats in IFilter @@ -71,12 +71,12 @@ export interface IState { isAutoPreAmpOn: boolean; isGraphViewOn: boolean; preAmp: number; - filters: Filters; + filters: IFiltersMap; } export interface IPreset { preAmp: number; - filters: Filters; + filters: IFiltersMap; } /** ----- Default Values ----- */ @@ -99,8 +99,8 @@ export const getDefaultFilterWithId = (): IFilter => { }; }; -const getDefaultFilters = (): Filters => { - const filters: Filters = {}; +const getDefaultFilters = (): IFiltersMap => { + const filters: IFiltersMap = {}; FIXED_FREQUENCIES.forEach((f) => { const filter: IFilter = { ...getDefaultFilterWithId(), frequency: f }; filters[filter.id] = filter; diff --git a/src/common/utils.ts b/src/common/utils.ts index 837204ea1..2565eaa65 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -1,5 +1,5 @@ import { - Filters, + IFiltersMap, IFilter, MAX_FREQUENCY, MIN_FREQUENCY, @@ -27,10 +27,10 @@ export const computeAvgFreq = ( export const isRestrictedPresetName = (newName: string) => RESERVED_FILE_NAMES_SET.has(newName.toUpperCase()); -export const cloneFilters = (filters: Filters) => { - const filtersClone: Filters = {}; +export const cloneFilters = (filters: IFiltersMap) => { + const filtersClone: IFiltersMap = {}; Object.entries(filters).forEach(([id, filter]) => { - filtersClone[id] = filter; + filtersClone[id] = { ...filter }; }); return filtersClone; }; diff --git a/src/main/main.ts b/src/main/main.ts index 48ab104b9..68b945301 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -12,7 +12,6 @@ import { app, BrowserWindow, ipcMain, shell } from 'electron'; import log from 'electron-log'; import { autoUpdater } from 'electron-updater'; import path from 'path'; -import { uid } from 'uid'; import fs from 'fs'; import { exec } from 'child_process'; import { @@ -34,6 +33,7 @@ import { FilterTypeEnum, IState, IPreset, + IFilter, MAX_FREQUENCY, MAX_GAIN, MAX_NUM_FILTERS, @@ -199,7 +199,7 @@ const handleUpdate = async ( return handleUpdateHelper(event, channel, undefined); }; -const checkFilterIdExistence = ( +const doesFilterIdExist = ( event: Electron.IpcMainEvent, channel: ChannelEnum, filterId: string @@ -422,7 +422,7 @@ ipcMain.on(ChannelEnum.GET_FILTER_GAIN, async (event, arg) => { const filterId = arg[0]; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -438,7 +438,7 @@ ipcMain.on(ChannelEnum.SET_FILTER_GAIN, async (event, arg) => { const gain = parseFloat(arg[1]) || 0; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -456,7 +456,7 @@ ipcMain.on(ChannelEnum.GET_FILTER_FREQUENCY, async (event, arg) => { const filterId = arg[0]; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -472,7 +472,7 @@ ipcMain.on(ChannelEnum.SET_FILTER_FREQUENCY, async (event, arg) => { const frequency = parseInt(arg[1], 10) || 0; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -490,7 +490,7 @@ ipcMain.on(ChannelEnum.GET_FILTER_QUALITY, async (event, arg) => { const filterId = arg[0]; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -506,7 +506,7 @@ ipcMain.on(ChannelEnum.SET_FILTER_QUALITY, async (event, arg) => { const quality = parseFloat(arg[1]) || 0; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -524,7 +524,7 @@ ipcMain.on(ChannelEnum.GET_FILTER_TYPE, async (event, arg) => { const filterId = arg[0]; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -540,7 +540,7 @@ ipcMain.on(ChannelEnum.SET_FILTER_TYPE, async (event, arg) => { const filterType = arg[1]; // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } @@ -575,13 +575,9 @@ ipcMain.on(ChannelEnum.ADD_FILTER, async (event, arg) => { return; } - const filterId = uid(8); - state.filters[filterId] = { - ...getDefaultFilterWithId(), - id: filterId, - frequency, - }; - await handleUpdateHelper(event, channel, filterId); + const newFilter: IFilter = { ...getDefaultFilterWithId(), frequency }; + state.filters[newFilter.id] = newFilter; + await handleUpdateHelper(event, channel, newFilter.id); }); ipcMain.on(ChannelEnum.REMOVE_FILTER, async (event, arg) => { @@ -595,7 +591,7 @@ ipcMain.on(ChannelEnum.REMOVE_FILTER, async (event, arg) => { } // Filter id must exist - if (!checkFilterIdExistence(event, channel, filterId)) { + if (!doesFilterIdExist(event, channel, filterId)) { return; } diff --git a/src/renderer/MainContent.tsx b/src/renderer/MainContent.tsx index 5b11ddf89..6c136cdd1 100644 --- a/src/renderer/MainContent.tsx +++ b/src/renderer/MainContent.tsx @@ -6,6 +6,7 @@ import { useAquaContext } from './utils/AquaContext'; import './styles/MainContent.scss'; import AddSliderDivider from './components/AddSliderDivider'; import Spinner from './icons/Spinner'; +import { sortHelper } from './utils/utils'; const MainContent = () => { const { filters, isLoading } = useAquaContext(); @@ -21,13 +22,7 @@ const MainContent = () => { ); // Obtain a visually sorted list of the filters - const visualSort = Object.values(filters).sort( - (a, b) => - a.frequency - b.frequency || - a.gain - b.gain || - a.quality - b.quality || - a.type.localeCompare(b.type) - ); + const visualSort = Object.values(filters).sort(sortHelper); // Compute a mapping from a filter id to its sorted index const map: { [key: string]: number } = {}; diff --git a/src/renderer/graph/FrequencyResponseChart.tsx b/src/renderer/graph/FrequencyResponseChart.tsx index 1e7cb51e3..01a295be3 100644 --- a/src/renderer/graph/FrequencyResponseChart.tsx +++ b/src/renderer/graph/FrequencyResponseChart.tsx @@ -1,4 +1,4 @@ -import { Filters, IFilter } from 'common/constants'; +import { IFiltersMap, IFilter } from 'common/constants'; import { useCallback, useEffect, @@ -47,7 +47,7 @@ const FrequencyResponseChart = () => { preAmp, setPreAmp, } = useAquaContext(); - const prevFilters = useRef({}); + const prevFilters = useRef({}); const prevFilterLines = useRef({}); const { chartData, autoPreAmpValue }: IGraphData = useMemo(() => { @@ -64,7 +64,7 @@ const FrequencyResponseChart = () => { }; // New filters have no previous data - if (!prevFilters.current[filter.id]) { + if (!(filter.id in prevFilters.current)) { updatedFilterLines[filter.id] = getFilterLineData(filter); return; } diff --git a/src/renderer/utils/AquaContext.tsx b/src/renderer/utils/AquaContext.tsx index 97404c12f..7dd987b4b 100644 --- a/src/renderer/utils/AquaContext.tsx +++ b/src/renderer/utils/AquaContext.tsx @@ -11,7 +11,7 @@ import { FilterTypeEnum, getDefaultFilterWithId, getDefaultState, - Filters, + IFiltersMap, IState, } from '../../common/constants'; import { ErrorDescription } from '../../common/errors'; @@ -34,7 +34,7 @@ type NumericalFilterAction = | FilterActionEnum.QUALITY; export type FilterAction = - | { type: FilterActionEnum.INIT; filters: Filters } + | { type: FilterActionEnum.INIT; filters: IFiltersMap } | { type: NumericalFilterAction; id: string; newValue: number } | { type: FilterActionEnum.TYPE; id: string; newValue: FilterTypeEnum } | { type: FilterActionEnum.ADD; id: string; frequency: number } @@ -56,10 +56,13 @@ export interface IAquaContext extends IState { const AquaContext = createContext(undefined); -type IFilterReducer = (filters: Filters, action: FilterAction) => Filters; +type IFilterReducer = ( + filters: IFiltersMap, + action: FilterAction +) => IFiltersMap; const filterReducer: IFilterReducer = ( - filters: Filters, + filters: IFiltersMap, action: FilterAction ) => { switch (action.type) { @@ -72,7 +75,6 @@ const filterReducer: IFilterReducer = ( } case FilterActionEnum.GAIN: { const filtersCloned = cloneFilters(filters); - console.log(filters); filtersCloned[action.id].gain = action.newValue; return filtersCloned; } diff --git a/src/renderer/utils/utils.ts b/src/renderer/utils/utils.ts index 9219c6f18..41f842be3 100644 --- a/src/renderer/utils/utils.ts +++ b/src/renderer/utils/utils.ts @@ -10,7 +10,11 @@ export const clamp = (num: number, min: number, max: number) => { return Math.min(Math.max(num, min), max); }; -export const sortHelper = (a: IFilter, b: IFilter) => a.frequency - b.frequency; +export const sortHelper = (a: IFilter, b: IFilter) => + a.frequency - b.frequency || + a.gain - b.gain || + a.quality - b.quality || + a.type.localeCompare(b.type); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#sequence_generator_range export const range = (start: number, stop: number, step: number) => From 2e78620271f65e0e787f57a7a771edf331b9f73f Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Thu, 16 Feb 2023 11:04:06 -0500 Subject: [PATCH 3/9] Fix lint errors and add tests --- src/__tests__/unit_tests/common/utils.test.ts | 58 ++++++++++++++++--- src/renderer/MainContent.tsx | 1 - src/renderer/components/FrequencyBand.tsx | 3 +- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/__tests__/unit_tests/common/utils.test.ts b/src/__tests__/unit_tests/common/utils.test.ts index dcda4682a..8bbb8b628 100644 --- a/src/__tests__/unit_tests/common/utils.test.ts +++ b/src/__tests__/unit_tests/common/utils.test.ts @@ -1,5 +1,15 @@ -import { getDefaultState } from 'common/constants'; -import { computeAvgFreq, roundToPrecision } from 'common/utils'; +import { + getDefaultState, + IFiltersMap, + RESERVED_FILE_NAMES_SET, +} from 'common/constants'; +import { + cloneFilters, + computeAvgFreq, + isRestrictedPresetName, + roundToPrecision, +} from 'common/utils'; +import { sortHelper } from 'renderer/utils/utils'; describe('utils', () => { describe('roundToPrecision', () => { @@ -16,20 +26,54 @@ describe('utils', () => { }); describe('computeAvgFreq', () => { - const filters = [...getDefaultState().filters]; + const filters = Object.values(getDefaultState().filters).sort(sortHelper); it('should compute average of first filter and min frequency for index 0', () => { - expect(computeAvgFreq(filters, 0)).toBe(6); + expect(computeAvgFreq(null, filters[0])).toBe(6); }); it('should compute average of last filter and max frequency for last index', () => { - expect(computeAvgFreq(filters, filters.length)).toBe(17889); + expect(computeAvgFreq(filters[filters.length - 1], null)).toBe(17889); }); it('should compute average of neighbouring filters for intermediary indices', () => { // Compute harmonic mean between 64Hz and 125Hz - expect(computeAvgFreq(filters, 2)).toBe(89); + expect(computeAvgFreq(filters[1], filters[2])).toBe(89); // Compute harmonic mean between 250Hz and 500Hz - expect(computeAvgFreq(filters, 4)).toBe(354); + expect(computeAvgFreq(filters[3], filters[4])).toBe(354); + }); + }); + + describe('isRestrictedPresetName', () => { + it('should return true for restricted names', () => { + RESERVED_FILE_NAMES_SET.forEach((name) => { + expect(isRestrictedPresetName(name)).toBe(true); + }); + }); + + it('should return false for non restricted names', () => { + expect(isRestrictedPresetName('greatest preset of all time')).toBe(false); + }); + }); + + describe('cloneFilters', () => { + const filtersMap: IFiltersMap = getDefaultState().filters; + const copy = cloneFilters(filtersMap); + it('should have same values', () => { + Object.entries(filtersMap).forEach(([id, filter]) => { + expect(copy[id]).toStrictEqual(filter); + }); + Object.entries(copy).forEach(([id, filter]) => { + expect(filtersMap[id]).toStrictEqual(filter); + }); + }); + + it('should have distinct IFilter objects', () => { + Object.entries(filtersMap).forEach(([id, filter]) => { + filter.id = `${id}*`; + }); + Object.entries(copy).forEach(([id, filter]) => { + expect(filter.id).toBe(`${id}`); + }); }); }); }); diff --git a/src/renderer/MainContent.tsx b/src/renderer/MainContent.tsx index 6c136cdd1..6a777a3bb 100644 --- a/src/renderer/MainContent.tsx +++ b/src/renderer/MainContent.tsx @@ -64,7 +64,6 @@ const MainContent = () => { return ( ) => { const INTERVAL = 100; From 53e634e5569d4eac179da25939f4fe1b844c4b71 Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:06:19 -0500 Subject: [PATCH 4/9] Add preset tests and add preset migration code --- package-lock.json | 360 ++++++++++++++++++ package.json | 1 + presetV1 | 1 + src/__tests__/test_presets/presetV1 | 1 + src/__tests__/test_presets/presetV2 | 1 + src/__tests__/unit_tests/main/flush.test.ts | 121 ++++++ src/common/constants.ts | 7 +- .../{constants.validator.ts => validator.ts} | 55 ++- src/main/flush.ts | 72 +++- src/main/main.ts | 30 +- 10 files changed, 616 insertions(+), 33 deletions(-) create mode 100644 presetV1 create mode 100644 src/__tests__/test_presets/presetV1 create mode 100644 src/__tests__/test_presets/presetV2 create mode 100644 src/__tests__/unit_tests/main/flush.test.ts rename src/common/{constants.validator.ts => validator.ts} (71%) diff --git a/package-lock.json b/package-lock.json index b43aabc18..f5b814a8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ }, "devDependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.6", + "@rkesters/typescript-json-validator": "^3.0.3", "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.2.0", @@ -1765,6 +1766,65 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true }, + "node_modules/@rkesters/typescript-json-validator": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@rkesters/typescript-json-validator/-/typescript-json-validator-3.0.3.tgz", + "integrity": "sha512-M5kTj4bNrf+v7ZF4cgizcZaqc3yUUzLwxzlQPqWIfLssN9zrB5C99qdIlU27hDAsG3dHcxKGziBbDtk81NZvIQ==", + "dev": true, + "dependencies": { + "@types/cross-spawn": "^6.0.0", + "@types/glob": "^7.1.1", + "@types/json-stable-stringify": "^1.0.32", + "@types/lodash": "^4.14.168", + "@types/minimatch": "^3.0.3", + "cross-spawn": "7.0.3", + "glob": "^7.1.3", + "json-stable-stringify": "^1.0.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "tsconfig-loader": "^1.1.0", + "typescript-json-schema": "0.53.0", + "yargs": "17.3.1" + }, + "bin": { + "typescript-json-validator": "lib/cli.js" + }, + "engines": { + "npm": "don't use npm, use pnpm", + "pnpm": ">=7.1.7" + }, + "peerDependencies": { + "ajv": "^8.8.2", + "ajv-formats": "^2.1.1" + } + }, + "node_modules/@rkesters/typescript-json-validator/node_modules/yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@rkesters/typescript-json-validator/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@sinclair/typebox": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", @@ -2123,6 +2183,15 @@ "@types/node": "*" } }, + "node_modules/@types/cross-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", + "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/d3": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.0.tgz", @@ -2546,6 +2615,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "node_modules/@types/json-stable-stringify": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz", + "integrity": "sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2561,6 +2636,12 @@ "@types/node": "*" } }, + "node_modules/@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true + }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", @@ -15579,6 +15660,18 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, + "node_modules/json-stable-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", + "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", + "dev": true, + "dependencies": { + "jsonify": "^0.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/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", @@ -15613,6 +15706,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/jsx-ast-utils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.2.tgz", @@ -19420,6 +19522,15 @@ "ret": "~0.1.10" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz", + "integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -21666,6 +21777,18 @@ "node": ">=0.4.0" } }, + "node_modules/tsconfig-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-loader/-/tsconfig-loader-1.1.0.tgz", + "integrity": "sha512-KrFF45RYo/JHpoAp1Lf68NupYNyRmh7BwSh1AmAQ3fdCMl8laOyZSLO5iByQR2VTkVdt454HS3c5kfVeYWq7iQ==", + "dev": true, + "dependencies": { + "deepmerge": "^4.2.2", + "json5": "^2.1.1", + "resolve": "^1.15.1", + "strip-bom": "^4.0.0" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -21810,6 +21933,84 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-json-schema": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.53.0.tgz", + "integrity": "sha512-BcFxC9nipQQOXxrBGI/jOWU31BwzVh6vqJR008G8VHKJtQ8YrZX6veriXfTK1l+L0/ff0yKl3mZigMLA6ZqkHg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/node": "^16.9.2", + "glob": "^7.1.7", + "safe-stable-stringify": "^2.2.0", + "ts-node": "^10.2.1", + "typescript": "~4.5.0", + "yargs": "^17.1.1" + }, + "bin": { + "typescript-json-schema": "bin/typescript-json-schema" + } + }, + "node_modules/typescript-json-schema/node_modules/@types/node": { + "version": "16.18.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz", + "integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==", + "dev": true + }, + "node_modules/typescript-json-schema/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/typescript-json-schema/node_modules/typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-json-schema/node_modules/yargs": { + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.0.tgz", + "integrity": "sha512-dwqOPg5trmrre9+v8SUo2q/hAwyKoVfu8OC1xPHKJGNdxAvPl4sKxL4vBnh3bQz/ZvvGAFeA5H3ou2kcOY8sQQ==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/typescript-json-schema/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/ua-parser-js": { "version": "1.0.33", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", @@ -24539,6 +24740,50 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true }, + "@rkesters/typescript-json-validator": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@rkesters/typescript-json-validator/-/typescript-json-validator-3.0.3.tgz", + "integrity": "sha512-M5kTj4bNrf+v7ZF4cgizcZaqc3yUUzLwxzlQPqWIfLssN9zrB5C99qdIlU27hDAsG3dHcxKGziBbDtk81NZvIQ==", + "dev": true, + "requires": { + "@types/cross-spawn": "^6.0.0", + "@types/glob": "^7.1.1", + "@types/json-stable-stringify": "^1.0.32", + "@types/lodash": "^4.14.168", + "@types/minimatch": "^3.0.3", + "cross-spawn": "7.0.3", + "glob": "^7.1.3", + "json-stable-stringify": "^1.0.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "tsconfig-loader": "^1.1.0", + "typescript-json-schema": "0.53.0", + "yargs": "17.3.1" + }, + "dependencies": { + "yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, "@sinclair/typebox": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", @@ -24844,6 +25089,15 @@ "@types/node": "*" } }, + "@types/cross-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.2.tgz", + "integrity": "sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/d3": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.0.tgz", @@ -25267,6 +25521,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "@types/json-stable-stringify": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz", + "integrity": "sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -25282,6 +25542,12 @@ "@types/node": "*" } }, + "@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true + }, "@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", @@ -35313,6 +35579,15 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, + "json-stable-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", + "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", + "dev": true, + "requires": { + "jsonify": "^0.0.1" + } + }, "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", @@ -35341,6 +35616,12 @@ "graceful-fs": "^4.1.6" } }, + "jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true + }, "jsx-ast-utils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.2.tgz", @@ -38172,6 +38453,12 @@ "ret": "~0.1.10" } }, + "safe-stable-stringify": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz", + "integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==", + "dev": true + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -39936,6 +40223,18 @@ } } }, + "tsconfig-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-loader/-/tsconfig-loader-1.1.0.tgz", + "integrity": "sha512-KrFF45RYo/JHpoAp1Lf68NupYNyRmh7BwSh1AmAQ3fdCMl8laOyZSLO5iByQR2VTkVdt454HS3c5kfVeYWq7iQ==", + "dev": true, + "requires": { + "deepmerge": "^4.2.2", + "json5": "^2.1.1", + "resolve": "^1.15.1", + "strip-bom": "^4.0.0" + } + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -40047,6 +40346,67 @@ "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "dev": true }, + "typescript-json-schema": { + "version": "0.53.0", + "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.53.0.tgz", + "integrity": "sha512-BcFxC9nipQQOXxrBGI/jOWU31BwzVh6vqJR008G8VHKJtQ8YrZX6veriXfTK1l+L0/ff0yKl3mZigMLA6ZqkHg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@types/node": "^16.9.2", + "glob": "^7.1.7", + "safe-stable-stringify": "^2.2.0", + "ts-node": "^10.2.1", + "typescript": "~4.5.0", + "yargs": "^17.1.1" + }, + "dependencies": { + "@types/node": { + "version": "16.18.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz", + "integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "typescript": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true + }, + "yargs": { + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.0.tgz", + "integrity": "sha512-dwqOPg5trmrre9+v8SUo2q/hAwyKoVfu8OC1xPHKJGNdxAvPl4sKxL4vBnh3bQz/ZvvGAFeA5H3ou2kcOY8sQQ==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, "ua-parser-js": { "version": "1.0.33", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.33.tgz", diff --git a/package.json b/package.json index 16500c2bc..b42d003e8 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ }, "devDependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.6", + "@rkesters/typescript-json-validator": "^3.0.3", "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.2.0", diff --git a/presetV1 b/presetV1 new file mode 100644 index 000000000..320982270 --- /dev/null +++ b/presetV1 @@ -0,0 +1 @@ +{"preAmp":0,"filters":{"123":{"id":"123","frequency":2,"gain":-4,"quality":6,"type":"PK"},"456":{"id":"456","frequency":8,"gain":-10,"quality":1.2,"type":"PK"}}} \ No newline at end of file diff --git a/src/__tests__/test_presets/presetV1 b/src/__tests__/test_presets/presetV1 new file mode 100644 index 000000000..320982270 --- /dev/null +++ b/src/__tests__/test_presets/presetV1 @@ -0,0 +1 @@ +{"preAmp":0,"filters":{"123":{"id":"123","frequency":2,"gain":-4,"quality":6,"type":"PK"},"456":{"id":"456","frequency":8,"gain":-10,"quality":1.2,"type":"PK"}}} \ No newline at end of file diff --git a/src/__tests__/test_presets/presetV2 b/src/__tests__/test_presets/presetV2 new file mode 100644 index 000000000..8b8012c9a --- /dev/null +++ b/src/__tests__/test_presets/presetV2 @@ -0,0 +1 @@ +{"preAmp":0,"filters":{"0a04dcf8":{"id":"0a04dcf8","frequency":32,"gain":-4,"quality":1,"type":"PK"}, "d77a7415":{"id":"d77a7415","frequency":16000,"gain":0,"quality":1,"type":"PK"}}} \ No newline at end of file diff --git a/src/__tests__/unit_tests/main/flush.test.ts b/src/__tests__/unit_tests/main/flush.test.ts new file mode 100644 index 000000000..b79c56716 --- /dev/null +++ b/src/__tests__/unit_tests/main/flush.test.ts @@ -0,0 +1,121 @@ +import { + deletePreset, + doesPresetExist, + fetchPreset, + renamePreset, + savePreset, +} from 'main/flush'; +import fs from 'fs'; +import { FilterTypeEnum, IPresetV2 } from 'common/constants'; +import path from 'path'; + +const PRESETS_DIR = 'src/__tests__/test_presets'; + +describe('flush', () => { + describe('fetchPreset', () => { + it('should read succesfully a preset of the IPresetV2 format', () => { + const presetName = 'presetV2'; + const preset = fetchPreset(presetName, PRESETS_DIR); + expect(preset).toStrictEqual({ + preAmp: 0, + filters: { + '0a04dcf8': { + id: '0a04dcf8', + frequency: 32, + gain: -4, + quality: 1, + type: FilterTypeEnum.PK, + }, + d77a7415: { + id: 'd77a7415', + frequency: 16000, + gain: 0, + quality: 1, + type: FilterTypeEnum.PK, + }, + }, + }); + }); + + it('should read succesfully a preset of the IPresetV1 format and replace it with a IPresetV2 format', () => { + const presetName = 'presetV1'; + const content = fs.readFileSync(path.join(PRESETS_DIR, presetName), { + encoding: 'utf8', + }); + const preset = fetchPreset('presetV1', PRESETS_DIR); + expect(preset).toStrictEqual({ + preAmp: 0, + filters: { + '123': { id: '123', frequency: 2, gain: -4, quality: 6, type: 'PK' }, + '456': { + id: '456', + frequency: 8, + gain: -10, + quality: 1.2, + type: FilterTypeEnum.PK, + }, + }, + }); + fs.writeFileSync(presetName, content, { + encoding: 'utf8', + }); + }); + }); + + describe('save and delete preset', () => { + it('should save and delete a preset', () => { + const presetName = 'newPreset'; + const preset: IPresetV2 = { + preAmp: 0, + filters: { + '123': { + id: '123', + frequency: 2, + gain: -4, + quality: 6, + type: FilterTypeEnum.PK, + }, + }, + }; + savePreset(presetName, preset, PRESETS_DIR); + expect(doesPresetExist(presetName, PRESETS_DIR)).toBe(true); + deletePreset(presetName, PRESETS_DIR); + expect(doesPresetExist(presetName, PRESETS_DIR)).toBe(false); + }); + }); + + describe('doesPresetExist', () => { + it('should return true for an existing preset', () => { + const presetName = 'presetV1'; + expect(doesPresetExist(presetName, PRESETS_DIR)).toBe(true); + }); + + it('should return false for a non-existing preset', () => { + const presetName = '404_not_found'; + expect(doesPresetExist(presetName, PRESETS_DIR)).toBe(false); + }); + }); + + describe('renamePreset', () => { + it('should rename presets', () => { + const oldPresetName = 'presetV1'; + const newPresetName = 'presetV11'; + renamePreset(oldPresetName, newPresetName, PRESETS_DIR); + expect(() => fetchPreset(oldPresetName, PRESETS_DIR)).toThrow(); + expect(fetchPreset(newPresetName, PRESETS_DIR)).toStrictEqual({ + preAmp: 0, + filters: { + '123': { id: '123', frequency: 2, gain: -4, quality: 6, type: 'PK' }, + '456': { + id: '456', + frequency: 8, + gain: -10, + quality: 1.2, + type: FilterTypeEnum.PK, + }, + }, + }); + renamePreset(newPresetName, oldPresetName, PRESETS_DIR); + }); + }); +}); diff --git a/src/common/constants.ts b/src/common/constants.ts index b9bc8f1ad..0f5c10a22 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -74,7 +74,12 @@ export interface IState { filters: IFiltersMap; } -export interface IPreset { +export interface IPresetV1 { + preAmp: number; + filters: IFilter[]; +} + +export interface IPresetV2 { preAmp: number; filters: IFiltersMap; } diff --git a/src/common/constants.validator.ts b/src/common/validator.ts similarity index 71% rename from src/common/constants.validator.ts rename to src/common/validator.ts index 988191f40..8091fcb39 100644 --- a/src/common/constants.validator.ts +++ b/src/common/validator.ts @@ -23,7 +23,7 @@ const IStateSchema = { enum: ['HSC', 'LSC', 'PK'], type: 'string', }, - Filters: { + IFiltersMap: { additionalProperties: { $ref: '#/definitions/IFilter', }, @@ -56,7 +56,7 @@ const IStateSchema = { }, properties: { filters: { - $ref: '#/definitions/Filters', + $ref: '#/definitions/IFiltersMap', }, isAutoPreAmpOn: { type: 'boolean', @@ -81,7 +81,53 @@ const IStateSchema = { type: 'object', }; -const IPresetSchema = { +export const IPresetSchemaV1 = { + $schema: 'http://json-schema.org/draft-07/schema#', + defaultProperties: [], + definitions: { + FilterTypeEnum: { + enum: ['HSC', 'LSC', 'PK'], + type: 'string', + }, + IFilter: { + defaultProperties: [], + properties: { + frequency: { + type: 'number', + }, + gain: { + type: 'number', + }, + id: { + type: 'string', + }, + quality: { + type: 'number', + }, + type: { + $ref: '#/definitions/FilterTypeEnum', + }, + }, + required: ['frequency', 'gain', 'id', 'quality', 'type'], + type: 'object', + }, + }, + properties: { + filters: { + items: { + $ref: '#/definitions/IFilter', + }, + type: 'array', + }, + preAmp: { + type: 'number', + }, + }, + required: ['filters', 'preAmp'], + type: 'object', +}; + +const IPresetSchemaV2 = { $schema: 'http://json-schema.org/draft-07/schema#', defaultProperties: [], definitions: { @@ -133,4 +179,5 @@ const IPresetSchema = { }; export const validateState = ajv.compile(IStateSchema); -export const validatePreset = ajv.compile(IPresetSchema); +export const validatePresetV1 = ajv.compile(IPresetSchemaV1); +export const validatePresetV2 = ajv.compile(IPresetSchemaV2); diff --git a/src/main/flush.ts b/src/main/flush.ts index 9273cdb4d..6ad1da11e 100644 --- a/src/main/flush.ts +++ b/src/main/flush.ts @@ -2,11 +2,15 @@ import fs from 'fs'; import path from 'path'; import { getDefaultState, - IPreset, + IPresetV1, + IPresetV2, IState, - PRESETS_DIR, } from '../common/constants'; -import { validatePreset, validateState } from '../common/constants.validator'; +import { + validatePresetV1, + validatePresetV2, + validateState, +} from '../common/validator'; export const stateToString = (state: IState) => { if (!state.isEnabled) { @@ -39,7 +43,7 @@ export const serializeState = (state: IState) => { return JSON.stringify(state); }; -export const serializePreset = (preset: IPreset) => { +export const serializePreset = (preset: IPresetV2) => { return JSON.stringify(preset); }; @@ -47,6 +51,7 @@ const CONFIG_CONTENT = 'Include: aqua.txt'; export const AQUA_LOCAL_CONFIG_FILENAME = 'state.txt'; export const AQUA_CONFIG_FILENAME = 'aqua.txt'; const CONFIG_FILENAME = 'config.txt'; +export const PRESETS_DIR = 'presets'; const addFileToPath = (pathPrefix: string, fileName: string) => { return path.join(pathPrefix, fileName); @@ -80,16 +85,33 @@ export const save = (state: IState) => { } }; -export const fetchPreset = (presetName: string) => { +export const fetchPreset = (presetName: string, presetsDir: string) => { try { - const presetPath = path.join(PRESETS_DIR, presetName); + const presetPath = path.join(presetsDir, presetName); const content = fs.readFileSync(presetPath, { encoding: 'utf8', }); - if (!validatePreset(content)) { + const json = JSON.parse(content); + if (validatePresetV1(json)) { + const oldFormat = json as IPresetV1; + const newFormat: IPresetV2 = { preAmp: oldFormat.preAmp, filters: {} }; + oldFormat.filters.forEach((filter) => { + // Its okay to shallow copy the filter because we won't give oldFormat to anyone else. + newFormat.filters[filter.id] = filter; + }); + try { + // Try to update our file. + // eslint-disable-next-line @typescript-eslint/no-use-before-define + savePreset(presetName, newFormat, presetsDir); + } catch { + // Ignore failed updates. + } + return newFormat; + } + if (!validatePresetV2(json)) { throw new Error('Invalid preset file'); } - return JSON.parse(content) as IPreset; + return json as IPresetV2; } catch (ex) { console.log('Failed to get presets!!'); console.log(ex); @@ -97,9 +119,13 @@ export const fetchPreset = (presetName: string) => { } }; -export const savePreset = (presetName: string, preset_info: IPreset) => { +export const savePreset = ( + presetName: string, + preset_info: IPresetV2, + presetsDir: string +) => { try { - const presetPath = path.join(PRESETS_DIR, presetName); + const presetPath = path.join(presetsDir, presetName); fs.writeFileSync(presetPath, serializePreset(preset_info), { encoding: 'utf8', }); @@ -107,12 +133,22 @@ export const savePreset = (presetName: string, preset_info: IPreset) => { console.log('Failed to save to preset %d', presetName); throw ex; } - console.log(`Wrote preset for: ${presetName}`); }; -export const doesPresetExist = (presetName: string) => { - const testPath = addFileToPath(PRESETS_DIR, presetName); +export const deletePreset = (presetName: string, presetsDir: string) => { + try { + const presetPath = path.join(presetsDir, presetName); + fs.unlinkSync(presetPath); + } catch (ex) { + console.log('Failed to delete preset'); + throw ex; + } + console.log(`Deleted preset: ${presetName}`); +}; + +export const doesPresetExist = (presetName: string, presetsDir: string) => { + const testPath = addFileToPath(presetsDir, presetName); try { return fs.existsSync(testPath); } catch (ex) { @@ -121,9 +157,13 @@ export const doesPresetExist = (presetName: string) => { } }; -export const renamePreset = (oldName: string, newName: string) => { - const oldPath = addFileToPath(PRESETS_DIR, oldName); - const newPath = addFileToPath(PRESETS_DIR, newName); +export const renamePreset = ( + oldName: string, + newName: string, + presetsDir: string +) => { + const oldPath = addFileToPath(presetsDir, oldName); + const newPath = addFileToPath(presetsDir, newName); try { fs.renameSync(oldPath, newPath); } catch (ex) { diff --git a/src/main/main.ts b/src/main/main.ts index 68b945301..c2dfa0395 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -24,6 +24,8 @@ import { fetchPreset, renamePreset, doesPresetExist, + PRESETS_DIR, + deletePreset, } from './flush'; import MenuBuilder from './menu'; import { resolveHtmlPath } from './util'; @@ -32,7 +34,7 @@ import ChannelEnum from '../common/channels'; import { FilterTypeEnum, IState, - IPreset, + IPresetV2, IFilter, MAX_FREQUENCY, MAX_GAIN, @@ -45,7 +47,6 @@ import { WINDOW_HEIGHT, WINDOW_HEIGHT_EXPANDED, WINDOW_WIDTH, - PRESETS_DIR, getDefaultFilterWithId, } from '../common/constants'; import { ErrorCode } from '../common/errors'; @@ -227,7 +228,7 @@ ipcMain.on(ChannelEnum.LOAD_PRESET, async (event, arg) => { // TODO: should we do some str checking here? try { - const presetSettings: IPreset = fetchPreset(presetName); + const presetSettings: IPresetV2 = fetchPreset(presetName, PRESETS_DIR); state.preAmp = presetSettings.preAmp; state.filters = presetSettings.filters; await handleUpdate(event, channel); @@ -249,10 +250,14 @@ ipcMain.on(ChannelEnum.SAVE_PRESET, async (event, arg) => { return; } - savePreset(presetName, { - preAmp: state.preAmp, - filters: state.filters, - }); + savePreset( + presetName, + { + preAmp: state.preAmp, + filters: state.filters, + }, + PRESETS_DIR + ); await handleUpdate(event, channel); } catch (e) { handleError(event, channel, ErrorCode.PRESET_FILE_ERROR); @@ -265,11 +270,9 @@ ipcMain.on(ChannelEnum.DELETE_PRESET, async (event, arg) => { const pathToDelete = path.join(PRESETS_DIR, presetName); console.log(`Deleting preset: ${presetName} at location ${pathToDelete}`); try { - fs.unlinkSync(pathToDelete); + deletePreset(presetName, PRESETS_DIR); await handleUpdate(event, channel); } catch (e) { - console.log('Failed to delete preset'); - console.log(e); handleError(event, channel, ErrorCode.PRESET_FILE_ERROR); } }); @@ -286,12 +289,15 @@ ipcMain.on(ChannelEnum.RENAME_PRESET, async (event, arg) => { try { // Validate the provided name - if (isRestrictedPresetName(newName) || doesPresetExist(newName)) { + if ( + isRestrictedPresetName(newName) || + doesPresetExist(newName, PRESETS_DIR) + ) { handleError(event, channel, ErrorCode.INVALID_PRESET_NAME); return; } - renamePreset(oldName, newName); + renamePreset(oldName, newName, PRESETS_DIR); await handleUpdate(event, channel); } catch (e) { handleError(event, channel, ErrorCode.PRESET_FILE_ERROR); From bcbd8ec2c440e9ae3f5724df4a4fd9e0b745fc57 Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:22:39 -0500 Subject: [PATCH 5/9] Remove slider index reference after rebase --- src/renderer/components/FrequencyBand.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/components/FrequencyBand.tsx b/src/renderer/components/FrequencyBand.tsx index 8cfee7dda..ea00ff275 100644 --- a/src/renderer/components/FrequencyBand.tsx +++ b/src/renderer/components/FrequencyBand.tsx @@ -76,7 +76,7 @@ const FrequencyBand = forwardRef( }); await setGain(filter.id, newValue); }, - [dispatchFilter, filter.id, sliderIndex] + [dispatchFilter, filter.id] ); const throttleSetGain = useThrottleAndExecuteLatest( @@ -93,7 +93,7 @@ const FrequencyBand = forwardRef( }); await setQuality(filter.id, newValue); }, - [dispatchFilter, filter.id, sliderIndex] + [dispatchFilter, filter.id] ); const throttleSetQuality = useThrottleAndExecuteLatest( From 09e35c301c0f92caab8b1f3444c58594d4696569 Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Fri, 17 Feb 2023 19:26:00 -0500 Subject: [PATCH 6/9] Fix test --- presetV1 | 1 - src/__tests__/unit_tests/main/flush.test.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 presetV1 diff --git a/presetV1 b/presetV1 deleted file mode 100644 index 320982270..000000000 --- a/presetV1 +++ /dev/null @@ -1 +0,0 @@ -{"preAmp":0,"filters":{"123":{"id":"123","frequency":2,"gain":-4,"quality":6,"type":"PK"},"456":{"id":"456","frequency":8,"gain":-10,"quality":1.2,"type":"PK"}}} \ No newline at end of file diff --git a/src/__tests__/unit_tests/main/flush.test.ts b/src/__tests__/unit_tests/main/flush.test.ts index b79c56716..289ccce93 100644 --- a/src/__tests__/unit_tests/main/flush.test.ts +++ b/src/__tests__/unit_tests/main/flush.test.ts @@ -56,7 +56,7 @@ describe('flush', () => { }, }, }); - fs.writeFileSync(presetName, content, { + fs.writeFileSync(path.join(PRESETS_DIR, presetName), content, { encoding: 'utf8', }); }); From b43690cdde9b6da785930c7b89e39fdb0811489d Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Fri, 17 Feb 2023 22:38:46 -0500 Subject: [PATCH 7/9] Improve frequency + quality scrolling. Fix < 20hz scrolling --- src/renderer/components/FrequencyBand.tsx | 56 +++++++++++++++++------ 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/src/renderer/components/FrequencyBand.tsx b/src/renderer/components/FrequencyBand.tsx index ea00ff275..f3bddaeca 100644 --- a/src/renderer/components/FrequencyBand.tsx +++ b/src/renderer/components/FrequencyBand.tsx @@ -18,6 +18,7 @@ import { WheelEvent, CSSProperties, useCallback, + useEffect, } from 'react'; import { useThrottleAndExecuteLatest } from 'renderer/utils/utils'; import { FILTER_OPTIONS } from '../icons/FilterTypeIcon'; @@ -53,6 +54,19 @@ const FrequencyBand = forwardRef( () => isMinSliderCount || isLoading, [isLoading, isMinSliderCount] ); + // Local copy of quality/freq value used so that the number input increases smoothly while throttling EQ APO writes + const [qualityValue, setQualityValue] = useState(filter.quality); + const [frequencyValue, setFrequencyValue] = useState( + filter.frequency + ); + + useEffect(() => { + setQualityValue(filter.quality); + }, [filter.quality]); + + useEffect(() => { + setFrequencyValue(filter.frequency); + }, [filter.frequency]); // *** Define functions for updating filter values and obtain throttled versions of them *** const normalSetGain = useCallback( @@ -101,6 +115,23 @@ const FrequencyBand = forwardRef( INTERVAL ); + const normalSetFrequency = useCallback( + async (newValue: number) => { + dispatchFilter({ + type: FilterActionEnum.FREQUENCY, + id: filter.id, + newValue, + }); + await setFrequency(filter.id, newValue); + }, + [dispatchFilter, filter.id] + ); + + const throttleSetFrequency = useThrottleAndExecuteLatest( + normalSetFrequency, + INTERVAL + ); + // *** Define handlers for handling changes in gain, frequency, quality and filter type *** const handleGainSubmit = useCallback( async (newValue: number) => { @@ -114,21 +145,18 @@ const FrequencyBand = forwardRef( ); const handleFrequencySubmit = async (newValue: number) => { + setFrequencyValue(newValue); try { - await setFrequency(filter.id, newValue); - dispatchFilter({ - type: FilterActionEnum.FREQUENCY, - id: filter.id, - newValue, - }); + throttleSetFrequency(newValue); } catch (e) { setGlobalError(e as ErrorDescription); } }; const handleQualitySubmit = async (newValue: number) => { + setQualityValue(newValue); try { - await throttleSetQuality(newValue); + throttleSetQuality(newValue); } catch (e) { setGlobalError(e as ErrorDescription); } @@ -163,7 +191,7 @@ const FrequencyBand = forwardRef( }; const onWheelFrequency = (e: WheelEvent) => { - const ranges = [10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 1]; + const ranges = [10000, 5000, 2000, 1000, 500, 200, 100, 50, 20]; const range = ranges.find((bound) => bound <= filter.frequency); const offset = range ? range / 10 : 1; return e.deltaY < 0 @@ -188,17 +216,17 @@ const FrequencyBand = forwardRef( />
Date: Thu, 23 Feb 2023 23:08:03 -0500 Subject: [PATCH 8/9] Refactor autoeq stuff and bump version --- release/app/package.json | 2 +- src/main/autoeq.ts | 21 ++++++++++++--------- src/main/main.ts | 2 +- src/renderer/utils/equalizerApi.ts | 16 ++++++++++++---- src/renderer/widgets/TextInput.tsx | 3 +++ 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/release/app/package.json b/release/app/package.json index 4385521e0..176ec3d69 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "aqua", - "version": "1.0.1", + "version": "1.1.0", "description": "An audio equalizer app", "license": "MIT", "author": { diff --git a/src/main/autoeq.ts b/src/main/autoeq.ts index 5efd1f3aa..8200323b7 100644 --- a/src/main/autoeq.ts +++ b/src/main/autoeq.ts @@ -3,12 +3,13 @@ import path from 'path'; import { app } from 'electron'; import { FilterTypeEnum, - getDefaultFilter, + getDefaultFilterWithId, IFilter, - IPreset, + IPresetV2, MAX_NUM_FILTERS, PREAMP_REGEX, FILTER_REGEX, + IFiltersMap, } from '../common/constants'; let AUTOEQ_DIR = './resources/autoeq'; @@ -27,12 +28,16 @@ export const getAutoEqResponseList = (device: string) => { export const getAutoEqPreset = (device: string, response: string) => { let preAmpParsed = 0; - const filtersList: IFilter[] = []; + const filters: IFiltersMap = {}; const filePath = path.join(AUTOEQ_DIR, device, response); const file = fs.readFileSync(filePath, 'utf8'); file.split('\n').forEach((line, i) => { + if (Object.keys(filters).length >= MAX_NUM_FILTERS) { + // Ensure filters doesn't exceed filter count cap + return; + } const preampMatch = line.match(PREAMP_REGEX); if (preampMatch) { if (preampMatch.length !== 2) { @@ -59,7 +64,7 @@ export const getAutoEqPreset = (device: string, response: string) => { ); } - const filter: IFilter = getDefaultFilter(); + const filter: IFilter = getDefaultFilterWithId(); switch (filterMatch[1]) { case 'PK': filter.type = FilterTypeEnum.PK; @@ -84,16 +89,14 @@ export const getAutoEqPreset = (device: string, response: string) => { `Filter parameter parse error on line ${i} for AutoEQ file: ${filePath}` ); } - filtersList.push(filter); + filters[filter.id] = filter; } // Ignore any lines which we do not recognize }); - const preset: IPreset = { + const preset: IPresetV2 = { preAmp: preAmpParsed, - filters: filtersList - .sort((a: IFilter, b: IFilter) => a.frequency - b.frequency) - .slice(0, MAX_NUM_FILTERS), + filters, }; return preset; diff --git a/src/main/main.ts b/src/main/main.ts index c2dfa0395..49db8cc3d 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -358,7 +358,7 @@ ipcMain.on(ChannelEnum.LOAD_AUTO_EQ_PRESET, async (event, arg) => { const [deviceName, responseName] = arg; try { - const presetSettings: IPreset = getAutoEqPreset(deviceName, responseName); + const presetSettings: IPresetV2 = getAutoEqPreset(deviceName, responseName); state.preAmp = presetSettings.preAmp; state.filters = presetSettings.filters; await handleUpdate(event, channel); diff --git a/src/renderer/utils/equalizerApi.ts b/src/renderer/utils/equalizerApi.ts index 7bede1214..f46f3ab9b 100644 --- a/src/renderer/utils/equalizerApi.ts +++ b/src/renderer/utils/equalizerApi.ts @@ -98,7 +98,8 @@ export const healthCheck = (): Promise => { }; /** - * Load preset into the current equalizer sliders + * Load preset into backend state + * @param {string} presetName - name of preset to load * @returns { Promise } exception if failed */ export const loadPreset = (presetName: string): Promise => { @@ -109,6 +110,7 @@ export const loadPreset = (presetName: string): Promise => { /** * Save preset into preset file + * @param {string} presetName - name to save preset under * @returns { Promise } if save was successful */ export const savePreset = (presetName: string): Promise => { @@ -119,6 +121,7 @@ export const savePreset = (presetName: string): Promise => { /** * Delete a preset file in preset folder + * @param {string} presetName - preset to delete * @returns { Promise } if delete was successful */ export const deletePreset = (presetName: string): Promise => { @@ -127,8 +130,10 @@ export const deletePreset = (presetName: string): Promise => { return promisifyResult(setterResponseHandler, channel); }; -/* +/** * Rename preset from an old name to a new one + * @param {string} oldName - preset name to change + * @param {string} newName - new preset name * @returns { Promise } if rename was successful */ export const renamePreset = ( @@ -162,6 +167,7 @@ export const getAutoEqDeviceList = (): Promise => { /** * Get a list of supported auto eq responses for the given device + * @param {string} deviceName - device to search auto eq presets under * @returns { Promise } exception if failed. */ export const getAutoEqResponseList = ( @@ -173,7 +179,9 @@ export const getAutoEqResponseList = ( }; /** - * Load autoeq preset for given device name and response into the current equalizer sliders + * Load autoeq preset for given device name and response into the backend state + * @param {string} deviceName - device to search auto eq presets under + * @param {string} responseName - response to load * @returns { Promise } exception if failed */ export const loadAutoEqPreset = ( @@ -394,7 +402,7 @@ export const getType = (filterId: string): Promise => { }; /** - * Adjusts a slider's quality + * Adjusts a slider's filter type * @param {string} filterId - id of the slider being adjusted * @param {string} filterType - new filter type */ diff --git a/src/renderer/widgets/TextInput.tsx b/src/renderer/widgets/TextInput.tsx index 5d6decf54..e34cf0a34 100644 --- a/src/renderer/widgets/TextInput.tsx +++ b/src/renderer/widgets/TextInput.tsx @@ -111,6 +111,9 @@ const TextInput = forwardRef( ); const onClick = useCallback((e: MouseEvent) => { + // When double clicking, consume the event so that user manipulations + // on the textbox don't trigger behaviour of parent elements that are + // technically not in focus if (e?.detail === 2) { e.stopPropagation(); } From 2ce26fa2d2cc84138f3bbe7ceb85f46c1475a830 Mon Sep 17 00:00:00 2001 From: Frank <30204408+xenown@users.noreply.github.com> Date: Fri, 24 Feb 2023 16:42:04 -0500 Subject: [PATCH 9/9] Move user data files to electron's userData dir to prevent them from being deleted after app installs --- src/common/constants.ts | 2 -- src/main/flush.ts | 14 ++++++++------ src/main/main.ts | 26 +++++++++++++------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/common/constants.ts b/src/common/constants.ts index 0f5c10a22..152964e07 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -45,8 +45,6 @@ export const WINDOW_WIDTH = 1428; export const WINDOW_HEIGHT = 625; export const WINDOW_HEIGHT_EXPANDED = 1036; -export const PRESETS_DIR = 'presets'; - export const PREAMP_REGEX = new RegExp('^Preamp: (-\\d\\.\\d) dB$'); export const FILTER_REGEX = new RegExp( '^Filter [1-9]\\d?: ON (PK|LS|HS) Fc ([1-9]\\d{0,3}|[1,2]\\d{4}) Hz Gain (-?[1,2]?\\d\\.\\d) dB Q (\\d\\.\\d\\d)$' diff --git a/src/main/flush.ts b/src/main/flush.ts index 6ad1da11e..92b70c5df 100644 --- a/src/main/flush.ts +++ b/src/main/flush.ts @@ -48,7 +48,7 @@ export const serializePreset = (preset: IPresetV2) => { }; const CONFIG_CONTENT = 'Include: aqua.txt'; -export const AQUA_LOCAL_CONFIG_FILENAME = 'state.txt'; +const AQUA_LOCAL_CONFIG_FILENAME = 'state.txt'; export const AQUA_CONFIG_FILENAME = 'aqua.txt'; const CONFIG_FILENAME = 'config.txt'; export const PRESETS_DIR = 'presets'; @@ -57,9 +57,10 @@ const addFileToPath = (pathPrefix: string, fileName: string) => { return path.join(pathPrefix, fileName); }; -export const fetchSettings = () => { +export const fetchSettings = (settingsDir: string) => { + const settingsPath = path.join(settingsDir, AQUA_LOCAL_CONFIG_FILENAME); try { - const content = fs.readFileSync(AQUA_LOCAL_CONFIG_FILENAME, { + const content = fs.readFileSync(settingsPath, { encoding: 'utf8', }); const input = JSON.parse(content); @@ -74,13 +75,14 @@ export const fetchSettings = () => { } }; -export const save = (state: IState) => { +export const save = (state: IState, settingsDir: string) => { + const settingsPath = path.join(settingsDir, AQUA_LOCAL_CONFIG_FILENAME); try { - fs.writeFileSync(AQUA_LOCAL_CONFIG_FILENAME, serializeState(state), { + fs.writeFileSync(settingsPath, serializeState(state), { encoding: 'utf8', }); } catch (ex) { - console.log('Failed to save to %d', AQUA_LOCAL_CONFIG_FILENAME); + console.log(`Failed to save to ${settingsPath}`); throw ex; } }; diff --git a/src/main/main.ts b/src/main/main.ts index 49db8cc3d..caba2be64 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -88,13 +88,15 @@ const setWindowDimension = (isExpanded: boolean) => { /** ----- Equalizer APO Implementation ----- */ // Load initial state from local state file -const state: IState = fetchSettings(); +const userDataDir = app.getPath('userData'); +const presetPath = path.join(userDataDir, PRESETS_DIR); +const state: IState = fetchSettings(userDataDir); let configPath = ''; try { // create presets dir if it doesn't exist - if (!fs.existsSync(PRESETS_DIR)) { - fs.mkdirSync(PRESETS_DIR); + if (!fs.existsSync(presetPath)) { + fs.mkdirSync(presetPath); } } catch (e) { console.error('Failed to make presets directory!!'); @@ -104,8 +106,6 @@ try { try { // update presets folder to support case-sensitive files - const presetPath = path.join(process.cwd(), PRESETS_DIR); - exec( `fsutil.exe file SetCaseSensitiveInfo "${presetPath}"`, (err, stdout) => { @@ -190,7 +190,7 @@ const handleUpdateHelper = async ( event.reply(channel, reply); // Flush changes to our local state file after informing UI that the changes have been applied - save(state); + save(state, userDataDir); }; const handleUpdate = async ( @@ -228,7 +228,7 @@ ipcMain.on(ChannelEnum.LOAD_PRESET, async (event, arg) => { // TODO: should we do some str checking here? try { - const presetSettings: IPresetV2 = fetchPreset(presetName, PRESETS_DIR); + const presetSettings: IPresetV2 = fetchPreset(presetName, presetPath); state.preAmp = presetSettings.preAmp; state.filters = presetSettings.filters; await handleUpdate(event, channel); @@ -256,7 +256,7 @@ ipcMain.on(ChannelEnum.SAVE_PRESET, async (event, arg) => { preAmp: state.preAmp, filters: state.filters, }, - PRESETS_DIR + presetPath ); await handleUpdate(event, channel); } catch (e) { @@ -267,10 +267,10 @@ ipcMain.on(ChannelEnum.SAVE_PRESET, async (event, arg) => { ipcMain.on(ChannelEnum.DELETE_PRESET, async (event, arg) => { const channel = ChannelEnum.DELETE_PRESET; const presetName = arg[0]; - const pathToDelete = path.join(PRESETS_DIR, presetName); + const pathToDelete = path.join(presetPath, presetName); console.log(`Deleting preset: ${presetName} at location ${pathToDelete}`); try { - deletePreset(presetName, PRESETS_DIR); + deletePreset(presetName, presetPath); await handleUpdate(event, channel); } catch (e) { handleError(event, channel, ErrorCode.PRESET_FILE_ERROR); @@ -291,13 +291,13 @@ ipcMain.on(ChannelEnum.RENAME_PRESET, async (event, arg) => { // Validate the provided name if ( isRestrictedPresetName(newName) || - doesPresetExist(newName, PRESETS_DIR) + doesPresetExist(newName, presetPath) ) { handleError(event, channel, ErrorCode.INVALID_PRESET_NAME); return; } - renamePreset(oldName, newName, PRESETS_DIR); + renamePreset(oldName, newName, presetPath); await handleUpdate(event, channel); } catch (e) { handleError(event, channel, ErrorCode.PRESET_FILE_ERROR); @@ -309,7 +309,7 @@ ipcMain.on(ChannelEnum.GET_PRESET_FILE_LIST, async (event) => { console.log(`Getting Preset List`); try { - const fileNames: string[] = fs.readdirSync(PRESETS_DIR); + const fileNames: string[] = fs.readdirSync(presetPath); console.log(fileNames); const reply: TSuccess = { result: fileNames }; event.reply(channel, reply);