diff --git a/README.md b/README.md index bb6589c4..c15d79db 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollec * Fancy, Reactive, Fast UI/UX. * Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [70+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/issues/284). * 20 seconds interval. +* [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages) ## 🔧 How to Install diff --git a/dockerfile b/dockerfile index 8674b999..3dabf513 100644 --- a/dockerfile +++ b/dockerfile @@ -1,25 +1,30 @@ -# DON'T UPDATE TO alpine3.13, 1.14, see #41. -FROM node:14-alpine3.12 AS release +FROM node:14-bullseye-slim AS release WORKDIR /app +# install dependencies +RUN apt update && apt --yes install python3 python3-pip python3-dev git g++ make iputils-ping +RUN ln -s /usr/bin/python3 /usr/bin/python + # split the sqlite install here, so that it can caches the arm prebuilt -RUN apk add --no-cache --virtual .build-deps make g++ python3 python3-dev git && \ - ln -s /usr/bin/python3 /usr/bin/python && \ - npm install mapbox/node-sqlite3#593c9d && \ - apk del .build-deps && \ - rm -f /usr/bin/python +RUN npm install mapbox/node-sqlite3#593c9d # Install apprise -RUN apk add --no-cache python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib +RUN apt --yes install python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib RUN pip3 --no-cache-dir install apprise && \ - rm -rf /root/.cache + rm -rf /root/.cache + +# additional package should be added here, since we don't want to re-compile the arm prebuilt again + +# add sqlite3 cli for debugging in the future +RUN apt --yes install sqlite3 + COPY . . RUN npm install --legacy-peer-deps && npm run build && npm prune EXPOSE 3001 VOLUME ["/app/data"] -HEALTHCHECK --interval=60s --timeout=30s --start-period=300s CMD node extra/healthcheck.js +HEALTHCHECK --interval=600s --timeout=130s --start-period=300s CMD node extra/healthcheck.js CMD ["node", "server/server.js"] FROM release AS nightly diff --git a/dockerfile-alpine b/dockerfile-alpine new file mode 100644 index 00000000..1dd6b6b5 --- /dev/null +++ b/dockerfile-alpine @@ -0,0 +1,26 @@ +# DON'T UPDATE TO alpine3.13, 1.14, see #41. +FROM node:14-alpine3.12 AS release +WORKDIR /app + +# split the sqlite install here, so that it can caches the arm prebuilt +RUN apk add --no-cache --virtual .build-deps make g++ python3 python3-dev git && \ + ln -s /usr/bin/python3 /usr/bin/python && \ + npm install mapbox/node-sqlite3#593c9d && \ + apk del .build-deps && \ + rm -f /usr/bin/python + +# Install apprise +RUN apk add --no-cache python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib +RUN pip3 --no-cache-dir install apprise && \ + rm -rf /root/.cache + +COPY . . +RUN npm install --legacy-peer-deps && npm run build && npm prune + +EXPOSE 3001 +VOLUME ["/app/data"] +HEALTHCHECK --interval=600s --timeout=130s --start-period=300s CMD node extra/healthcheck.js +CMD ["node", "server/server.js"] + +FROM release AS nightly +RUN npm run mark-as-nightly diff --git a/extra/healthcheck.js b/extra/healthcheck.js index c0b33b6e..ed4e3eb2 100644 --- a/extra/healthcheck.js +++ b/extra/healthcheck.js @@ -1,19 +1,31 @@ -let http = require("http"); +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + +let client; + +if (process.env.SSL_KEY && process.env.SSL_CERT) { + client = require("https"); +} else { + client = require("http"); +} + let options = { - host: "localhost", - port: "3001", - timeout: 2000, + host: process.env.HOST || "127.0.0.1", + port: parseInt(process.env.PORT) || 3001, + timeout: 120 * 1000, }; -let request = http.request(options, (res) => { - console.log(`STATUS: ${res.statusCode}`); - if (res.statusCode == 200) { + +let request = client.request(options, (res) => { + console.log(`Health Check OK [Res Code: ${res.statusCode}]`); + if (res.statusCode === 200) { process.exit(0); } else { process.exit(1); } }); + request.on("error", function (err) { - console.log("ERROR"); + console.error("Health Check ERROR"); process.exit(1); }); + request.end(); diff --git a/extra/update-version.js b/extra/update-version.js index 697a6401..ca810a40 100644 --- a/extra/update-version.js +++ b/extra/update-version.js @@ -23,6 +23,8 @@ if (! exists) { pkg.version = newVersion; pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion); pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion); + pkg.scripts["build-docker-alpine"] = pkg.scripts["build-docker-alpine"].replaceAll(oldVersion, newVersion); + pkg.scripts["build-docker-debian"] = pkg.scripts["build-docker-debian"].replaceAll(oldVersion, newVersion); fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); commit(newVersion); diff --git a/package-lock.json b/package-lock.json index 25be1477..dcf5077d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "uptime-kuma", - "version": "1.5.0", + "version": "1.5.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "uptime-kuma", - "version": "1.5.0", + "version": "1.5.2", "license": "MIT", "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.36", @@ -26,19 +26,19 @@ "express": "^4.17.1", "express-basic-auth": "^1.2.0", "form-data": "^4.0.0", - "http-graceful-shutdown": "^3.1.3", + "http-graceful-shutdown": "^3.1.4", "jsonwebtoken": "^8.5.1", "nodemailer": "^6.6.3", "password-hash": "^1.2.2", "prom-client": "^13.2.0", "prometheus-api-metrics": "^3.2.0", "redbean-node": "0.1.2", - "socket.io": "^4.1.3", - "socket.io-client": "^4.1.3", + "socket.io": "^4.2.0", + "socket.io-client": "^4.2.0", "sqlite3": "github:mapbox/node-sqlite3#593c9d", "tcp-ping": "^0.1.1", "v-pagination-3": "^0.1.6", - "vue": "^3.2.2", + "vue": "^3.2.8", "vue-chart-3": "^0.5.7", "vue-confirm-dialog": "^1.0.2", "vue-i18n": "^9.1.7", @@ -48,19 +48,19 @@ }, "devDependencies": { "@babel/eslint-parser": "^7.15.0", - "@types/bootstrap": "^5.1.1", - "@vitejs/plugin-legacy": "^1.5.1", - "@vitejs/plugin-vue": "^1.4.0", - "@vue/compiler-sfc": "^3.2.2", - "core-js": "^3.16.1", + "@types/bootstrap": "^5.1.2", + "@vitejs/plugin-legacy": "^1.5.2", + "@vitejs/plugin-vue": "^1.6.0", + "@vue/compiler-sfc": "^3.2.6", + "core-js": "^3.17.0", "dns2": "^2.0.1", "eslint": "^7.32.0", - "eslint-plugin-vue": "^7.16.0", - "sass": "^1.37.5", + "eslint-plugin-vue": "^7.17.0", + "sass": "^1.38.2", "stylelint": "^13.13.1", "stylelint-config-standard": "^22.0.0", - "typescript": "^4.3.5", - "vite": "^2.4.4" + "typescript": "^4.4.2", + "vite": "^2.5.3" }, "engines": { "node": "14.*" @@ -85,20 +85,20 @@ } }, "node_modules/@babel/core": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", - "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.4.tgz", + "integrity": "sha512-Lkcv9I4a8bgUI8LJOLM6IKv6hnz1KOju6KM1lceqVMKlKKqNRopYd2Pc9MgIurqvMJ6BooemrnJz8jlIiQIpsA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.0", - "@babel/helper-module-transforms": "^7.15.0", - "@babel/helpers": "^7.14.8", - "@babel/parser": "^7.15.0", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0", + "@babel/generator": "^7.15.4", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -151,9 +151,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.0.tgz", - "integrity": "sha512-+gSPtjSBxOZz4Uh8Ggqu7HbfpB8cT1LwW0DnVVLZEJvzXauiD0Di3zszcBkRmfGGrLdYeHUwcflG7i3tr9kQlw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.4.tgz", + "integrity": "sha512-hPMIAmGNbmQzXJIo2P43Zj9UhRmGev5f9nqdBFOWNGDGh6XKmjby79woBvg6y0Jur6yRfQBneDbUQ8ZVc1krFw==", "dev": true, "dependencies": { "eslint-scope": "^5.1.1", @@ -169,12 +169,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", - "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", + "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", "dev": true, "dependencies": { - "@babel/types": "^7.15.0", + "@babel/types": "^7.15.4", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -192,9 +192,9 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", - "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.15.0", @@ -210,132 +210,132 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", - "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "dependencies": { - "@babel/types": "^7.15.0" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", - "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.4.tgz", + "integrity": "sha512-9fHHSGE9zTC++KuXLZcB5FKgvlV83Ox+NLUmQTawovwlJ85+QMhk1CnVk406CQVj97LaWod6KVjl2Sfgw9Aktw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.0", - "@babel/helper-simple-access": "^7.14.8", - "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", "@babel/helper-validator-identifier": "^7.14.9", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", - "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.0", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.14.8", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", - "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "dependencies": { - "@babel/types": "^7.14.8" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" @@ -359,14 +359,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", - "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "dependencies": { - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" @@ -458,9 +458,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", - "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.4.tgz", + "integrity": "sha512-xmzz+7fRpjrvDUj+GV7zfz/R3gSK2cOxGlazaXooxspCr539cbTXJKvBJzSVI2pPhcRGquoOtaIkKCsHQUiO3w==", "bin": { "parser": "bin/babel-parser.js" }, @@ -469,23 +469,23 @@ } }, "node_modules/@babel/standalone": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.15.3.tgz", - "integrity": "sha512-Bst2YWEyQ2ROyO0+jxPVnnkSmUh44/x54+LSbe5M4N5LGfOkxpajEUKVE4ndXtIVrLlHCyuiqCPwv3eC1ItnCg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.15.4.tgz", + "integrity": "sha512-UO0QCTFjX5NSuwX/i8+/pesmRPoRTtf46Cpn8VHcXvNinEr2lxqe8Ix10TfU/UK5qsaOrcKk24We8wH1G0nTZA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" @@ -504,18 +504,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", - "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.15.0", - "@babel/types": "^7.15.0", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -545,9 +545,9 @@ } }, "node_modules/@babel/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", - "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.4.tgz", + "integrity": "sha512-0f1HJFuGmmbrKTCZtbm3cU+b/AqdEYk5toj5iQur58xkVMlS0JWaKxTBSmCXd47uiN7vbcozAupm6Mvs80GNhw==", "dependencies": { "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" @@ -817,9 +817,9 @@ } }, "node_modules/@popperjs/core": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.3.tgz", - "integrity": "sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz", + "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -870,9 +870,9 @@ } }, "node_modules/@types/bootstrap": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.2.tgz", - "integrity": "sha512-dSQvMi2dMyNwJU6LZjP0pimuBowsMUvGScYdfqqeiDUoj9TxXZCpfu0cTl94U0Zvw/tdH9j/9ToOhi4LKNLZhg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.4.tgz", + "integrity": "sha512-VAY+o6sCKrJ7Xix/lugdvQz0PpOn7Go+fQzCXOZvIdp7E/TDaiJddInVhNB/84bk9NX6uuKFSfl2pqslNYH9aA==", "dev": true, "dependencies": { "@popperjs/core": "^2.9.2", @@ -1013,9 +1013,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.8.tgz", - "integrity": "sha512-8upnoQU0OPzbIkm+ZMM0zCeFCkw2s3mS0IWdx0+AAaWqm4fkBb0UJp8Edl7FVKRamYbpJC/aVsHpKWBIbiC7Zg==" + "version": "16.7.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz", + "integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1061,9 +1061,9 @@ "dev": true }, "node_modules/@vitejs/plugin-legacy": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-1.5.1.tgz", - "integrity": "sha512-g+0iy0X3NJRUSKZK+OCeSxNWnCuuE/6lsmr2WLWPOEt1vp6LdfHuNCYRooCm6s0ccTZ/SiumVk8vt9DWSYs+8A==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-1.5.2.tgz", + "integrity": "sha512-b1CaWY/wi7gQZnZaxH+ujPTPb91bEPgnnk7l0WIwxoQtW5UC5MQywRcAbFX+Ise62exXctOMBtsnXKJw2KajXw==", "dev": true, "dependencies": { "@babel/standalone": "^7.14.9", @@ -1092,40 +1092,40 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.6.tgz", - "integrity": "sha512-vbwnz7+OhtLO5p5i630fTuQCL+MlUpEMTKHuX+RfetQ+3pFCkItt2JUH+9yMaBG2Hkz6av+T9mwN/acvtIwpbw==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.8.tgz", + "integrity": "sha512-Sx8qJ030+QM/NakUrkQuUGCeDEb+0d0AgFOl5W4qRvR6e+YgLnW2ew0jREf4T1hak9Fdk8Edl67StECHrhEuew==", "dependencies": { "@babel/parser": "^7.15.0", "@babel/types": "^7.15.0", - "@vue/shared": "3.2.6", + "@vue/shared": "3.2.8", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.6.tgz", - "integrity": "sha512-+a/3oBAzFIXhHt8L5IHJOTP4a5egzvpXYyi13jR7CUYOR1S+Zzv7vBWKYBnKyJLwnrxTZnTQVjeHCgJq743XKg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.8.tgz", + "integrity": "sha512-nxBW6k8FMWQ74294CRbqR+iEJRO5vIjx85I3YCOyZFD6FsDHyFL60g76TcJzucp+F2XXIDaYz+A+F4gQlDatjw==", "dependencies": { - "@vue/compiler-core": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/compiler-core": "3.2.8", + "@vue/shared": "3.2.8" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.6.tgz", - "integrity": "sha512-Ariz1eDsf+2fw6oWXVwnBNtfKHav72RjlWXpEgozYBLnfRPzP+7jhJRw4Nq0OjSsLx2HqjF3QX7HutTjYB0/eA==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.8.tgz", + "integrity": "sha512-XClueQAXoWtN2EToKgfYH9FCL70Ac4bxx6OZFZzxYSg1bei8IB9srJP1UOfnJb2IpnM1heikAz1dp1HI1wHcyQ==", "dev": true, "dependencies": { "@babel/parser": "^7.15.0", "@babel/types": "^7.15.0", "@types/estree": "^0.0.48", - "@vue/compiler-core": "3.2.6", - "@vue/compiler-dom": "3.2.6", - "@vue/compiler-ssr": "3.2.6", - "@vue/ref-transform": "3.2.6", - "@vue/shared": "3.2.6", + "@vue/compiler-core": "3.2.8", + "@vue/compiler-dom": "3.2.8", + "@vue/compiler-ssr": "3.2.8", + "@vue/ref-transform": "3.2.8", + "@vue/shared": "3.2.8", "consolidate": "^0.16.0", "estree-walker": "^2.0.2", "hash-sum": "^2.0.0", @@ -1139,13 +1139,13 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.6.tgz", - "integrity": "sha512-A7IKRKHSyPnTC4w1FxHkjzoyjXInsXkcs/oX22nBQ+6AWlXj2Tt1le96CWPOXy5vYlsTYkF1IgfBaKIdeN/39g==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.8.tgz", + "integrity": "sha512-QqyiFRiIl55W0abDNQ6cNG/7iIfBHmbXVtssUAjX3IlI87ELeT0xackmrCyTSnfIX12ixljg9AN0COIZwlvt5A==", "dev": true, "dependencies": { - "@vue/compiler-dom": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/compiler-dom": "3.2.8", + "@vue/shared": "3.2.8" } }, "node_modules/@vue/devtools-api": { @@ -1154,49 +1154,49 @@ "integrity": "sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==" }, "node_modules/@vue/reactivity": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.6.tgz", - "integrity": "sha512-8vIDD2wpCnYisNNZjmcIj+Rixn0uhZNY3G1vzlgdVdLygeRSuFjkmnZk6WwvGzUWpKfnG0e/NUySM3mVi59hAA==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.8.tgz", + "integrity": "sha512-/Hj3Uz28SG+xB5SDWPOXUs0emvHkq82EmTgk44/plTVFeswCZ3i3Hd7WmsrPT4rGajlDKd5uqMmW0ith1ED0FA==", "dependencies": { - "@vue/shared": "3.2.6" + "@vue/shared": "3.2.8" } }, "node_modules/@vue/ref-transform": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.6.tgz", - "integrity": "sha512-ie39+Y4nbirDLvH+WEq6Eo/l3n3mFATayqR+kEMSphrtMW6Uh/eEMx1Gk2Jnf82zmj3VLRq7dnmPx72JLcBYkQ==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.8.tgz", + "integrity": "sha512-9LdADd4JM3klt+b2qNT8a7b7JvBETNBy2Btv5rDzyPrAVS4Vrw+1WWay6gZBgnxfJ9TPSvG8f/9zu6gNGHmJLA==", "dev": true, "dependencies": { "@babel/parser": "^7.15.0", - "@vue/compiler-core": "3.2.6", - "@vue/shared": "3.2.6", + "@vue/compiler-core": "3.2.8", + "@vue/shared": "3.2.8", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.6.tgz", - "integrity": "sha512-3mqtgpj/YSGFxtvTufSERRApo92B16JNNxz9p+5eG6PPuqTmuRJz214MqhKBEgLEAIQ6R6YCbd83ZDtjQnyw2g==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.8.tgz", + "integrity": "sha512-hwzXLGw1njBEY5JSyRXIIdCtzMFFF6F38WcKMmoIE3p7da30jEbWt8EwwrBomjT8ZbqzElOGlewBcnXNOiiIUg==", "dependencies": { - "@vue/reactivity": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/reactivity": "3.2.8", + "@vue/shared": "3.2.8" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.6.tgz", - "integrity": "sha512-fq33urnP0BNCGm2O3KCzkJlKIHI80C94HJ4qDZbjsTtxyOn5IHqwKSqXVN3RQvO6epcQH+sWS+JNwcNDPzoasg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.8.tgz", + "integrity": "sha512-A/aRrlGLJ5y4Z7eNbnO/xHwx2RiPijQo7D3OIwESroG3HNP+dpuoqamajo5TXS9ZGjbMOih82COoe7xb9P4BZw==", "dependencies": { - "@vue/runtime-core": "3.2.6", - "@vue/shared": "3.2.6", + "@vue/runtime-core": "3.2.8", + "@vue/shared": "3.2.8", "csstype": "^2.6.8" } }, "node_modules/@vue/shared": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.6.tgz", - "integrity": "sha512-uwX0Qs2e6kdF+WmxwuxJxOnKs/wEkMArtYpHSm7W+VY/23Tl8syMRyjnzEeXrNCAP0/8HZxEGkHJsjPEDNRuHw==" + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.8.tgz", + "integrity": "sha512-E2DQQnG7Qr4GwTs3GlfPPlHliGVADoufTnhpwfoViw7JlyLMmYtjfnTwM6nXAwvSJWiF7D+7AxpnWBBT3VWo6Q==" }, "node_modules/abbrev": { "version": "1.1.1", @@ -1315,9 +1315,9 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -2022,9 +2022,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "node_modules/core-js": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.4.tgz", - "integrity": "sha512-Tq4GVE6XCjE+hcyW6hPy0ofN3hwtLudz5ZRdrlCnsnD/xkm/PWQRudzYHiKgZKUcefV6Q57fhDHjZHJP5dpfSg==", + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.17.2.tgz", + "integrity": "sha512-XkbXqhcXeMHPRk2ItS+zQYliAMilea2euoMsnpRRdDad6b2VY6CQQcwz1K8AnWesfw4p165RzY0bTnr3UrbYiA==", "dev": true, "hasInstallScript": true, "funding": { @@ -2033,9 +2033,9 @@ } }, "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=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -2313,9 +2313,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.3.824", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.824.tgz", - "integrity": "sha512-Fk+5aD0HDi9i9ZKt9n2VPOZO1dQy7PV++hz2wJ/KIn+CvVfu4fny39squHtyVDPuHNuoJGAZIbuReEklqYIqfA==", + "version": "1.3.830", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.830.tgz", + "integrity": "sha512-gBN7wNAxV5vl1430dG+XRcQhD4pIeYeak6p6rjdCtlz5wWNwDad8jwvphe5oi1chL5MV6RNRikfffBBiFuj+rQ==", "dev": true }, "node_modules/emoji-regex": { @@ -2431,9 +2431,9 @@ } }, "node_modules/esbuild": { - "version": "0.12.24", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.24.tgz", - "integrity": "sha512-C0ibY+HsXzYB6L/pLWEiWjMpghKsIc58Q5yumARwBQsHl9DXPakW+5NI/Y9w4YXiz0PEP6XTGTT/OV4Nnsmb4A==", + "version": "0.12.25", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.25.tgz", + "integrity": "sha512-woie0PosbRSoN8gQytrdCzUbS2ByKgO8nD1xCZkEup3D9q92miCze4PqEI9TZDYAuwn6CruEnQpJxgTRWdooAg==", "dev": true, "hasInstallScript": true, "bin": { @@ -2960,9 +2960,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.2.tgz", - "integrity": "sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", + "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==", "funding": [ { "type": "individual", @@ -3922,9 +3922,9 @@ } }, "node_modules/knex": { - "version": "0.95.10", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.10.tgz", - "integrity": "sha512-I60A8TXcMdeJlE6h7DSgEYyY37S7kgLObz1qlJ7QvPMD6vnKO5dtuLEht5pMia9Qf5BomqVgkWCdVTqcC/ImOA==", + "version": "0.95.11", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.11.tgz", + "integrity": "sha512-grDetD91O8VoQVCFqeWTgkzdq5406W6rggF/lK1hHuwzmjDs/0m9KxyncGdZbklTi7aUgHvw3+Cfy4x7FvpdaQ==", "dependencies": { "colorette": "1.2.1", "commander": "^7.1.0", @@ -5789,9 +5789,9 @@ } }, "node_modules/redbean-node/node_modules/@types/node": { - "version": "14.17.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.12.tgz", - "integrity": "sha512-vhUqgjJR1qxwTWV5Ps5txuy2XMdf7Fw+OrdChRboy8BmWUPkckOhphaohzFG6b8DW7CrxaBMdrdJ47SYFq1okw==" + "version": "14.17.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.14.tgz", + "integrity": "sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A==" }, "node_modules/redent": { "version": "3.0.0", @@ -6032,9 +6032,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.38.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.38.2.tgz", - "integrity": "sha512-Bz1fG6qiyF0FX6m/I+VxtdVKz1Dfmg/e9kfDy2PhWOkq3T384q2KxwIfP0fXpeI+EyyETdOauH+cRHQDFASllA==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.39.0.tgz", + "integrity": "sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0" @@ -7220,6 +7220,12 @@ "extsprintf": "^1.2.0" } }, + "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=", + "optional": true + }, "node_modules/vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", @@ -7251,9 +7257,9 @@ } }, "node_modules/vite": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.5.2.tgz", - "integrity": "sha512-JK5uhiVyMqHiAJbgBa8rCvpP8bEhAE9dKDv1gCmP+EUP2FSPmEeW3WXlCXauPB3MDa8behPW+ntyNXqnGaxslg==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.5.3.tgz", + "integrity": "sha512-1wMDnjflvtTTkMov8O/Xb5+w1/VW/Gw8oCf8f6dqgHn8lMOEqq0SaPtFEQeikFcOKCfSbiU0nEi0LDIx6DNsaQ==", "dev": true, "dependencies": { "esbuild": "^0.12.17", @@ -7272,19 +7278,19 @@ } }, "node_modules/vue": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.6.tgz", - "integrity": "sha512-Zlb3LMemQS3Xxa6xPsecu45bNjr1hxO8Bh5FUmE0Dr6Ot0znZBKiM47rK6O7FTcakxOnvVN+NTXWJF6u8ajpCQ==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.8.tgz", + "integrity": "sha512-x7lwdnOSkceHQUXRVVHBaZzcp6v7M2CYtSZH75zZaT1mTjB4plC4KZHKP/5jAvdqOLBHZGwDSMkWXm3YbAufrA==", "dependencies": { - "@vue/compiler-dom": "3.2.6", - "@vue/runtime-dom": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/compiler-dom": "3.2.8", + "@vue/runtime-dom": "3.2.8", + "@vue/shared": "3.2.8" } }, "node_modules/vue-chart-3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/vue-chart-3/-/vue-chart-3-0.5.7.tgz", - "integrity": "sha512-BccfPv2rodY6IOppYHvMluVmIJE1CHfp5uW2DXrHrm1kIzaafLwpQ5SwdrxuCevn/QhKoi7azzcxwRcoWbX9hg==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/vue-chart-3/-/vue-chart-3-0.5.8.tgz", + "integrity": "sha512-VJEBTdMgWOaYqekXtz4LVBIeYyIx3qDlQnFyY4Ao1GwizokYZBycCeRN3oKDcYbbZi5yxYqTy6+Tm+m+SOPUPA==", "dependencies": { "@vue/runtime-core": "latest", "@vue/runtime-dom": "latest", @@ -7560,20 +7566,20 @@ "dev": true }, "@babel/core": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", - "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.4.tgz", + "integrity": "sha512-Lkcv9I4a8bgUI8LJOLM6IKv6hnz1KOju6KM1lceqVMKlKKqNRopYd2Pc9MgIurqvMJ6BooemrnJz8jlIiQIpsA==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.0", - "@babel/helper-module-transforms": "^7.15.0", - "@babel/helpers": "^7.14.8", - "@babel/parser": "^7.15.0", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0", + "@babel/generator": "^7.15.4", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -7609,9 +7615,9 @@ } }, "@babel/eslint-parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.0.tgz", - "integrity": "sha512-+gSPtjSBxOZz4Uh8Ggqu7HbfpB8cT1LwW0DnVVLZEJvzXauiD0Di3zszcBkRmfGGrLdYeHUwcflG7i3tr9kQlw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.4.tgz", + "integrity": "sha512-hPMIAmGNbmQzXJIo2P43Zj9UhRmGev5f9nqdBFOWNGDGh6XKmjby79woBvg6y0Jur6yRfQBneDbUQ8ZVc1krFw==", "dev": true, "requires": { "eslint-scope": "^5.1.1", @@ -7620,12 +7626,12 @@ } }, "@babel/generator": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", - "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", + "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", "dev": true, "requires": { - "@babel/types": "^7.15.0", + "@babel/types": "^7.15.4", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -7639,9 +7645,9 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", - "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "requires": { "@babel/compat-data": "^7.15.0", @@ -7651,105 +7657,105 @@ } }, "@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", - "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "requires": { - "@babel/types": "^7.15.0" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-transforms": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", - "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.4.tgz", + "integrity": "sha512-9fHHSGE9zTC++KuXLZcB5FKgvlV83Ox+NLUmQTawovwlJ85+QMhk1CnVk406CQVj97LaWod6KVjl2Sfgw9Aktw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.0", - "@babel/helper-simple-access": "^7.14.8", - "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", "@babel/helper-validator-identifier": "^7.14.9", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-replace-supers": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", - "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.0", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-simple-access": { - "version": "7.14.8", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", - "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "requires": { - "@babel/types": "^7.14.8" + "@babel/types": "^7.15.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-validator-identifier": { @@ -7764,14 +7770,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", - "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "requires": { - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/highlight": { @@ -7844,25 +7850,25 @@ } }, "@babel/parser": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", - "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==" + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.4.tgz", + "integrity": "sha512-xmzz+7fRpjrvDUj+GV7zfz/R3gSK2cOxGlazaXooxspCr539cbTXJKvBJzSVI2pPhcRGquoOtaIkKCsHQUiO3w==" }, "@babel/standalone": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.15.3.tgz", - "integrity": "sha512-Bst2YWEyQ2ROyO0+jxPVnnkSmUh44/x54+LSbe5M4N5LGfOkxpajEUKVE4ndXtIVrLlHCyuiqCPwv3eC1ItnCg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.15.4.tgz", + "integrity": "sha512-UO0QCTFjX5NSuwX/i8+/pesmRPoRTtf46Cpn8VHcXvNinEr2lxqe8Ix10TfU/UK5qsaOrcKk24We8wH1G0nTZA==", "dev": true }, "@babel/template": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" }, "dependencies": { "@babel/code-frame": { @@ -7877,18 +7883,18 @@ } }, "@babel/traverse": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", - "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.15.0", - "@babel/types": "^7.15.0", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -7911,9 +7917,9 @@ } }, "@babel/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", - "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.4.tgz", + "integrity": "sha512-0f1HJFuGmmbrKTCZtbm3cU+b/AqdEYk5toj5iQur58xkVMlS0JWaKxTBSmCXd47uiN7vbcozAupm6Mvs80GNhw==", "requires": { "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" @@ -7968,8 +7974,7 @@ "@fortawesome/vue-fontawesome": { "version": "3.0.0-4", "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.0-4.tgz", - "integrity": "sha512-dQVhhMRcUPCb0aqk5ohm0KGk5OJ7wFZ9aYapLzJB3Z+xs7LhkRWLTb87reelUAG5PFDjutDAXuloT9hi6cz72A==", - "requires": {} + "integrity": "sha512-dQVhhMRcUPCb0aqk5ohm0KGk5OJ7wFZ9aYapLzJB3Z+xs7LhkRWLTb87reelUAG5PFDjutDAXuloT9hi6cz72A==" }, "@humanwhocodes/config-array": { "version": "0.5.0", @@ -8115,9 +8120,9 @@ } }, "@popperjs/core": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.3.tgz", - "integrity": "sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ==" + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz", + "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==" }, "@stylelint/postcss-css-in-js": { "version": "0.37.2", @@ -8156,9 +8161,9 @@ } }, "@types/bootstrap": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.2.tgz", - "integrity": "sha512-dSQvMi2dMyNwJU6LZjP0pimuBowsMUvGScYdfqqeiDUoj9TxXZCpfu0cTl94U0Zvw/tdH9j/9ToOhi4LKNLZhg==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.4.tgz", + "integrity": "sha512-VAY+o6sCKrJ7Xix/lugdvQz0PpOn7Go+fQzCXOZvIdp7E/TDaiJddInVhNB/84bk9NX6uuKFSfl2pqslNYH9aA==", "dev": true, "requires": { "@popperjs/core": "^2.9.2", @@ -8299,9 +8304,9 @@ "dev": true }, "@types/node": { - "version": "16.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.8.tgz", - "integrity": "sha512-8upnoQU0OPzbIkm+ZMM0zCeFCkw2s3mS0IWdx0+AAaWqm4fkBb0UJp8Edl7FVKRamYbpJC/aVsHpKWBIbiC7Zg==" + "version": "16.7.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz", + "integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -8347,9 +8352,9 @@ "dev": true }, "@vitejs/plugin-legacy": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-1.5.1.tgz", - "integrity": "sha512-g+0iy0X3NJRUSKZK+OCeSxNWnCuuE/6lsmr2WLWPOEt1vp6LdfHuNCYRooCm6s0ccTZ/SiumVk8vt9DWSYs+8A==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-1.5.2.tgz", + "integrity": "sha512-b1CaWY/wi7gQZnZaxH+ujPTPb91bEPgnnk7l0WIwxoQtW5UC5MQywRcAbFX+Ise62exXctOMBtsnXKJw2KajXw==", "dev": true, "requires": { "@babel/standalone": "^7.14.9", @@ -8363,44 +8368,43 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.6.0.tgz", "integrity": "sha512-n3i8htn8pTg9M+kM3cnEfsPZx/6ngInlTroth6fA1LQTJq5aTVQ8ggaE5pPoAy9vCgHPtcaXMzwpldhqRAkebQ==", - "dev": true, - "requires": {} + "dev": true }, "@vue/compiler-core": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.6.tgz", - "integrity": "sha512-vbwnz7+OhtLO5p5i630fTuQCL+MlUpEMTKHuX+RfetQ+3pFCkItt2JUH+9yMaBG2Hkz6av+T9mwN/acvtIwpbw==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.8.tgz", + "integrity": "sha512-Sx8qJ030+QM/NakUrkQuUGCeDEb+0d0AgFOl5W4qRvR6e+YgLnW2ew0jREf4T1hak9Fdk8Edl67StECHrhEuew==", "requires": { "@babel/parser": "^7.15.0", "@babel/types": "^7.15.0", - "@vue/shared": "3.2.6", + "@vue/shared": "3.2.8", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } }, "@vue/compiler-dom": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.6.tgz", - "integrity": "sha512-+a/3oBAzFIXhHt8L5IHJOTP4a5egzvpXYyi13jR7CUYOR1S+Zzv7vBWKYBnKyJLwnrxTZnTQVjeHCgJq743XKg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.8.tgz", + "integrity": "sha512-nxBW6k8FMWQ74294CRbqR+iEJRO5vIjx85I3YCOyZFD6FsDHyFL60g76TcJzucp+F2XXIDaYz+A+F4gQlDatjw==", "requires": { - "@vue/compiler-core": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/compiler-core": "3.2.8", + "@vue/shared": "3.2.8" } }, "@vue/compiler-sfc": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.6.tgz", - "integrity": "sha512-Ariz1eDsf+2fw6oWXVwnBNtfKHav72RjlWXpEgozYBLnfRPzP+7jhJRw4Nq0OjSsLx2HqjF3QX7HutTjYB0/eA==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.8.tgz", + "integrity": "sha512-XClueQAXoWtN2EToKgfYH9FCL70Ac4bxx6OZFZzxYSg1bei8IB9srJP1UOfnJb2IpnM1heikAz1dp1HI1wHcyQ==", "dev": true, "requires": { "@babel/parser": "^7.15.0", "@babel/types": "^7.15.0", "@types/estree": "^0.0.48", - "@vue/compiler-core": "3.2.6", - "@vue/compiler-dom": "3.2.6", - "@vue/compiler-ssr": "3.2.6", - "@vue/ref-transform": "3.2.6", - "@vue/shared": "3.2.6", + "@vue/compiler-core": "3.2.8", + "@vue/compiler-dom": "3.2.8", + "@vue/compiler-ssr": "3.2.8", + "@vue/ref-transform": "3.2.8", + "@vue/shared": "3.2.8", "consolidate": "^0.16.0", "estree-walker": "^2.0.2", "hash-sum": "^2.0.0", @@ -8414,13 +8418,13 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.6.tgz", - "integrity": "sha512-A7IKRKHSyPnTC4w1FxHkjzoyjXInsXkcs/oX22nBQ+6AWlXj2Tt1le96CWPOXy5vYlsTYkF1IgfBaKIdeN/39g==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.8.tgz", + "integrity": "sha512-QqyiFRiIl55W0abDNQ6cNG/7iIfBHmbXVtssUAjX3IlI87ELeT0xackmrCyTSnfIX12ixljg9AN0COIZwlvt5A==", "dev": true, "requires": { - "@vue/compiler-dom": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/compiler-dom": "3.2.8", + "@vue/shared": "3.2.8" } }, "@vue/devtools-api": { @@ -8429,49 +8433,49 @@ "integrity": "sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==" }, "@vue/reactivity": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.6.tgz", - "integrity": "sha512-8vIDD2wpCnYisNNZjmcIj+Rixn0uhZNY3G1vzlgdVdLygeRSuFjkmnZk6WwvGzUWpKfnG0e/NUySM3mVi59hAA==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.8.tgz", + "integrity": "sha512-/Hj3Uz28SG+xB5SDWPOXUs0emvHkq82EmTgk44/plTVFeswCZ3i3Hd7WmsrPT4rGajlDKd5uqMmW0ith1ED0FA==", "requires": { - "@vue/shared": "3.2.6" + "@vue/shared": "3.2.8" } }, "@vue/ref-transform": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.6.tgz", - "integrity": "sha512-ie39+Y4nbirDLvH+WEq6Eo/l3n3mFATayqR+kEMSphrtMW6Uh/eEMx1Gk2Jnf82zmj3VLRq7dnmPx72JLcBYkQ==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.8.tgz", + "integrity": "sha512-9LdADd4JM3klt+b2qNT8a7b7JvBETNBy2Btv5rDzyPrAVS4Vrw+1WWay6gZBgnxfJ9TPSvG8f/9zu6gNGHmJLA==", "dev": true, "requires": { "@babel/parser": "^7.15.0", - "@vue/compiler-core": "3.2.6", - "@vue/shared": "3.2.6", + "@vue/compiler-core": "3.2.8", + "@vue/shared": "3.2.8", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/runtime-core": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.6.tgz", - "integrity": "sha512-3mqtgpj/YSGFxtvTufSERRApo92B16JNNxz9p+5eG6PPuqTmuRJz214MqhKBEgLEAIQ6R6YCbd83ZDtjQnyw2g==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.8.tgz", + "integrity": "sha512-hwzXLGw1njBEY5JSyRXIIdCtzMFFF6F38WcKMmoIE3p7da30jEbWt8EwwrBomjT8ZbqzElOGlewBcnXNOiiIUg==", "requires": { - "@vue/reactivity": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/reactivity": "3.2.8", + "@vue/shared": "3.2.8" } }, "@vue/runtime-dom": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.6.tgz", - "integrity": "sha512-fq33urnP0BNCGm2O3KCzkJlKIHI80C94HJ4qDZbjsTtxyOn5IHqwKSqXVN3RQvO6epcQH+sWS+JNwcNDPzoasg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.8.tgz", + "integrity": "sha512-A/aRrlGLJ5y4Z7eNbnO/xHwx2RiPijQo7D3OIwESroG3HNP+dpuoqamajo5TXS9ZGjbMOih82COoe7xb9P4BZw==", "requires": { - "@vue/runtime-core": "3.2.6", - "@vue/shared": "3.2.6", + "@vue/runtime-core": "3.2.8", + "@vue/shared": "3.2.8", "csstype": "^2.6.8" } }, "@vue/shared": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.6.tgz", - "integrity": "sha512-uwX0Qs2e6kdF+WmxwuxJxOnKs/wEkMArtYpHSm7W+VY/23Tl8syMRyjnzEeXrNCAP0/8HZxEGkHJsjPEDNRuHw==" + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.8.tgz", + "integrity": "sha512-E2DQQnG7Qr4GwTs3GlfPPlHliGVADoufTnhpwfoViw7JlyLMmYtjfnTwM6nXAwvSJWiF7D+7AxpnWBBT3VWo6Q==" }, "abbrev": { "version": "1.1.1", @@ -8497,8 +8501,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "agent-base": { "version": "6.0.2", @@ -8557,9 +8560,9 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -8853,8 +8856,7 @@ "bootstrap": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.0.tgz", - "integrity": "sha512-bs74WNI9BgBo3cEovmdMHikSKoXnDgA6VQjJ7TyTotU6L7d41ZyCEEelPwkYEzsG/Zjv3ie9IE3EMAje0W9Xew==", - "requires": {} + "integrity": "sha512-bs74WNI9BgBo3cEovmdMHikSKoXnDgA6VQjJ7TyTotU6L7d41ZyCEEelPwkYEzsG/Zjv3ie9IE3EMAje0W9Xew==" }, "brace-expansion": { "version": "1.1.11", @@ -8968,8 +8970,7 @@ "chartjs-adapter-dayjs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/chartjs-adapter-dayjs/-/chartjs-adapter-dayjs-1.0.0.tgz", - "integrity": "sha512-EnbVqTJGFKLpg1TROLdCEufrzbmIa2oeLGx8O2Wdjw2EoMudoOo9+YFu+6CM0Z0hQ/v3yq/e/Y6efQMu22n8Jg==", - "requires": {} + "integrity": "sha512-EnbVqTJGFKLpg1TROLdCEufrzbmIa2oeLGx8O2Wdjw2EoMudoOo9+YFu+6CM0Z0hQ/v3yq/e/Y6efQMu22n8Jg==" }, "chokidar": { "version": "3.5.2", @@ -9107,15 +9108,15 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "core-js": { - "version": "3.16.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.16.4.tgz", - "integrity": "sha512-Tq4GVE6XCjE+hcyW6hPy0ofN3hwtLudz5ZRdrlCnsnD/xkm/PWQRudzYHiKgZKUcefV6Q57fhDHjZHJP5dpfSg==", + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.17.2.tgz", + "integrity": "sha512-XkbXqhcXeMHPRk2ItS+zQYliAMilea2euoMsnpRRdDad6b2VY6CQQcwz1K8AnWesfw4p165RzY0bTnr3UrbYiA==", "dev": true }, "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=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cors": { "version": "2.8.5", @@ -9335,9 +9336,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.824", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.824.tgz", - "integrity": "sha512-Fk+5aD0HDi9i9ZKt9n2VPOZO1dQy7PV++hz2wJ/KIn+CvVfu4fny39squHtyVDPuHNuoJGAZIbuReEklqYIqfA==", + "version": "1.3.830", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.830.tgz", + "integrity": "sha512-gBN7wNAxV5vl1430dG+XRcQhD4pIeYeak6p6rjdCtlz5wWNwDad8jwvphe5oi1chL5MV6RNRikfffBBiFuj+rQ==", "dev": true }, "emoji-regex": { @@ -9434,9 +9435,9 @@ } }, "esbuild": { - "version": "0.12.24", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.24.tgz", - "integrity": "sha512-C0ibY+HsXzYB6L/pLWEiWjMpghKsIc58Q5yumARwBQsHl9DXPakW+5NI/Y9w4YXiz0PEP6XTGTT/OV4Nnsmb4A==", + "version": "0.12.25", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.25.tgz", + "integrity": "sha512-woie0PosbRSoN8gQytrdCzUbS2ByKgO8nD1xCZkEup3D9q92miCze4PqEI9TZDYAuwn6CruEnQpJxgTRWdooAg==", "dev": true }, "escalade": { @@ -9861,9 +9862,9 @@ "dev": true }, "follow-redirects": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.2.tgz", - "integrity": "sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==" + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", + "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==" }, "forever-agent": { "version": "0.6.1", @@ -10261,8 +10262,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "requires": {} + "dev": true }, "ignore": { "version": "4.0.6", @@ -10584,9 +10584,9 @@ "dev": true }, "knex": { - "version": "0.95.10", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.10.tgz", - "integrity": "sha512-I60A8TXcMdeJlE6h7DSgEYyY37S7kgLObz1qlJ7QvPMD6vnKO5dtuLEht5pMia9Qf5BomqVgkWCdVTqcC/ImOA==", + "version": "0.95.11", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.11.tgz", + "integrity": "sha512-grDetD91O8VoQVCFqeWTgkzdq5406W6rggF/lK1hHuwzmjDs/0m9KxyncGdZbklTi7aUgHvw3+Cfy4x7FvpdaQ==", "requires": { "colorette": "1.2.1", "commander": "^7.1.0", @@ -11463,8 +11463,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "requires": {} + "dev": true }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -11783,8 +11782,7 @@ "version": "0.36.2", "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", - "dev": true, - "requires": {} + "dev": true }, "postcss-value-parser": { "version": "4.1.0", @@ -12002,9 +12000,9 @@ }, "dependencies": { "@types/node": { - "version": "14.17.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.12.tgz", - "integrity": "sha512-vhUqgjJR1qxwTWV5Ps5txuy2XMdf7Fw+OrdChRboy8BmWUPkckOhphaohzFG6b8DW7CrxaBMdrdJ47SYFq1okw==" + "version": "14.17.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.14.tgz", + "integrity": "sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A==" } } }, @@ -12176,9 +12174,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.38.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.38.2.tgz", - "integrity": "sha512-Bz1fG6qiyF0FX6m/I+VxtdVKz1Dfmg/e9kfDy2PhWOkq3T384q2KxwIfP0fXpeI+EyyETdOauH+cRHQDFASllA==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.39.0.tgz", + "integrity": "sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0" @@ -12680,8 +12678,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-5.0.0.tgz", "integrity": "sha512-c8aubuARSu5A3vEHLBeOSJt1udOdS+1iue7BmJDTSXoCBmfEQmmWX+59vYIj3NQdJBY6a/QRv1ozVFpaB9jaqA==", - "dev": true, - "requires": {} + "dev": true }, "stylelint-config-standard": { "version": "22.0.0", @@ -13113,6 +13110,14 @@ "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" + }, + "dependencies": { + "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=", + "optional": true + } } }, "vfile": { @@ -13138,9 +13143,9 @@ } }, "vite": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.5.2.tgz", - "integrity": "sha512-JK5uhiVyMqHiAJbgBa8rCvpP8bEhAE9dKDv1gCmP+EUP2FSPmEeW3WXlCXauPB3MDa8behPW+ntyNXqnGaxslg==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.5.3.tgz", + "integrity": "sha512-1wMDnjflvtTTkMov8O/Xb5+w1/VW/Gw8oCf8f6dqgHn8lMOEqq0SaPtFEQeikFcOKCfSbiU0nEi0LDIx6DNsaQ==", "dev": true, "requires": { "esbuild": "^0.12.17", @@ -13151,19 +13156,19 @@ } }, "vue": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.6.tgz", - "integrity": "sha512-Zlb3LMemQS3Xxa6xPsecu45bNjr1hxO8Bh5FUmE0Dr6Ot0znZBKiM47rK6O7FTcakxOnvVN+NTXWJF6u8ajpCQ==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.8.tgz", + "integrity": "sha512-x7lwdnOSkceHQUXRVVHBaZzcp6v7M2CYtSZH75zZaT1mTjB4plC4KZHKP/5jAvdqOLBHZGwDSMkWXm3YbAufrA==", "requires": { - "@vue/compiler-dom": "3.2.6", - "@vue/runtime-dom": "3.2.6", - "@vue/shared": "3.2.6" + "@vue/compiler-dom": "3.2.8", + "@vue/runtime-dom": "3.2.8", + "@vue/shared": "3.2.8" } }, "vue-chart-3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/vue-chart-3/-/vue-chart-3-0.5.7.tgz", - "integrity": "sha512-BccfPv2rodY6IOppYHvMluVmIJE1CHfp5uW2DXrHrm1kIzaafLwpQ5SwdrxuCevn/QhKoi7azzcxwRcoWbX9hg==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/vue-chart-3/-/vue-chart-3-0.5.8.tgz", + "integrity": "sha512-VJEBTdMgWOaYqekXtz4LVBIeYyIx3qDlQnFyY4Ao1GwizokYZBycCeRN3oKDcYbbZi5yxYqTy6+Tm+m+SOPUPA==", "requires": { "@vue/runtime-core": "latest", "@vue/runtime-dom": "latest", @@ -13176,14 +13181,12 @@ "vue-confirm-dialog": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/vue-confirm-dialog/-/vue-confirm-dialog-1.0.2.tgz", - "integrity": "sha512-gTo1bMDWOLd/6ihmWv8VlPxhc9QaKoE5YqlsKydUOfrrQ3Q3taljF6yI+1TMtAtJLrvZ8DYrePhgBhY1VCJzbQ==", - "requires": {} + "integrity": "sha512-gTo1bMDWOLd/6ihmWv8VlPxhc9QaKoE5YqlsKydUOfrrQ3Q3taljF6yI+1TMtAtJLrvZ8DYrePhgBhY1VCJzbQ==" }, "vue-demi": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.10.1.tgz", - "integrity": "sha512-L6Oi+BvmMv6YXvqv5rJNCFHEKSVu7llpWWJczqmAQYOdmPPw5PNYoz1KKS//Fxhi+4QP64dsPjtmvnYGo1jemA==", - "requires": {} + "integrity": "sha512-L6Oi+BvmMv6YXvqv5rJNCFHEKSVu7llpWWJczqmAQYOdmPPw5PNYoz1KKS//Fxhi+4QP64dsPjtmvnYGo1jemA==" }, "vue-eslint-parser": { "version": "7.10.0", @@ -13246,8 +13249,7 @@ "vue-toastification": { "version": "2.0.0-rc.1", "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.1.tgz", - "integrity": "sha512-hjauv/FyesNZdwcr5m1SCyvu1JmlB+Ts5bTptDLDmsYYlj6Oqv8NYakiElpCF+Abwkn9J/AChh6FwkTL1HOb7Q==", - "requires": {} + "integrity": "sha512-hjauv/FyesNZdwcr5m1SCyvu1JmlB+Ts5bTptDLDmsYYlj6Oqv8NYakiElpCF+Abwkn9J/AChh6FwkTL1HOb7Q==" }, "which": { "version": "2.0.2", @@ -13292,8 +13294,7 @@ "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "requires": {} + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" }, "xmlhttprequest-ssl": { "version": "2.0.0", diff --git a/package.json b/package.json index f503bbf5..c04be03f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uptime-kuma", - "version": "1.5.2", + "version": "1.5.3", "license": "MIT", "repository": { "type": "git", @@ -18,11 +18,12 @@ "start-server": "node server/server.js", "build": "vite build", "vite-preview-dist": "vite preview --host", - "build-docker": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.5.2 --target release . --push", + "build-docker": "npm run build-docker-alpine && npm run build-docker-debian", + "build-docker-alpine": "docker buildx build -f dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:alpine -t louislam/uptime-kuma:1-alpine -t louislam/uptime-kuma:1.5.3-alpine --target release . --push", + "build-docker-debian": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma -t louislam/uptime-kuma:1 -t louislam/uptime-kuma:1.5.3 -t louislam/uptime-kuma:debian -t louislam/uptime-kuma:1-debian -t louislam/uptime-kuma:1.5.3-debian --target release . --push", "build-docker-nightly": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly --target nightly . --push", "build-docker-nightly-amd64": "docker buildx build --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain", - "build-docker-1.5.0-debian": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:1.5.0-debian --target release . --push", - "setup": "git checkout 1.5.2 && npm install --legacy-peer-deps && node node_modules/esbuild/install.js && npm run build && npm prune", + "setup": "git checkout 1.5.3 && npm install --legacy-peer-deps && node node_modules/esbuild/install.js && npm run build && npm prune", "update-version": "node extra/update-version.js", "mark-as-nightly": "node extra/mark-as-nightly.js", "reset-password": "node extra/reset-password.js", @@ -64,7 +65,7 @@ "sqlite3": "github:mapbox/node-sqlite3#593c9d", "tcp-ping": "^0.1.1", "v-pagination-3": "^0.1.6", - "vue": "^3.2.6", + "vue": "^3.2.8", "vue-chart-3": "^0.5.7", "vue-confirm-dialog": "^1.0.2", "vue-i18n": "^9.1.7", diff --git a/server/client.js b/server/client.js new file mode 100644 index 00000000..4f28a2fa --- /dev/null +++ b/server/client.js @@ -0,0 +1,91 @@ +/* + * For Client Socket + */ +const { TimeLogger } = require("../src/util"); +const { R } = require("redbean-node"); +const { io } = require("./server"); + +async function sendNotificationList(socket) { + const timeLogger = new TimeLogger(); + + let result = []; + let list = await R.find("notification", " user_id = ? ", [ + socket.userID, + ]); + + for (let bean of list) { + result.push(bean.export()) + } + + io.to(socket.userID).emit("notificationList", result) + + timeLogger.print("Send Notification List"); + + return list; +} + +/** + * Send Heartbeat History list to socket + * @param toUser True = send to all browsers with the same user id, False = send to the current browser only + * @param overwrite Overwrite client-side's heartbeat list + */ +async function sendHeartbeatList(socket, monitorID, toUser = false, overwrite = false) { + const timeLogger = new TimeLogger(); + + let list = await R.find("heartbeat", ` + monitor_id = ? + ORDER BY time DESC + LIMIT 100 + `, [ + monitorID, + ]) + + let result = []; + + for (let bean of list) { + result.unshift(bean.toJSON()); + } + + if (toUser) { + io.to(socket.userID).emit("heartbeatList", monitorID, result, overwrite); + } else { + socket.emit("heartbeatList", monitorID, result, overwrite); + } + + timeLogger.print(`[Monitor: ${monitorID}] sendHeartbeatList`); +} + +/** + * Important Heart beat list (aka event list) + * @param socket + * @param monitorID + * @param toUser True = send to all browsers with the same user id, False = send to the current browser only + * @param overwrite Overwrite client-side's heartbeat list + */ +async function sendImportantHeartbeatList(socket, monitorID, toUser = false, overwrite = false) { + const timeLogger = new TimeLogger(); + + let list = await R.find("heartbeat", ` + monitor_id = ? + AND important = 1 + ORDER BY time DESC + LIMIT 500 + `, [ + monitorID, + ]) + + timeLogger.print(`[Monitor: ${monitorID}] sendImportantHeartbeatList`); + + if (toUser) { + io.to(socket.userID).emit("importantHeartbeatList", monitorID, list, overwrite); + } else { + socket.emit("importantHeartbeatList", monitorID, list, overwrite); + } + +} + +module.exports = { + sendNotificationList, + sendImportantHeartbeatList, + sendHeartbeatList, +} diff --git a/server/notification.js b/server/notification.js index 472012af..f78401d9 100644 --- a/server/notification.js +++ b/server/notification.js @@ -4,6 +4,8 @@ const FormData = require("form-data"); const nodemailer = require("nodemailer"); const child_process = require("child_process"); +const { UP, DOWN } = require("../src/util"); + class Notification { /** @@ -80,7 +82,7 @@ class Notification { } } else if (notification.type === "smtp") { - return await Notification.smtp(notification, msg) + return await Notification.smtp(notification, msg, heartbeatJSON) } else if (notification.type === "discord") { try { @@ -109,7 +111,7 @@ class Notification { } // If heartbeatJSON is not null, we go into the normal alerting loop. - if (heartbeatJSON["status"] == 0) { + if (heartbeatJSON["status"] == DOWN) { let discorddowndata = { username: discordDisplayName, embeds: [{ @@ -139,7 +141,7 @@ class Notification { await axios.post(notification.discordWebhookUrl, discorddowndata) return okMsg; - } else if (heartbeatJSON["status"] == 1) { + } else if (heartbeatJSON["status"] == UP) { let discordupdata = { username: discordDisplayName, embeds: [{ @@ -343,7 +345,7 @@ class Notification { const mattermostIconEmoji = notification.mattermosticonemo; const mattermostIconUrl = notification.mattermosticonurl; - if (heartbeatJSON["status"] == 0) { + if (heartbeatJSON["status"] == DOWN) { let mattermostdowndata = { username: mattermostUserName, text: "Uptime Kuma Alert", @@ -387,7 +389,7 @@ class Notification { mattermostdowndata ); return okMsg; - } else if (heartbeatJSON["status"] == 1) { + } else if (heartbeatJSON["status"] == UP) { let mattermostupdata = { username: mattermostUserName, text: "Uptime Kuma Alert", @@ -489,19 +491,19 @@ class Notification { return okMsg; } - if (heartbeatJSON["status"] == 0) { + if (heartbeatJSON["status"] == DOWN) { let downdata = { - "title": "UptimeKuma Alert:" + monitorJSON["name"], - "body": "[🔴 Down]" + heartbeatJSON["msg"] + "\nTime (UTC):" + heartbeatJSON["time"], + "title": "UptimeKuma Alert: " + monitorJSON["name"], + "body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], } await axios.post(lunaseadevice, downdata) return okMsg; } - if (heartbeatJSON["status"] == 1) { + if (heartbeatJSON["status"] == UP) { let updata = { - "title": "UptimeKuma Alert:" + monitorJSON["name"], - "body": "[✅ Up]" + heartbeatJSON["msg"] + "\nTime (UTC):" + heartbeatJSON["time"], + "title": "UptimeKuma Alert: " + monitorJSON["name"], + "body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], } await axios.post(lunaseadevice, updata) return okMsg; @@ -527,18 +529,18 @@ class Notification { "body": "Testing Successful.", } await axios.post(pushbulletUrl, testdata, config) - } else if (heartbeatJSON["status"] == 0) { + } else if (heartbeatJSON["status"] == DOWN) { let downdata = { "type": "note", - "title": "UptimeKuma Alert:" + monitorJSON["name"], - "body": "[🔴 Down]" + heartbeatJSON["msg"] + "\nTime (UTC):" + heartbeatJSON["time"], + "title": "UptimeKuma Alert: " + monitorJSON["name"], + "body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], } await axios.post(pushbulletUrl, downdata, config) - } else if (heartbeatJSON["status"] == 1) { + } else if (heartbeatJSON["status"] == UP) { let updata = { "type": "note", - "title": "UptimeKuma Alert:" + monitorJSON["name"], - "body": "[✅ Up]" + heartbeatJSON["msg"] + "\nTime (UTC):" + heartbeatJSON["time"], + "title": "UptimeKuma Alert: " + monitorJSON["name"], + "body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], } await axios.post(pushbulletUrl, updata, config) } @@ -566,7 +568,7 @@ class Notification { ] } await axios.post(lineAPIUrl, testMessage, config) - } else if (heartbeatJSON["status"] == 0) { + } else if (heartbeatJSON["status"] == DOWN) { let downMessage = { "to": notification.lineUserID, "messages": [ @@ -577,7 +579,7 @@ class Notification { ] } await axios.post(lineAPIUrl, downMessage, config) - } else if (heartbeatJSON["status"] == 1) { + } else if (heartbeatJSON["status"] == UP) { let upMessage = { "to": notification.lineUserID, "messages": [ @@ -634,7 +636,7 @@ class Notification { await R.trash(bean) } - static async smtp(notification, msg) { + static async smtp(notification, msg, heartbeatJSON = null) { const config = { host: notification.smtpHost, @@ -652,12 +654,17 @@ class Notification { let transporter = nodemailer.createTransport(config); + let bodyTextContent = msg; + if(heartbeatJSON) { + bodyTextContent = `${msg}\nTime (UTC): ${heartbeatJSON["time"]}`; + } + // send mail with defined transport object await transporter.sendMail({ from: `"Uptime Kuma" <${notification.smtpFrom}>`, to: notification.smtpTo, subject: msg, - text: msg, + text: bodyTextContent, }); return "Sent Successfully."; diff --git a/server/server.js b/server/server.js index 7dd78bfa..e9cb1394 100644 --- a/server/server.js +++ b/server/server.js @@ -82,7 +82,12 @@ if (sslKey && sslCert) { } const io = new Server(server); -app.use(express.json()) +module.exports.io = io; + +// Must be after io instantiation +const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList } = require("./client"); + +app.use(express.json()); /** * Total WebSocket client connected to server currently, no actual use @@ -657,6 +662,76 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString(); } }); + socket.on("clearEvents", async (monitorID, callback) => { + try { + checkLogin(socket) + + console.log(`Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`) + + await R.exec("UPDATE heartbeat SET msg = ?, important = ? WHERE monitor_id = ? ", [ + "", + "0", + monitorID, + ]); + + await sendImportantHeartbeatList(socket, monitorID, true, true); + + callback({ + ok: true, + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); + + socket.on("clearHeartbeats", async (monitorID, callback) => { + try { + checkLogin(socket) + + console.log(`Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`) + + await R.exec("DELETE FROM heartbeat WHERE monitor_id = ?", [ + monitorID + ]); + + await sendHeartbeatList(socket, monitorID, true, true); + + callback({ + ok: true, + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); + + socket.on("clearStatistics", async (callback) => { + try { + checkLogin(socket) + + console.log(`Clear Statistics User ID: ${socket.userID}`) + + await R.exec("DELETE FROM heartbeat"); + + callback({ + ok: true, + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); + debug("added all socket handlers") // *************************** @@ -725,25 +800,6 @@ async function sendMonitorList(socket) { return list; } -async function sendNotificationList(socket) { - const timeLogger = new TimeLogger(); - - let result = []; - let list = await R.find("notification", " user_id = ? ", [ - socket.userID, - ]); - - for (let bean of list) { - result.push(bean.export()) - } - - io.to(socket.userID).emit("notificationList", result) - - timeLogger.print("Send Notification List"); - - return list; -} - async function afterLogin(socket, user) { socket.userID = user.id; socket.join(user.id) @@ -878,48 +934,6 @@ async function startMonitors() { } } -/** - * Send Heartbeat History list to socket - */ -async function sendHeartbeatList(socket, monitorID) { - const timeLogger = new TimeLogger(); - - let list = await R.find("heartbeat", ` - monitor_id = ? - ORDER BY time DESC - LIMIT 100 - `, [ - monitorID, - ]) - - let result = []; - - for (let bean of list) { - result.unshift(bean.toJSON()) - } - - socket.emit("heartbeatList", monitorID, result) - - timeLogger.print(`[Monitor: ${monitorID}] sendHeartbeatList`) -} - -async function sendImportantHeartbeatList(socket, monitorID) { - const timeLogger = new TimeLogger(); - - let list = await R.find("heartbeat", ` - monitor_id = ? - AND important = 1 - ORDER BY time DESC - LIMIT 500 - `, [ - monitorID, - ]) - - timeLogger.print(`[Monitor: ${monitorID}] sendImportantHeartbeatList`); - - socket.emit("importantHeartbeatList", monitorID, list) -} - async function shutdownFunction(signal) { console.log("Shutdown requested"); console.log("Called signal: " + signal); diff --git a/src/assets/vars.scss b/src/assets/vars.scss index 9d487eb2..2f436983 100644 --- a/src/assets/vars.scss +++ b/src/assets/vars.scss @@ -16,3 +16,5 @@ $dark-border-color: #1d2634; $easing-in: cubic-bezier(0.54, 0.78, 0.55, 0.97); $easing-out: cubic-bezier(0.25, 0.46, 0.45, 0.94); $easing-in-out: cubic-bezier(0.79, 0.14, 0.15, 0.86); + +$dropdown-border-radius: 0.5rem; diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index 33b003db..04d046bd 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -31,7 +31,7 @@ export default { beatWidth: 10, beatHeight: 30, hoverScale: 1.5, - beatMargin: 3, // Odd number only, even = blurry + beatMargin: 4, move: false, maxBeat: -1, } @@ -122,11 +122,26 @@ export default { this.$root.heartbeatList[this.monitorId] = []; } }, + mounted() { if (this.size === "small") { - this.beatWidth = 5.6; - this.beatMargin = 2.4; - this.beatHeight = 16 + this.beatWidth = 5; + this.beatHeight = 16; + this.beatMargin = 2; + } + + // Suddenly, have an idea how to handle it universally. + // If the pixel * ratio != Integer, then it causes render issue, round it to solve it!! + const actualWidth = this.beatWidth * window.devicePixelRatio; + const actualMargin = this.beatMargin * window.devicePixelRatio; + + if (! Number.isInteger(actualWidth)) { + this.beatWidth = Math.round(actualWidth) / window.devicePixelRatio; + console.log(this.beatWidth); + } + + if (! Number.isInteger(actualMargin)) { + this.beatMargin = Math.round(actualMargin) / window.devicePixelRatio; } window.addEventListener("resize", this.resize); diff --git a/src/components/HiddenInput.vue b/src/components/HiddenInput.vue new file mode 100644 index 00000000..7ec9f2e4 --- /dev/null +++ b/src/components/HiddenInput.vue @@ -0,0 +1,102 @@ + + + diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue index 2fdb8fe1..080fb859 100644 --- a/src/components/NotificationDialog.vue +++ b/src/components/NotificationDialog.vue @@ -40,7 +40,7 @@